commit ba0705b62d0e086ed8e1aa09925e8665dde36322 Author: lijiaqi Date: Wed Jul 31 10:11:57 2024 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..02e6f28 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/ +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +/log/ +upload/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/bin/start.sh b/bin/start.sh new file mode 100644 index 0000000..922b769 --- /dev/null +++ b/bin/start.sh @@ -0,0 +1,29 @@ +#!/bin/sh + +cd $PWD +pid=$(ps -ef | grep club-nfc.jar | grep -v grep | awk '{print $2}') +if [ -n "$pid" ]; then + kill -9 $pid +fi + +# 优化JVM参数 +JAVA_OPTS="$MAVEN_OPTS -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m" + +# 方式一、配置外部自定义的属性文件(建议) +JAVA_OPTS="$JAVA_OPTS -Dspring.config.location=$PWD\application.yml" + +# 方式二、配置环境名称,加载不同的属性文件 +# JAVA_OPTS="$JAVA_OPTS -Dspring.profiles.active=prod" + +if [ -z "$JAVA_HOME" ]; then + RUN_JAVA=java +else + RUN_JAVA="$JAVA_HOME"/bin/java +fi + +# 根据情况修改 web.war 为您的 war 包名称 +nohup $RUN_JAVA $JAVA_OPTS -jar club-nfc.jar > system.log 2>&1 & + +sleep 1 +pid=$(ps -ef | grep club-nfc.jar | grep -v grep | awk '{print $2}') +echo $pid6 diff --git a/bin/update.sh b/bin/update.sh new file mode 100644 index 0000000..1032e43 --- /dev/null +++ b/bin/update.sh @@ -0,0 +1,8 @@ +_pwd="/www/wwwroot/jianlu.fpvone.cn" +_ip="119.3.89.153" + +cd ../ +#mvn clean package +scp target/build/*.jar root@${_ip}:${_pwd} +#scp target/build/lib/*.* root@${_ip}:${_pwd}/lib +ssh root@${_ip} "cd ${_pwd}; sh ./start.sh" diff --git a/hs_err_pid8424.log b/hs_err_pid8424.log new file mode 100644 index 0000000..8c916a7 --- /dev/null +++ b/hs_err_pid8424.log @@ -0,0 +1,780 @@ +# +# There is insufficient memory for the Java Runtime Environment to continue. +# Native memory allocation (mmap) failed to map 67108864 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:3550), pid=8424, tid=14764 +# +# JRE version: Java(TM) SE Runtime Environment (17.0.7+8) (build 17.0.7+8-LTS-224) +# Java VM: Java HotSpot(TM) 64-Bit Server VM (17.0.7+8-LTS-224, mixed mode, emulated-client, 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: -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.4\lib\idea_rt.jar=62085:D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.4\bin -Dfile.encoding=UTF-8 cn.workde.Application + +Host: Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz, 8 cores, 15G, Windows 11 , 64 bit Build 22621 (10.0.22621.3527) +Time: Wed May 22 15:12:15 2024 Windows 11 , 64 bit Build 22621 (10.0.22621.3527) elapsed time: 10.306436 seconds (0d 0h 0m 10s) + +--------------- T H R E A D --------------- + +Current thread (0x0000023938c4e3d0): VMThread "VM Thread" [stack: 0x0000007486e00000,0x0000007486f00000] [id=14764] + +Stack: [0x0000007486e00000,0x0000007486f00000] +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +V [jvm.dll+0x676a4a] +V [jvm.dll+0x7d74f4] +V [jvm.dll+0x7d8c9e] +V [jvm.dll+0x7d9303] +V [jvm.dll+0x2452c5] +V [jvm.dll+0x6738f9] +V [jvm.dll+0x668232] +V [jvm.dll+0x302826] +V [jvm.dll+0x309da6] +V [jvm.dll+0x35952e] +V [jvm.dll+0x35975f] +V [jvm.dll+0x2d9a38] +V [jvm.dll+0x2d7e45] +V [jvm.dll+0x2d744c] +V [jvm.dll+0x31ab1b] +V [jvm.dll+0x7ddb0b] +V [jvm.dll+0x7de844] +V [jvm.dll+0x7ded5d] +V [jvm.dll+0x7df134] +V [jvm.dll+0x7df200] +V [jvm.dll+0x78759a] +V [jvm.dll+0x675875] +C [ucrtbase.dll+0x29333] +C [KERNEL32.DLL+0x1257d] +C [ntdll.dll+0x5aa48] + +VM_Operation (0x00000074868fda90): G1CollectForAllocation, mode: safepoint, requested by thread 0x0000023922142190 + + +--------------- P R O C E S S --------------- + +Threads class SMR info: +_java_thread_list=0x000002393dca2430, length=56, elements={ +0x0000023922142190, 0x0000023938c52670, 0x0000023938c533f0, 0x0000023939811490, +0x0000023939814220, 0x00000239398183a0, 0x0000023939818c60, 0x0000023939819d70, +0x000002393981fa20, 0x00000239398ba890, 0x00000239399bf740, 0x00000239399c3c60, +0x000002393a190290, 0x000002393a196190, 0x000002393a2e3270, 0x000002393ab32560, +0x000002393d398a60, 0x00000239399c7390, 0x00000239399c7860, 0x000002393d450a20, +0x000002393d8b79e0, 0x000002393d85f1d0, 0x000002393d942550, 0x000002393d940d40, +0x000002393d941210, 0x000002393d93f530, 0x000002393d93f060, 0x000002393d941bb0, +0x000002393d93fa00, 0x000002393d9416e0, 0x000002393d93fed0, 0x000002393d942080, +0x000002393d9403a0, 0x000002393d942a20, 0x000002393d940870, 0x000002393da0a780, +0x000002393da07760, 0x000002393da08100, 0x000002393da0ac50, 0x000002393da07c30, +0x000002393da0eae0, 0x000002393da09440, 0x000002393da0bac0, 0x000002393da0bf90, +0x000002393da0c930, 0x000002393da0e610, 0x000002393da0c460, 0x000002393da07290, +0x000002393da0d7a0, 0x000002393da085d0, 0x000002393da0e140, 0x000002393da0dc70, +0x000002393da09910, 0x000002393da0ce00, 0x000002393da0b120, 0x000002393da0b5f0 +} + +Java Threads: ( => current thread ) + 0x0000023922142190 JavaThread "main" [_thread_blocked, id=10008, stack(0x0000007486800000,0x0000007486900000)] + 0x0000023938c52670 JavaThread "Reference Handler" daemon [_thread_blocked, id=6088, stack(0x0000007486f00000,0x0000007487000000)] + 0x0000023938c533f0 JavaThread "Finalizer" daemon [_thread_blocked, id=13948, stack(0x0000007487000000,0x0000007487100000)] + 0x0000023939811490 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=25164, stack(0x0000007487100000,0x0000007487200000)] + 0x0000023939814220 JavaThread "Attach Listener" daemon [_thread_blocked, id=20912, stack(0x0000007487200000,0x0000007487300000)] + 0x00000239398183a0 JavaThread "Service Thread" daemon [_thread_blocked, id=3060, stack(0x0000007487300000,0x0000007487400000)] + 0x0000023939818c60 JavaThread "Monitor Deflation Thread" daemon [_thread_blocked, id=20764, stack(0x0000007487400000,0x0000007487500000)] + 0x0000023939819d70 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=12980, stack(0x0000007487500000,0x0000007487600000)] + 0x000002393981fa20 JavaThread "Sweeper thread" daemon [_thread_blocked, id=9796, stack(0x0000007487600000,0x0000007487700000)] + 0x00000239398ba890 JavaThread "Common-Cleaner" daemon [_thread_blocked, id=5368, stack(0x0000007487700000,0x0000007487800000)] + 0x00000239399bf740 JavaThread "C1 CompilerThread1" daemon [_thread_blocked, id=21132, stack(0x0000007487800000,0x0000007487900000)] + 0x00000239399c3c60 JavaThread "C1 CompilerThread2" daemon [_thread_blocked, id=22444, stack(0x0000007487900000,0x0000007487a00000)] + 0x000002393a190290 JavaThread "Monitor Ctrl-Break" daemon [_thread_in_native, id=11728, stack(0x0000007487a00000,0x0000007487b00000)] + 0x000002393a196190 JavaThread "Notification Thread" daemon [_thread_blocked, id=10088, stack(0x0000007487b00000,0x0000007487c00000)] + 0x000002393a2e3270 JavaThread "RMI TCP Accept-0" daemon [_thread_in_native, id=16228, stack(0x0000007487c00000,0x0000007487d00000)] + 0x000002393ab32560 JavaThread "C1 CompilerThread3" daemon [_thread_blocked, id=9864, stack(0x0000007488700000,0x0000007488800000)] + 0x000002393d398a60 JavaThread "Catalina-utility-1" [_thread_blocked, id=18404, stack(0x0000007488800000,0x0000007488900000)] + 0x00000239399c7390 JavaThread "Catalina-utility-2" [_thread_blocked, id=14436, stack(0x0000007488a00000,0x0000007488b00000)] + 0x00000239399c7860 JavaThread "container-0" [_thread_blocked, id=12912, stack(0x0000007488b00000,0x0000007488c00000)] + 0x000002393d450a20 JavaThread "Thread-1" daemon [_thread_in_native, id=23812, stack(0x0000007488c00000,0x0000007488d00000)] + 0x000002393d8b79e0 JavaThread "redisson-netty-2-1" [_thread_in_native, id=10544, stack(0x0000007488d00000,0x0000007488e00000)] + 0x000002393d85f1d0 JavaThread "redisson-netty-2-2" [_thread_in_native, id=25144, stack(0x0000007488e00000,0x0000007488f00000)] + 0x000002393d942550 JavaThread "redisson-netty-2-3" [_thread_in_native, id=23576, stack(0x0000007488f00000,0x0000007489000000)] + 0x000002393d940d40 JavaThread "redisson-netty-2-4" [_thread_in_native, id=14732, stack(0x0000007489000000,0x0000007489100000)] + 0x000002393d941210 JavaThread "redisson-timer-4-1" [_thread_blocked, id=19608, stack(0x0000007489200000,0x0000007489300000)] + 0x000002393d93f530 JavaThread "redisson-netty-2-5" [_thread_in_native, id=15404, stack(0x0000007489300000,0x0000007489400000)] + 0x000002393d93f060 JavaThread "redisson-netty-2-6" [_thread_in_native, id=4504, stack(0x0000007489400000,0x0000007489500000)] + 0x000002393d941bb0 JavaThread "redisson-netty-2-7" [_thread_in_native, id=20820, stack(0x0000007489500000,0x0000007489600000)] + 0x000002393d93fa00 JavaThread "redisson-netty-2-8" [_thread_in_native, id=25156, stack(0x0000007489600000,0x0000007489700000)] + 0x000002393d9416e0 JavaThread "redisson-netty-2-9" [_thread_in_native, id=1292, stack(0x0000007489700000,0x0000007489800000)] + 0x000002393d93fed0 JavaThread "redisson-netty-2-10" [_thread_in_native, id=19860, stack(0x0000007489800000,0x0000007489900000)] + 0x000002393d942080 JavaThread "redisson-netty-2-11" [_thread_in_native, id=24496, stack(0x0000007489900000,0x0000007489a00000)] + 0x000002393d9403a0 JavaThread "redisson-netty-2-12" [_thread_in_native, id=8920, stack(0x0000007489a00000,0x0000007489b00000)] + 0x000002393d942a20 JavaThread "redisson-netty-2-13" [_thread_in_native, id=2252, stack(0x0000007489b00000,0x0000007489c00000)] + 0x000002393d940870 JavaThread "redisson-netty-2-14" [_thread_in_native, id=25312, stack(0x0000007489c00000,0x0000007489d00000)] + 0x000002393da0a780 JavaThread "redisson-netty-2-15" [_thread_in_native, id=23700, stack(0x0000007489d00000,0x0000007489e00000)] + 0x000002393da07760 JavaThread "redisson-netty-2-16" [_thread_in_native, id=6460, stack(0x0000007489e00000,0x0000007489f00000)] + 0x000002393da08100 JavaThread "redisson-netty-2-17" [_thread_in_native, id=16868, stack(0x0000007489f00000,0x000000748a000000)] + 0x000002393da0ac50 JavaThread "redisson-netty-2-18" [_thread_in_native, id=23564, stack(0x000000748a000000,0x000000748a100000)] + 0x000002393da07c30 JavaThread "redisson-netty-2-19" [_thread_in_native, id=21992, stack(0x000000748a100000,0x000000748a200000)] + 0x000002393da0eae0 JavaThread "redisson-netty-2-20" [_thread_in_native, id=14076, stack(0x000000748a200000,0x000000748a300000)] + 0x000002393da09440 JavaThread "redisson-netty-2-21" [_thread_in_native, id=6948, stack(0x000000748a300000,0x000000748a400000)] + 0x000002393da0bac0 JavaThread "redisson-netty-2-22" [_thread_in_native, id=17608, stack(0x000000748a400000,0x000000748a500000)] + 0x000002393da0bf90 JavaThread "redisson-netty-2-23" [_thread_in_native, id=25272, stack(0x000000748a500000,0x000000748a600000)] + 0x000002393da0c930 JavaThread "redisson-netty-2-24" [_thread_in_native, id=3304, stack(0x000000748a600000,0x000000748a700000)] + 0x000002393da0e610 JavaThread "redisson-netty-2-25" [_thread_in_native, id=20732, stack(0x000000748a700000,0x000000748a800000)] + 0x000002393da0c460 JavaThread "redisson-netty-2-26" [_thread_in_native, id=22208, stack(0x000000748a800000,0x000000748a900000)] + 0x000002393da07290 JavaThread "redisson-netty-2-27" [_thread_in_native, id=2008, stack(0x000000748a900000,0x000000748aa00000)] + 0x000002393da0d7a0 JavaThread "redisson-netty-2-28" [_thread_in_native, id=23224, stack(0x000000748aa00000,0x000000748ab00000)] + 0x000002393da085d0 JavaThread "redisson-netty-2-29" [_thread_in_native, id=24388, stack(0x000000748ab00000,0x000000748ac00000)] + 0x000002393da0e140 JavaThread "redisson-netty-2-30" [_thread_in_native, id=13404, stack(0x000000748ac00000,0x000000748ad00000)] + 0x000002393da0dc70 JavaThread "redisson-netty-2-31" [_thread_in_native, id=25028, stack(0x000000748ad00000,0x000000748ae00000)] + 0x000002393da09910 JavaThread "redisson-netty-2-32" [_thread_in_native, id=12008, stack(0x000000748ae00000,0x000000748af00000)] + 0x000002393da0ce00 JavaThread "Keep-Alive-Timer" daemon [_thread_blocked, id=20876, stack(0x000000748af00000,0x000000748b000000)] + 0x000002393da0b120 JavaThread "Icc-Refresh-Token1" daemon [_thread_blocked, id=18544, stack(0x000000748b000000,0x000000748b100000)] + 0x000002393da0b5f0 JavaThread "lettuce-timer-6-1" daemon [_thread_blocked, id=24764, stack(0x000000748b100000,0x000000748b200000)] + +Other Threads: +=>0x0000023938c4e3d0 VMThread "VM Thread" [stack: 0x0000007486e00000,0x0000007486f00000] [id=14764] + 0x00000239221cafd0 WatcherThread [stack: 0x0000007487d00000,0x0000007487e00000] [id=11824] + 0x00000239221af970 GCTaskThread "GC Thread#0" [stack: 0x0000007486900000,0x0000007486a00000] [id=15384] + 0x000002393a3b7e30 GCTaskThread "GC Thread#1" [stack: 0x0000007487e00000,0x0000007487f00000] [id=5700] + 0x000002393a365d70 GCTaskThread "GC Thread#2" [stack: 0x0000007487f00000,0x0000007488000000] [id=24868] + 0x000002393a366020 GCTaskThread "GC Thread#3" [stack: 0x0000007488000000,0x0000007488100000] [id=19436] + 0x000002393a3fd970 GCTaskThread "GC Thread#4" [stack: 0x0000007488100000,0x0000007488200000] [id=3764] + 0x000002393a3fe0a0 GCTaskThread "GC Thread#5" [stack: 0x0000007488200000,0x0000007488300000] [id=22636] + 0x000002393a900e10 GCTaskThread "GC Thread#6" [stack: 0x0000007488300000,0x0000007488400000] [id=15592] + 0x000002393a9034e0 GCTaskThread "GC Thread#7" [stack: 0x0000007488400000,0x0000007488500000] [id=5268] + 0x00000239221c0540 ConcurrentGCThread "G1 Main Marker" [stack: 0x0000007486a00000,0x0000007486b00000] [id=23748] + 0x00000239221c2610 ConcurrentGCThread "G1 Conc#0" [stack: 0x0000007486b00000,0x0000007486c00000] [id=3168] + 0x000002393ae776d0 ConcurrentGCThread "G1 Conc#1" [stack: 0x0000007488900000,0x0000007488a00000] [id=14820] + 0x0000023938b0b200 ConcurrentGCThread "G1 Refine#0" [stack: 0x0000007486c00000,0x0000007486d00000] [id=20492] + 0x000002393a3f4470 ConcurrentGCThread "G1 Refine#1" [stack: 0x0000007488500000,0x0000007488600000] [id=17004] + 0x000002393a3febe0 ConcurrentGCThread "G1 Refine#2" [stack: 0x0000007488600000,0x0000007488700000] [id=1924] + 0x0000023938b0ba30 ConcurrentGCThread "G1 Service" [stack: 0x0000007486d00000,0x0000007486e00000] [id=22572] + +Threads with active compile tasks: + +VM state: at safepoint (normal execution) + +VM Mutex/Monitor currently owned by a thread: ([mutex/lock_event]) +[0x000002392213ee20] Threads_lock - owner thread: 0x0000023938c4e3d0 +[0x000002392213f060] Heap_lock - owner thread: 0x0000023922142190 + +Heap address: 0x0000000702800000, size: 4056 MB, Compressed Oops mode: Zero based, Oop shift amount: 3 + +CDS archive(s) mapped at: [0x0000000800000000-0x0000000800bd0000-0x0000000800bd0000), size 12386304, SharedBaseAddress: 0x0000000800000000, ArchiveRelocationMode: 0. +Compressed class space mapped at: 0x0000000800c00000-0x0000000840c00000, reserved size: 1073741824 +Narrow klass base: 0x0000000800000000, Narrow klass shift: 0, Narrow klass range: 0x100000000 + +GC Precious Log: + CPUs: 8 total, 8 available + Memory: 16217M + Large Page Support: Disabled + NUMA Support: Disabled + Compressed Oops: Enabled (Zero based) + Heap Region Size: 2M + Heap Min Capacity: 8M + Heap Initial Capacity: 254M + Heap Max Capacity: 4056M + Pre-touch: Disabled + Parallel Workers: 8 + Concurrent Workers: 2 + Concurrent Refinement Workers: 8 + Periodic GC: Disabled + +Heap: + garbage-first heap total 194560K, used 87891K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 1 young (2048K), 1 survivors (2048K) + Metaspace used 68301K, committed 68864K, reserved 1114112K + class space used 9119K, committed 9408K, reserved 1048576K + +Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, OA=open archive, CA=closed archive, TAMS=top-at-mark-start (previous, next) +| 0|0x0000000702800000, 0x0000000702a00000, 0x0000000702a00000|100%| O| |TAMS 0x0000000702a00000, 0x0000000702800000| Untracked +| 1|0x0000000702a00000, 0x0000000702c00000, 0x0000000702c00000|100%| O| |TAMS 0x0000000702c00000, 0x0000000702a00000| Untracked +| 2|0x0000000702c00000, 0x0000000702e00000, 0x0000000702e00000|100%| O| |TAMS 0x0000000702e00000, 0x0000000702c00000| Untracked +| 3|0x0000000702e00000, 0x0000000703000000, 0x0000000703000000|100%| O| |TAMS 0x0000000703000000, 0x0000000702e00000| Untracked +| 4|0x0000000703000000, 0x0000000703200000, 0x0000000703200000|100%| O| |TAMS 0x0000000703200000, 0x0000000703000000| Untracked +| 5|0x0000000703200000, 0x0000000703361800, 0x0000000703400000| 69%| O| |TAMS 0x0000000703361800, 0x0000000703200000| Untracked +| 6|0x0000000703400000, 0x0000000703600000, 0x0000000703600000|100%| O| |TAMS 0x0000000703600000, 0x0000000703400000| Untracked +| 7|0x0000000703600000, 0x0000000703800000, 0x0000000703800000|100%| O| |TAMS 0x0000000703800000, 0x0000000703600000| Untracked +| 8|0x0000000703800000, 0x0000000703a00000, 0x0000000703a00000|100%| O| |TAMS 0x0000000703a00000, 0x0000000703800000| Untracked +| 9|0x0000000703a00000, 0x0000000703c00000, 0x0000000703c00000|100%| O| |TAMS 0x0000000703c00000, 0x0000000703a00000| Untracked +| 10|0x0000000703c00000, 0x0000000703e00000, 0x0000000703e00000|100%| O| |TAMS 0x0000000703e00000, 0x0000000703c00000| Untracked +| 11|0x0000000703e00000, 0x0000000704000000, 0x0000000704000000|100%| O| |TAMS 0x0000000704000000, 0x0000000703e00000| Untracked +| 12|0x0000000704000000, 0x0000000704200000, 0x0000000704200000|100%| O| |TAMS 0x0000000704200000, 0x0000000704000000| Untracked +| 13|0x0000000704200000, 0x0000000704400000, 0x0000000704400000|100%| O| |TAMS 0x0000000704400000, 0x0000000704200000| Untracked +| 14|0x0000000704400000, 0x0000000704600000, 0x0000000704600000|100%| O| |TAMS 0x0000000704600000, 0x0000000704400000| Untracked +| 15|0x0000000704600000, 0x0000000704800000, 0x0000000704800000|100%| O| |TAMS 0x0000000704800000, 0x0000000704600000| Untracked +| 16|0x0000000704800000, 0x0000000704a00000, 0x0000000704a00000|100%| O| |TAMS 0x0000000704a00000, 0x0000000704800000| Untracked +| 17|0x0000000704a00000, 0x0000000704c00000, 0x0000000704c00000|100%| O| |TAMS 0x0000000704c00000, 0x0000000704a00000| Untracked +| 18|0x0000000704c00000, 0x0000000704e00000, 0x0000000704e00000|100%| O| |TAMS 0x0000000704e00000, 0x0000000704c00000| Untracked +| 19|0x0000000704e00000, 0x0000000705000000, 0x0000000705000000|100%| O| |TAMS 0x0000000705000000, 0x0000000704e00000| Untracked +| 20|0x0000000705000000, 0x0000000705200000, 0x0000000705200000|100%| O| |TAMS 0x0000000705200000, 0x0000000705000000| Untracked +| 21|0x0000000705200000, 0x0000000705400000, 0x0000000705400000|100%| O| |TAMS 0x0000000705400000, 0x0000000705200000| Untracked +| 22|0x0000000705400000, 0x0000000705600000, 0x0000000705600000|100%| O| |TAMS 0x0000000705600000, 0x0000000705400000| Untracked +| 23|0x0000000705600000, 0x0000000705800000, 0x0000000705800000|100%| O| |TAMS 0x0000000705800000, 0x0000000705600000| Untracked +| 24|0x0000000705800000, 0x0000000705a00000, 0x0000000705a00000|100%| O| |TAMS 0x0000000705a00000, 0x0000000705800000| Untracked +| 25|0x0000000705a00000, 0x0000000705c00000, 0x0000000705c00000|100%| O| |TAMS 0x0000000705c00000, 0x0000000705a00000| Untracked +| 26|0x0000000705c00000, 0x0000000705e00000, 0x0000000705e00000|100%| O| |TAMS 0x0000000705e00000, 0x0000000705c00000| Untracked +| 27|0x0000000705e00000, 0x0000000705e00000, 0x0000000706000000| 0%| F| |TAMS 0x0000000705e00000, 0x0000000705e00000| Untracked +| 28|0x0000000706000000, 0x0000000706000000, 0x0000000706200000| 0%| F| |TAMS 0x0000000706000000, 0x0000000706000000| Untracked +| 29|0x0000000706200000, 0x0000000706200000, 0x0000000706400000| 0%| F| |TAMS 0x0000000706200000, 0x0000000706200000| Untracked +| 30|0x0000000706400000, 0x0000000706400000, 0x0000000706600000| 0%| F| |TAMS 0x0000000706400000, 0x0000000706400000| Untracked +| 31|0x0000000706600000, 0x0000000706600000, 0x0000000706800000| 0%| F| |TAMS 0x0000000706600000, 0x0000000706600000| Untracked +| 32|0x0000000706800000, 0x0000000706a00000, 0x0000000706a00000|100%| O| |TAMS 0x0000000706a00000, 0x0000000706800000| Complete +| 33|0x0000000706a00000, 0x0000000706a00000, 0x0000000706c00000| 0%| F| |TAMS 0x0000000706a00000, 0x0000000706a00000| Untracked +| 34|0x0000000706c00000, 0x0000000706e00000, 0x0000000706e00000|100%| O| |TAMS 0x0000000706c00000, 0x0000000706c00000| Untracked +| 35|0x0000000706e00000, 0x0000000706e00000, 0x0000000707000000| 0%| F| |TAMS 0x0000000706e00000, 0x0000000706e00000| Untracked +| 36|0x0000000707000000, 0x0000000707000000, 0x0000000707200000| 0%| F| |TAMS 0x0000000707000000, 0x0000000707000000| Untracked +| 37|0x0000000707200000, 0x0000000707400000, 0x0000000707400000|100%| O| |TAMS 0x0000000707200000, 0x0000000707200000| Untracked +| 38|0x0000000707400000, 0x0000000707600000, 0x0000000707600000|100%| O| |TAMS 0x0000000707400000, 0x0000000707400000| Untracked +| 39|0x0000000707600000, 0x0000000707800000, 0x0000000707800000|100%| O| |TAMS 0x0000000707600000, 0x0000000707600000| Untracked +| 40|0x0000000707800000, 0x0000000707a00000, 0x0000000707a00000|100%| O| |TAMS 0x0000000707800000, 0x0000000707800000| Untracked +| 41|0x0000000707a00000, 0x0000000707a00000, 0x0000000707c00000| 0%| F| |TAMS 0x0000000707a00000, 0x0000000707a00000| Untracked +| 42|0x0000000707c00000, 0x0000000707c00000, 0x0000000707e00000| 0%| F| |TAMS 0x0000000707c00000, 0x0000000707c00000| Untracked +| 43|0x0000000707e00000, 0x0000000708000000, 0x0000000708000000|100%| O| |TAMS 0x0000000708000000, 0x0000000707e00000| Complete +| 44|0x0000000708000000, 0x0000000708200000, 0x0000000708200000|100%| O| |TAMS 0x0000000708200000, 0x0000000708000000| Untracked +| 45|0x0000000708200000, 0x0000000708400000, 0x0000000708400000|100%| O| |TAMS 0x0000000708400000, 0x0000000708200000| Untracked +| 46|0x0000000708400000, 0x0000000708600000, 0x0000000708600000|100%| O| |TAMS 0x00000007085b1200, 0x0000000708400000| Untracked +| 47|0x0000000708600000, 0x0000000708800000, 0x0000000708800000|100%| O| |TAMS 0x0000000708600000, 0x0000000708600000| Untracked +| 48|0x0000000708800000, 0x0000000708a00000, 0x0000000708a00000|100%| O| |TAMS 0x0000000708800000, 0x0000000708800000| Untracked +| 49|0x0000000708a00000, 0x0000000708c00000, 0x0000000708c00000|100%| O| |TAMS 0x0000000708a00000, 0x0000000708a00000| Untracked +| 50|0x0000000708c00000, 0x0000000708e00000, 0x0000000708e00000|100%| O| |TAMS 0x0000000708c00000, 0x0000000708c00000| Untracked +| 51|0x0000000708e00000, 0x0000000709000000, 0x0000000709000000|100%| O| |TAMS 0x0000000708e00000, 0x0000000708e00000| Untracked +| 52|0x0000000709000000, 0x00000007091a4a00, 0x0000000709200000| 82%| O| |TAMS 0x0000000709000000, 0x0000000709000000| Untracked +| 53|0x0000000709200000, 0x0000000709200000, 0x0000000709400000| 0%| F| |TAMS 0x0000000709200000, 0x0000000709200000| Untracked +| 54|0x0000000709400000, 0x0000000709400000, 0x0000000709600000| 0%| F| |TAMS 0x0000000709400000, 0x0000000709400000| Untracked +| 55|0x0000000709600000, 0x0000000709600000, 0x0000000709800000| 0%| F| |TAMS 0x0000000709600000, 0x0000000709600000| Untracked +| 56|0x0000000709800000, 0x0000000709800000, 0x0000000709a00000| 0%| F| |TAMS 0x0000000709800000, 0x0000000709800000| Untracked +| 57|0x0000000709a00000, 0x0000000709a00000, 0x0000000709c00000| 0%| F| |TAMS 0x0000000709a00000, 0x0000000709a00000| Untracked +| 58|0x0000000709c00000, 0x0000000709c00000, 0x0000000709e00000| 0%| F| |TAMS 0x0000000709c00000, 0x0000000709c00000| Untracked +| 59|0x0000000709e00000, 0x0000000709e00000, 0x000000070a000000| 0%| F| |TAMS 0x0000000709e00000, 0x0000000709e00000| Untracked +| 60|0x000000070a000000, 0x000000070a000000, 0x000000070a200000| 0%| F| |TAMS 0x000000070a000000, 0x000000070a000000| Untracked +| 61|0x000000070a200000, 0x000000070a200000, 0x000000070a400000| 0%| F| |TAMS 0x000000070a200000, 0x000000070a200000| Untracked +| 62|0x000000070a400000, 0x000000070a400000, 0x000000070a600000| 0%| F| |TAMS 0x000000070a400000, 0x000000070a400000| Untracked +| 63|0x000000070a600000, 0x000000070a600000, 0x000000070a800000| 0%| F| |TAMS 0x000000070a600000, 0x000000070a600000| Untracked +| 64|0x000000070a800000, 0x000000070a800000, 0x000000070aa00000| 0%| F| |TAMS 0x000000070a800000, 0x000000070a800000| Untracked +| 65|0x000000070aa00000, 0x000000070aa00000, 0x000000070ac00000| 0%| F| |TAMS 0x000000070aa00000, 0x000000070aa00000| Untracked +| 66|0x000000070ac00000, 0x000000070ac00000, 0x000000070ae00000| 0%| F| |TAMS 0x000000070ac00000, 0x000000070ac00000| Untracked +| 67|0x000000070ae00000, 0x000000070ae00000, 0x000000070b000000| 0%| F| |TAMS 0x000000070ae00000, 0x000000070ae00000| Untracked +| 68|0x000000070b000000, 0x000000070b000000, 0x000000070b200000| 0%| F| |TAMS 0x000000070b000000, 0x000000070b000000| Untracked +| 69|0x000000070b200000, 0x000000070b200000, 0x000000070b400000| 0%| F| |TAMS 0x000000070b200000, 0x000000070b200000| Untracked +| 70|0x000000070b400000, 0x000000070b400000, 0x000000070b600000| 0%| F| |TAMS 0x000000070b400000, 0x000000070b400000| Untracked +| 71|0x000000070b600000, 0x000000070b600000, 0x000000070b800000| 0%| F| |TAMS 0x000000070b600000, 0x000000070b600000| Untracked +| 72|0x000000070b800000, 0x000000070b800000, 0x000000070ba00000| 0%| F| |TAMS 0x000000070b800000, 0x000000070b800000| Untracked +| 73|0x000000070ba00000, 0x000000070ba00000, 0x000000070bc00000| 0%| F| |TAMS 0x000000070ba00000, 0x000000070ba00000| Untracked +| 74|0x000000070bc00000, 0x000000070bc00000, 0x000000070be00000| 0%| F| |TAMS 0x000000070bc00000, 0x000000070bc00000| Untracked +| 75|0x000000070be00000, 0x000000070be00000, 0x000000070c000000| 0%| F| |TAMS 0x000000070be00000, 0x000000070be00000| Untracked +| 76|0x000000070c000000, 0x000000070c000000, 0x000000070c200000| 0%| F| |TAMS 0x000000070c000000, 0x000000070c000000| Untracked +| 77|0x000000070c200000, 0x000000070c200000, 0x000000070c400000| 0%| F| |TAMS 0x000000070c200000, 0x000000070c200000| Untracked +| 78|0x000000070c400000, 0x000000070c400000, 0x000000070c600000| 0%| F| |TAMS 0x000000070c400000, 0x000000070c400000| Untracked +| 79|0x000000070c600000, 0x000000070c600000, 0x000000070c800000| 0%| F| |TAMS 0x000000070c600000, 0x000000070c600000| Untracked +| 80|0x000000070c800000, 0x000000070c800000, 0x000000070ca00000| 0%| F| |TAMS 0x000000070c800000, 0x000000070c800000| Untracked +| 81|0x000000070ca00000, 0x000000070ca00000, 0x000000070cc00000| 0%| F| |TAMS 0x000000070ca00000, 0x000000070ca00000| Untracked +| 82|0x000000070cc00000, 0x000000070cc00000, 0x000000070ce00000| 0%| F| |TAMS 0x000000070cc00000, 0x000000070cc00000| Untracked +| 83|0x000000070ce00000, 0x000000070ce00000, 0x000000070d000000| 0%| F| |TAMS 0x000000070ce00000, 0x000000070ce00000| Untracked +| 84|0x000000070d000000, 0x000000070d000000, 0x000000070d200000| 0%| F| |TAMS 0x000000070d000000, 0x000000070d000000| Untracked +| 85|0x000000070d200000, 0x000000070d200000, 0x000000070d400000| 0%| F| |TAMS 0x000000070d200000, 0x000000070d200000| Untracked +| 86|0x000000070d400000, 0x000000070d400000, 0x000000070d600000| 0%| F| |TAMS 0x000000070d400000, 0x000000070d400000| Untracked +| 87|0x000000070d600000, 0x000000070d600000, 0x000000070d800000| 0%| F| |TAMS 0x000000070d600000, 0x000000070d600000| Untracked +| 88|0x000000070d800000, 0x000000070d800000, 0x000000070da00000| 0%| F| |TAMS 0x000000070d800000, 0x000000070d800000| Untracked +| 89|0x000000070da00000, 0x000000070da00000, 0x000000070dc00000| 0%| F| |TAMS 0x000000070da00000, 0x000000070da00000| Untracked +| 90|0x000000070dc00000, 0x000000070dc00000, 0x000000070de00000| 0%| F| |TAMS 0x000000070dc00000, 0x000000070dc00000| Untracked +| 91|0x000000070de00000, 0x000000070de00000, 0x000000070e000000| 0%| F| |TAMS 0x000000070de00000, 0x000000070de00000| Untracked +| 92|0x000000070e000000, 0x000000070e0cecd0, 0x000000070e200000| 40%| S|CS|TAMS 0x000000070e000000, 0x000000070e000000| Complete +| 93|0x000000070e200000, 0x000000070e200000, 0x000000070e400000| 0%| F| |TAMS 0x000000070e200000, 0x000000070e200000| Untracked +| 126|0x0000000712400000, 0x0000000712400000, 0x0000000712600000| 0%| F| |TAMS 0x0000000712400000, 0x0000000712400000| Untracked + +Card table byte_map: [0x000002392d2b0000,0x000002392daa0000] _byte_map_base: 0x0000023929a9c000 + +Marking Bits (Prev, Next): (CMBitMap*) 0x00000239221afe90, (CMBitMap*) 0x00000239221afed0 + Prev Bits: [0x000002392e290000, 0x00000239321f0000) + Next Bits: [0x00000239321f0000, 0x0000023936150000) + +Polling page: 0x00000239202b0000 + +Metaspace: + +Usage: + Non-class: 57.80 MB used. + Class: 8.91 MB used. + Both: 66.70 MB used. + +Virtual space: + Non-class space: 64.00 MB reserved, 58.06 MB ( 91%) committed, 8 nodes. + Class space: 1.00 GB reserved, 9.19 MB ( <1%) committed, 1 nodes. + Both: 1.06 GB reserved, 67.25 MB ( 6%) committed. + +Chunk freelists: + Non-Class: 1.03 MB + Class: 2.73 MB + Both: 3.77 MB + +MaxMetaspaceSize: unlimited +CompressedClassSpaceSize: 1.00 GB +Initial GC threshold: 21.00 MB +Current GC threshold: 107.50 MB +CDS: on +MetaspaceReclaimPolicy: balanced + - commit_granule_bytes: 65536. + - commit_granule_words: 8192. + - virtual_space_node_default_size: 1048576. + - enlarge_chunks_in_place: 1. + - new_chunks_are_fully_committed: 0. + - uncommit_free_chunks: 1. + - use_allocation_guard: 0. + - handle_deallocations: 1. + + +Internal statistics: + +num_allocs_failed_limit: 9. +num_arena_births: 760. +num_arena_deaths: 0. +num_vsnodes_births: 9. +num_vsnodes_deaths: 0. +num_space_committed: 1076. +num_space_uncommitted: 0. +num_chunks_returned_to_freelist: 9. +num_chunks_taken_from_freelist: 3150. +num_chunk_merges: 6. +num_chunk_splits: 2243. +num_chunks_enlarged: 1710. +num_purges: 0. +num_inconsistent_stats: 0. + +CodeCache: size=49152Kb used=16349Kb max_used=16349Kb free=32802Kb + bounds [0x00000239299a0000, 0x000002392a9a0000, 0x000002392c9a0000] + total_blobs=8474 nmethods=7792 adapters=605 + compilation: enabled + stopped_count=0, restarted_count=0 + full_count=0 + +Compilation events (20 events): +Event: 10.142 Thread 0x0000023939819d70 7785 1 java.util.stream.SortedOps$RefSortingSink::accept (10 bytes) +Event: 10.142 Thread 0x0000023939819d70 nmethod 7785 0x000002392a993910 code [0x000002392a993aa0, 0x000002392a993b88] +Event: 10.257 Thread 0x0000023939819d70 7786 1 sun.reflect.generics.parser.SignatureParser::parseFormalTypeParameter (16 bytes) +Event: 10.257 Thread 0x000002393ab32560 7787 1 sun.reflect.generics.parser.SignatureParser::parseBounds (112 bytes) +Event: 10.257 Thread 0x00000239399c3c60 7788 1 sun.reflect.generics.tree.FormalTypeParameter::make (10 bytes) +Event: 10.257 Thread 0x00000239399bf740 7789 1 sun.reflect.generics.tree.FormalTypeParameter:: (15 bytes) +Event: 10.257 Thread 0x00000239399bf740 nmethod 7789 0x000002392a993c10 code [0x000002392a993da0, 0x000002392a993f18] +Event: 10.257 Thread 0x00000239399c3c60 nmethod 7788 0x000002392a993f90 code [0x000002392a994120, 0x000002392a9942d8] +Event: 10.257 Thread 0x00000239399c3c60 7790 1 sun.reflect.generics.reflectiveObjects.LazyReflectiveObjectGenerator::reifyBounds (51 bytes) +Event: 10.257 Thread 0x00000239399bf740 7791 1 sun.reflect.generics.reflectiveObjects.TypeVariableImpl::make (66 bytes) +Event: 10.257 Thread 0x0000023939819d70 nmethod 7786 0x000002392a994390 code [0x000002392a994540, 0x000002392a9947a8] +Event: 10.257 Thread 0x0000023939819d70 7792 1 sun.reflect.generics.reflectiveObjects.TypeVariableImpl:: (22 bytes) +Event: 10.257 Thread 0x0000023939819d70 nmethod 7792 0x000002392a994910 code [0x000002392a994aa0, 0x000002392a994cf8] +Event: 10.258 Thread 0x000002393ab32560 nmethod 7787 0x000002392a994d90 code [0x000002392a994fe0, 0x000002392a995698] +Event: 10.258 Thread 0x00000239399c3c60 nmethod 7790 0x000002392a995a90 code [0x000002392a995c40, 0x000002392a996028] +Event: 10.259 Thread 0x00000239399bf740 nmethod 7791 0x000002392a996210 code [0x000002392a996420, 0x000002392a996ae8] +Event: 10.278 Thread 0x00000239399bf740 7793 ! 1 jdk.proxy2.$Proxy46::annotationType (29 bytes) +Event: 10.278 Thread 0x00000239399bf740 nmethod 7793 0x000002392a996d10 code [0x000002392a996ec0, 0x000002392a9970d8] +Event: 10.283 Thread 0x00000239399bf740 7794 1 org.springframework.core.MethodParameter::clone (9 bytes) +Event: 10.283 Thread 0x00000239399bf740 nmethod 7794 0x000002392a997210 code [0x000002392a9973a0, 0x000002392a9974e8] + +GC Heap History (20 events): +Event: 7.650 GC heap after +{Heap after GC invocations=23 (full 0): + garbage-first heap total 141312K, used 46797K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 4 young (8192K), 4 survivors (8192K) + Metaspace used 55396K, committed 55936K, reserved 1097728K + class space used 7482K, committed 7744K, reserved 1048576K +} +Event: 8.005 GC heap before +{Heap before GC invocations=23 (full 0): + garbage-first heap total 141312K, used 73421K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 18 young (36864K), 4 survivors (8192K) + Metaspace used 60083K, committed 60480K, reserved 1105920K + class space used 7999K, committed 8192K, reserved 1048576K +} +Event: 8.011 GC heap after +{Heap after GC invocations=24 (full 0): + garbage-first heap total 141312K, used 48800K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 4 young (8192K), 4 survivors (8192K) + Metaspace used 60083K, committed 60480K, reserved 1105920K + class space used 7999K, committed 8192K, reserved 1048576K +} +Event: 8.790 GC heap before +{Heap before GC invocations=25 (full 0): + garbage-first heap total 141312K, used 116384K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 37 young (75776K), 4 survivors (8192K) + Metaspace used 64276K, committed 64832K, reserved 1105920K + class space used 8557K, committed 8832K, reserved 1048576K +} +Event: 8.798 GC heap after +{Heap after GC invocations=26 (full 0): + garbage-first heap total 141312K, used 55694K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 5 young (10240K), 5 survivors (10240K) + Metaspace used 64276K, committed 64832K, reserved 1105920K + class space used 8557K, committed 8832K, reserved 1048576K +} +Event: 8.912 GC heap before +{Heap before GC invocations=26 (full 0): + garbage-first heap total 141312K, used 110990K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 33 young (67584K), 5 survivors (10240K) + Metaspace used 64347K, committed 64896K, reserved 1105920K + class space used 8568K, committed 8832K, reserved 1048576K +} +Event: 8.924 GC heap after +{Heap after GC invocations=27 (full 0): + garbage-first heap total 141312K, used 71506K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 5 young (10240K), 5 survivors (10240K) + Metaspace used 64347K, committed 64896K, reserved 1105920K + class space used 8568K, committed 8832K, reserved 1048576K +} +Event: 9.052 GC heap before +{Heap before GC invocations=27 (full 0): + garbage-first heap total 141312K, used 104274K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 22 young (45056K), 5 survivors (10240K) + Metaspace used 64371K, committed 64896K, reserved 1105920K + class space used 8571K, committed 8832K, reserved 1048576K +} +Event: 9.059 GC heap after +{Heap after GC invocations=28 (full 0): + garbage-first heap total 194560K, used 78632K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 3 young (6144K), 3 survivors (6144K) + Metaspace used 64371K, committed 64896K, reserved 1105920K + class space used 8571K, committed 8832K, reserved 1048576K +} +Event: 9.226 GC heap before +{Heap before GC invocations=28 (full 0): + garbage-first heap total 194560K, used 146216K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 37 young (75776K), 3 survivors (6144K) + Metaspace used 64371K, committed 64896K, reserved 1105920K + class space used 8571K, committed 8832K, reserved 1048576K +} +Event: 9.228 GC heap after +{Heap after GC invocations=29 (full 0): + garbage-first heap total 194560K, used 77125K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 2 young (4096K), 2 survivors (4096K) + Metaspace used 64371K, committed 64896K, reserved 1105920K + class space used 8571K, committed 8832K, reserved 1048576K +} +Event: 9.385 GC heap before +{Heap before GC invocations=29 (full 0): + garbage-first heap total 194560K, used 148805K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 38 young (77824K), 2 survivors (4096K) + Metaspace used 64371K, committed 64896K, reserved 1105920K + class space used 8571K, committed 8832K, reserved 1048576K +} +Event: 9.394 GC heap after +{Heap after GC invocations=30 (full 0): + garbage-first heap total 194560K, used 94512K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 5 young (10240K), 5 survivors (10240K) + Metaspace used 64371K, committed 64896K, reserved 1105920K + class space used 8571K, committed 8832K, reserved 1048576K +} +Event: 9.525 GC heap before +{Heap before GC invocations=30 (full 0): + garbage-first heap total 194560K, used 143664K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 30 young (61440K), 5 survivors (10240K) + Metaspace used 64379K, committed 64960K, reserved 1105920K + class space used 8572K, committed 8832K, reserved 1048576K +} +Event: 9.532 GC heap after +{Heap after GC invocations=31 (full 0): + garbage-first heap total 194560K, used 103498K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 4 young (8192K), 4 survivors (8192K) + Metaspace used 64379K, committed 64960K, reserved 1105920K + class space used 8572K, committed 8832K, reserved 1048576K +} +Event: 9.733 GC heap before +{Heap before GC invocations=31 (full 0): + garbage-first heap total 194560K, used 144458K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 25 young (51200K), 4 survivors (8192K) + Metaspace used 65112K, committed 65664K, reserved 1114112K + class space used 8700K, committed 8960K, reserved 1048576K +} +Event: 9.743 GC heap after +{Heap after GC invocations=32 (full 0): + garbage-first heap total 194560K, used 113722K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 4 young (8192K), 4 survivors (8192K) + Metaspace used 65112K, committed 65664K, reserved 1114112K + class space used 8700K, committed 8960K, reserved 1048576K +} +Event: 10.242 GC heap before +{Heap before GC invocations=33 (full 0): + garbage-first heap total 194560K, used 136250K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 21 young (43008K), 4 survivors (8192K) + Metaspace used 68204K, committed 68736K, reserved 1114112K + class space used 9100K, committed 9344K, reserved 1048576K +} +Event: 10.249 GC heap after +{Heap after GC invocations=34 (full 0): + garbage-first heap total 194560K, used 107573K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 2 young (4096K), 2 survivors (4096K) + Metaspace used 68204K, committed 68736K, reserved 1114112K + class space used 9100K, committed 9344K, reserved 1048576K +} +Event: 10.300 GC heap before +{Heap before GC invocations=34 (full 0): + garbage-first heap total 194560K, used 111669K [0x0000000702800000, 0x0000000800000000) + region size 2048K, 4 young (8192K), 2 survivors (4096K) + Metaspace used 68301K, committed 68864K, reserved 1114112K + class space used 9119K, committed 9408K, reserved 1048576K +} + +Deoptimization events (18 events): +Event: 2.465 Thread 0x0000023922142190 DEOPT PACKING pc=0x0000023929fa7e79 sp=0x00000074868fd140 +Event: 2.465 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868fc620 mode 3 +Event: 2.673 Thread 0x0000023922142190 DEOPT PACKING pc=0x0000023929e2e125 sp=0x00000074868fe040 +Event: 2.673 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868fd5c0 mode 3 +Event: 4.076 Thread 0x0000023922142190 DEOPT PACKING pc=0x000002392a25e6f9 sp=0x00000074868fdfb0 +Event: 4.076 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868fd498 mode 3 +Event: 4.670 Thread 0x0000023922142190 DEOPT PACKING pc=0x000002392a2df30a sp=0x00000074868fb9b0 +Event: 4.670 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868faf48 mode 0 +Event: 5.683 Thread 0x000002393d941210 DEOPT PACKING pc=0x0000023929fb5809 sp=0x00000074892ff130 +Event: 5.683 Thread 0x000002393d941210 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074892fe5c8 mode 3 +Event: 6.498 Thread 0x0000023922142190 DEOPT PACKING pc=0x0000023929f94b62 sp=0x00000074868fcb00 +Event: 6.498 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868fc008 mode 3 +Event: 6.577 Thread 0x0000023922142190 DEOPT PACKING pc=0x000002392a5a2c54 sp=0x00000074868fcfc0 +Event: 6.577 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868fc458 mode 3 +Event: 8.707 Thread 0x0000023922142190 DEOPT PACKING pc=0x000002392a805993 sp=0x00000074868fd340 +Event: 8.707 Thread 0x0000023922142190 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x00000074868fc888 mode 3 +Event: 8.869 Thread 0x000002393df9cbb0 DEOPT PACKING pc=0x0000023929f9241f sp=0x000000748b9fefd0 +Event: 8.869 Thread 0x000002393df9cbb0 DEOPT UNPACKING pc=0x00000239299f2b43 sp=0x000000748b9fe428 mode 3 + +Classes unloaded (0 events): +No events + +Classes redefined (0 events): +No events + +Internal exceptions (20 events): +Event: 9.425 Thread 0x000002393da0d2d0 Exception (0x000000070e019580) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.426 Thread 0x000002393da0d2d0 Exception (0x000000070e0197a0) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.426 Thread 0x000002393da0d2d0 Exception (0x000000070e01a000) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.427 Thread 0x000002393da0d2d0 Exception (0x000000070e01a210) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.427 Thread 0x000002393da0d2d0 Exception (0x000000070e01aa78) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.428 Thread 0x000002393da0d2d0 Exception (0x000000070e01ac98) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.428 Thread 0x000002393da0d2d0 Exception (0x000000070e01b520) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.428 Thread 0x000002393da0d2d0 Exception (0x000000070e01b760) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.428 Thread 0x000002393da0d2d0 Exception (0x000000070e01bff8) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.428 Thread 0x000002393da0d2d0 Exception (0x000000070e01c250) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.428 Thread 0x000002393da0d2d0 Exception (0x000000070e01cae0) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.429 Thread 0x000002393da0d2d0 Exception (0x000000070e01cd30) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.549 Thread 0x0000023944212e60 Exception (0x000000070da27418) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.549 Thread 0x0000023944219840 Exception (0x000000070daafb50) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.551 Thread 0x000002393da0b5f0 Exception (0x000000070dabf8c0) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.551 Thread 0x0000023944212990 Exception (0x000000070da9e2e0) +thrown [s\open\src\hotspot\share\prims\jni.cpp, line 516] +Event: 9.815 Thread 0x0000023922142190 Exception (0x000000070e33cad8) +thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 759] +Event: 9.918 Thread 0x0000023922142190 Exception (0x000000070da6b668) +thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 826] +Event: 9.929 Thread 0x0000023922142190 Exception (0x000000070db3a638) +thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 826] +Event: 9.944 Thread 0x0000023922142190 Exception (0x000000070d83ffe0) +thrown [s\open\src\hotspot\share\interpreter\linkResolver.cpp, line 826] + +VM Operations (20 events): +Event: 9.061 Executing VM operation: G1CollectForAllocation done +Event: 9.226 Executing VM operation: G1CollectForAllocation +Event: 9.229 Executing VM operation: G1CollectForAllocation done +Event: 9.384 Executing VM operation: G1CollectForAllocation +Event: 9.395 Executing VM operation: G1CollectForAllocation done +Event: 9.525 Executing VM operation: G1CollectForAllocation +Event: 9.534 Executing VM operation: G1CollectForAllocation done +Event: 9.729 Executing VM operation: HandshakeAllThreads +Event: 9.729 Executing VM operation: HandshakeAllThreads done +Event: 9.729 Executing VM operation: HandshakeAllThreads +Event: 9.729 Executing VM operation: HandshakeAllThreads done +Event: 9.733 Executing VM operation: G1CollectForAllocation +Event: 9.743 Executing VM operation: G1CollectForAllocation done +Event: 9.792 Executing VM operation: G1Concurrent +Event: 9.797 Executing VM operation: G1Concurrent done +Event: 9.822 Executing VM operation: G1Concurrent +Event: 9.822 Executing VM operation: G1Concurrent done +Event: 10.242 Executing VM operation: G1CollectForAllocation +Event: 10.249 Executing VM operation: G1CollectForAllocation done +Event: 10.300 Executing VM operation: G1CollectForAllocation + +Events (20 events): +Event: 10.009 loading class jdk/internal/reflect/UnsafeQualifiedObjectFieldAccessorImpl +Event: 10.009 loading class jdk/internal/reflect/UnsafeQualifiedFieldAccessorImpl +Event: 10.009 loading class jdk/internal/reflect/UnsafeQualifiedFieldAccessorImpl done +Event: 10.009 loading class jdk/internal/reflect/UnsafeQualifiedObjectFieldAccessorImpl done +Event: 10.096 loading class javax/management/InstanceAlreadyExistsException +Event: 10.096 loading class javax/management/InstanceAlreadyExistsException done +Event: 10.096 loading class javax/management/NotCompliantMBeanException +Event: 10.097 loading class javax/management/NotCompliantMBeanException done +Event: 10.097 loading class javax/management/modelmbean/ModelMBean +Event: 10.098 loading class javax/management/PersistentMBean +Event: 10.098 loading class javax/management/PersistentMBean done +Event: 10.098 loading class javax/management/modelmbean/ModelMBean done +Event: 10.100 loading class javax/management/modelmbean/ModelMBeanInfo +Event: 10.101 loading class javax/management/modelmbean/ModelMBeanInfo done +Event: 10.104 loading class javax/management/AttributeList +Event: 10.105 loading class javax/management/AttributeList done +Event: 10.105 loading class javax/management/Attribute +Event: 10.105 loading class javax/management/Attribute done +Event: 10.105 loading class javax/management/IntrospectionException +Event: 10.105 loading class javax/management/IntrospectionException done + + +Dynamic libraries: +0x00007ff64dcf0000 - 0x00007ff64dd00000 D:\Program Files\Java\jdk-17.0.7\bin\java.exe +0x00007ffc6a190000 - 0x00007ffc6a3a7000 C:\WINDOWS\SYSTEM32\ntdll.dll +0x00007ffc68900000 - 0x00007ffc689c4000 C:\WINDOWS\System32\KERNEL32.DLL +0x00007ffc675b0000 - 0x00007ffc67957000 C:\WINDOWS\System32\KERNELBASE.dll +0x00007ffc67a50000 - 0x00007ffc67b61000 C:\WINDOWS\System32\ucrtbase.dll +0x00007ffc63a20000 - 0x00007ffc63a3b000 D:\Program Files\Java\jdk-17.0.7\bin\VCRUNTIME140.dll +0x00007ffc63e20000 - 0x00007ffc63e39000 D:\Program Files\Java\jdk-17.0.7\bin\jli.dll +0x00007ffc69a60000 - 0x00007ffc69b12000 C:\WINDOWS\System32\ADVAPI32.dll +0x00007ffc68740000 - 0x00007ffc687e7000 C:\WINDOWS\System32\msvcrt.dll +0x00007ffc67f40000 - 0x00007ffc67fe8000 C:\WINDOWS\System32\sechost.dll +0x00007ffc67490000 - 0x00007ffc674b8000 C:\WINDOWS\System32\bcrypt.dll +0x00007ffc683b0000 - 0x00007ffc684c5000 C:\WINDOWS\System32\RPCRT4.dll +0x00007ffc68ea0000 - 0x00007ffc6904e000 C:\WINDOWS\System32\USER32.dll +0x00007ffc67580000 - 0x00007ffc675a6000 C:\WINDOWS\System32\win32u.dll +0x00007ffc48c30000 - 0x00007ffc48ec3000 C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.22621.3527_none_270e469b73872a76\COMCTL32.dll +0x00007ffc69c20000 - 0x00007ffc69c49000 C:\WINDOWS\System32\GDI32.dll +0x00007ffc67d80000 - 0x00007ffc67e99000 C:\WINDOWS\System32\gdi32full.dll +0x00007ffc67ce0000 - 0x00007ffc67d7a000 C:\WINDOWS\System32\msvcp_win.dll +0x00007ffc5b4a0000 - 0x00007ffc5b4aa000 C:\WINDOWS\SYSTEM32\VERSION.dll +0x00007ffc69be0000 - 0x00007ffc69c11000 C:\WINDOWS\System32\IMM32.DLL +0x00007ffc64750000 - 0x00007ffc6475c000 D:\Program Files\Java\jdk-17.0.7\bin\vcruntime140_1.dll +0x00007ffc53d20000 - 0x00007ffc53dae000 D:\Program Files\Java\jdk-17.0.7\bin\msvcp140.dll +0x00007ffbe1a40000 - 0x00007ffbe261d000 D:\Program Files\Java\jdk-17.0.7\bin\server\jvm.dll +0x00007ffc68d30000 - 0x00007ffc68d38000 C:\WINDOWS\System32\PSAPI.DLL +0x00007ffc5f4b0000 - 0x00007ffc5f4e4000 C:\WINDOWS\SYSTEM32\WINMM.dll +0x00007ffc440a0000 - 0x00007ffc440a9000 C:\WINDOWS\SYSTEM32\WSOCK32.dll +0x00007ffc69c50000 - 0x00007ffc69cc1000 C:\WINDOWS\System32\WS2_32.dll +0x00007ffc664f0000 - 0x00007ffc66508000 C:\WINDOWS\SYSTEM32\kernel.appcore.dll +0x00007ffc63df0000 - 0x00007ffc63dfa000 D:\Program Files\Java\jdk-17.0.7\bin\jimage.dll +0x00007ffc5e660000 - 0x00007ffc5e892000 C:\WINDOWS\SYSTEM32\DBGHELP.DLL +0x00007ffc68000000 - 0x00007ffc68388000 C:\WINDOWS\System32\combase.dll +0x00007ffc68ba0000 - 0x00007ffc68c77000 C:\WINDOWS\System32\OLEAUT32.dll +0x00007ffc5a360000 - 0x00007ffc5a392000 C:\WINDOWS\SYSTEM32\dbgcore.DLL +0x00007ffc67960000 - 0x00007ffc679d9000 C:\WINDOWS\System32\bcryptPrimitives.dll +0x00007ffc623e0000 - 0x00007ffc623ee000 D:\Program Files\Java\jdk-17.0.7\bin\instrument.dll +0x00007ffc60230000 - 0x00007ffc60255000 D:\Program Files\Java\jdk-17.0.7\bin\java.dll +0x00007ffc09680000 - 0x00007ffc09757000 D:\Program Files\Java\jdk-17.0.7\bin\jsvml.dll +0x00007ffc69200000 - 0x00007ffc69a5c000 C:\WINDOWS\System32\SHELL32.dll +0x00007ffc65340000 - 0x00007ffc65c36000 C:\WINDOWS\SYSTEM32\windows.storage.dll +0x00007ffc65200000 - 0x00007ffc6533e000 C:\WINDOWS\SYSTEM32\wintypes.dll +0x00007ffc68800000 - 0x00007ffc688f5000 C:\WINDOWS\System32\SHCORE.dll +0x00007ffc68630000 - 0x00007ffc6868e000 C:\WINDOWS\System32\shlwapi.dll +0x00007ffc673c0000 - 0x00007ffc673e1000 C:\WINDOWS\SYSTEM32\profapi.dll +0x00007ffc598e0000 - 0x00007ffc598f8000 D:\Program Files\Java\jdk-17.0.7\bin\zip.dll +0x00007ffc5f5e0000 - 0x00007ffc5f5f9000 D:\Program Files\Java\jdk-17.0.7\bin\net.dll +0x00007ffc61240000 - 0x00007ffc61376000 C:\WINDOWS\SYSTEM32\WINHTTP.dll +0x00007ffc66950000 - 0x00007ffc669b9000 C:\WINDOWS\system32\mswsock.dll +0x00007ffc5a280000 - 0x00007ffc5a296000 D:\Program Files\Java\jdk-17.0.7\bin\nio.dll +0x00007ffc53d00000 - 0x00007ffc53d1a000 D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.4\bin\breakgen64.dll +0x00007ffc65f80000 - 0x00007ffc66078000 C:\WINDOWS\SYSTEM32\DNSAPI.dll +0x00007ffc65f10000 - 0x00007ffc65f3d000 C:\WINDOWS\SYSTEM32\IPHLPAPI.DLL +0x00007ffc687f0000 - 0x00007ffc687f9000 C:\WINDOWS\System32\NSI.dll +0x00007ffc5c700000 - 0x00007ffc5c70a000 C:\Windows\System32\rasadhlp.dll +0x00007ffc5fa90000 - 0x00007ffc5fb13000 C:\WINDOWS\System32\fwpuclnt.dll +0x00007ffc61450000 - 0x00007ffc6145a000 D:\Program Files\Java\jdk-17.0.7\bin\management.dll +0x00007ffc60530000 - 0x00007ffc6053b000 D:\Program Files\Java\jdk-17.0.7\bin\management_ext.dll +0x00007ffc66bf0000 - 0x00007ffc66c0b000 C:\WINDOWS\SYSTEM32\CRYPTSP.dll +0x00007ffc66450000 - 0x00007ffc66485000 C:\WINDOWS\system32\rsaenh.dll +0x00007ffc669f0000 - 0x00007ffc66a18000 C:\WINDOWS\SYSTEM32\USERENV.dll +0x00007ffc66b60000 - 0x00007ffc66b6c000 C:\WINDOWS\SYSTEM32\CRYPTBASE.dll +0x00007ffc60f60000 - 0x00007ffc60f79000 C:\WINDOWS\SYSTEM32\dhcpcsvc6.DLL +0x00007ffc60eb0000 - 0x00007ffc60ecf000 C:\WINDOWS\SYSTEM32\dhcpcsvc.DLL +0x00007ffc3b460000 - 0x00007ffc3b477000 C:\WINDOWS\system32\napinsp.dll +0x00007ffc32db0000 - 0x00007ffc32dcb000 C:\WINDOWS\system32\pnrpnsp.dll +0x00007ffc32d90000 - 0x00007ffc32da1000 C:\WINDOWS\System32\winrnr.dll +0x00007ffc60090000 - 0x00007ffc600a5000 C:\WINDOWS\system32\wshbth.dll +0x00007ffc32d60000 - 0x00007ffc32d87000 C:\WINDOWS\system32\nlansp_c.dll +0x00007ffc5a160000 - 0x00007ffc5a170000 D:\Program Files\Java\jdk-17.0.7\bin\verify.dll +0x00007ffc60310000 - 0x00007ffc6031d000 D:\Program Files\Java\jdk-17.0.7\bin\sunmscapi.dll +0x00007ffc67b70000 - 0x00007ffc67cd8000 C:\WINDOWS\System32\CRYPT32.dll +0x00007ffc66dc0000 - 0x00007ffc66dee000 C:\WINDOWS\SYSTEM32\ncrypt.dll +0x00007ffc66d80000 - 0x00007ffc66db7000 C:\WINDOWS\SYSTEM32\NTASN1.dll +0x00007ffc2b460000 - 0x00007ffc2b468000 C:\WINDOWS\system32\wshunix.dll + +dbghelp: loaded successfully - version: 4.0.5 - missing functions: none +symbol engine: initialized successfully - sym options: 0x614 - pdb path: .;D:\Program Files\Java\jdk-17.0.7\bin;C:\WINDOWS\SYSTEM32;C:\WINDOWS\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.22621.3527_none_270e469b73872a76;D:\Program Files\Java\jdk-17.0.7\bin\server;D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.4\bin + +VM Arguments: +jvm_args: -XX:TieredStopAtLevel=1 -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dmanagement.endpoints.jmx.exposure.include=* -javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.4\lib\idea_rt.jar=62085:D:\Program Files\JetBrains\IntelliJ IDEA 2021.2.4\bin -Dfile.encoding=UTF-8 +java_command: cn.workde.Application +java_class_path (initial): D:\IDEA\club-nfc\target\classes;C:\Users\li.jiaqi\.m2\repository\org\springframework\boot\spring-boot-starter-web\3.0.4\spring-boot-starter-web-3.0.4.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\boot\spring-boot-starter\3.0.4\spring-boot-starter-3.0.4.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\boot\spring-boot\3.0.4\spring-boot-3.0.4.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\boot\spring-boot-starter-logging\3.0.4\spring-boot-starter-logging-3.0.4.jar;C:\Users\li.jiaqi\.m2\repository\ch\qos\logback\logback-classic\1.4.5\logback-classic-1.4.5.jar;C:\Users\li.jiaqi\.m2\repository\ch\qos\logback\logback-core\1.4.5\logback-core-1.4.5.jar;C:\Users\li.jiaqi\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.19.0\log4j-to-slf4j-2.19.0.jar;C:\Users\li.jiaqi\.m2\repository\org\apache\logging\log4j\log4j-api\2.19.0\log4j-api-2.19.0.jar;C:\Users\li.jiaqi\.m2\repository\org\slf4j\jul-to-slf4j\2.0.6\jul-to-slf4j-2.0.6.jar;C:\Users\li.jiaqi\.m2\repository\jakarta\annotation\jakarta.annotation-api\2.1.1\jakarta.annotation-api-2.1.1.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\spring-core\6.0.6\spring-core-6.0.6.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\spring-jcl\6.0.6\spring-jcl-6.0.6.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\boot\spring-boot-starter-json\3.0.4\spring-boot-starter-json-3.0.4.jar;C:\Users\li.jiaqi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.14.2\jackson-datatype-jdk8-2.14.2.jar;C:\Users\li.jiaqi\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.14.2\jackson-datatype-jsr310-2.14.2.jar;C:\Users\li.jiaqi\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.14.2\jackson-module-parameter-names-2.14.2.jar;C:\Users\li.jiaqi\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\3.0.4\spring-boot-starter-tomcat-3.0.4.jar;C:\Users\li.jiaqi\.m2\repository\org\apache\tomcat\emb +Launcher Type: SUN_STANDARD + +[Global flags] + intx CICompilerCount = 4 {product} {ergonomic} + uint ConcGCThreads = 2 {product} {ergonomic} + uint G1ConcRefinementThreads = 8 {product} {ergonomic} + size_t G1HeapRegionSize = 2097152 {product} {ergonomic} + uintx GCDrainStackTargetSize = 64 {product} {ergonomic} + size_t InitialHeapSize = 266338304 {product} {ergonomic} + bool ManagementServer = true {product} {command line} + size_t MarkStackSize = 4194304 {product} {ergonomic} + size_t MaxHeapSize = 4253024256 {product} {ergonomic} + size_t MaxNewSize = 2550136832 {product} {ergonomic} + size_t MinHeapDeltaBytes = 2097152 {product} {ergonomic} + size_t MinHeapSize = 8388608 {product} {ergonomic} + uintx NonProfiledCodeHeapSize = 0 {pd product} {ergonomic} + bool ProfileInterpreter = false {pd product} {command line} + uintx ProfiledCodeHeapSize = 0 {pd product} {ergonomic} + size_t SoftMaxHeapSize = 4253024256 {manageable} {ergonomic} + intx TieredStopAtLevel = 1 {product} {command line} + 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=D:\Program Files\Java\jdk1.8.0_291 +CLASSPATH=D:\apache-jmeter-5.5\lib\ext\ApacheJMeter_core.jar;D:\apache-jmeter-5.5\lib\jorphan.jar;D:\apache-jmeter-5.5\lib\logkit-2.0.jar +PATH=D:\Program Files\Java\jdk1.8.0_291\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\Program Files\Bandizip\;D:\Program Files\Maven\apache-maven-3.8.6\bin;D:\Program Files\MySQL\MySQL Server 8.0\bin;C:\Program Files\Docker\Docker\resources\bin;C:\Program Files (x86)\EasyShare\x86\;C:\Program Files (x86)\EasyShare\x64\;D:\Program Files (x86)\nodejs\;D:\Program Files\Git\cmd;C:\Users\li.jiaqi\AppData\Local\Microsoft\WindowsApps;C:\Users\li.jiaqi\AppData\Roaming\npm +USERNAME=li.jiaqi +OS=Windows_NT +PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 142 Stepping 12, GenuineIntel + + + +--------------- S Y S T E M --------------- + +OS: + Windows 11 , 64 bit Build 22621 (10.0.22621.3527) +OS uptime: 0 days 23:41 hours +Hyper-V role detected + +CPU: total 8 (initial active 8) (4 cores per cpu, 2 threads per core) family 6 model 142 stepping 12 microcode 0xde, 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, fma, vzeroupper, clflush, clflushopt, hv + +Memory: 4k page, system-wide physical 16217M (393M free) +TotalPageFile size 35150M (AvailPageFile size 105M) +current process WorkingSet (physical memory assigned to process): 425M, peak: 425M +current process commit charge ("private bytes"): 470M, peak: 534M + +vm_info: Java HotSpot(TM) 64-Bit Server VM (17.0.7+8-LTS-224) for windows-amd64 JRE (17.0.7+8-LTS-224), built on Feb 28 2023 23:03:02 by "mach5one" with MS VC++ 17.1 (VS2022) + +END. diff --git a/ip/qqzeng-ip-utf8.dat b/ip/qqzeng-ip-utf8.dat new file mode 100644 index 0000000..a0edc15 Binary files /dev/null and b/ip/qqzeng-ip-utf8.dat differ diff --git a/lib/DmJdbcDriver18.jar b/lib/DmJdbcDriver18.jar new file mode 100644 index 0000000..de8e1cc Binary files /dev/null and b/lib/DmJdbcDriver18.jar differ diff --git a/lib/xwy-saas-data.client-1.2.0.jar b/lib/xwy-saas-data.client-1.2.0.jar new file mode 100644 index 0000000..b15f90f Binary files /dev/null and b/lib/xwy-saas-data.client-1.2.0.jar differ diff --git a/lib/xxpt.gateway.shared.client-1.0.jar b/lib/xxpt.gateway.shared.client-1.0.jar new file mode 100644 index 0000000..43d2d86 Binary files /dev/null and b/lib/xxpt.gateway.shared.client-1.0.jar differ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..31a55fa --- /dev/null +++ b/pom.xml @@ -0,0 +1,431 @@ + + + 4.0.0 + + + org.springframework.boot + spring-boot-starter-parent + 3.0.4 + + + + + cn.workde + club-nfc + 1.0-SNAPSHOT + + + 17 + 17 + 4.3.0 + 5.8.11 + 0.11.5 + 1.1.21 + 8.0.22 + 3.5.6 + 1.4.12 + 1.5.3.Final + 3.20.0 + 3.3.2 + + 1.38.0 + + + ${project.artifactId}-${project.version} + target/build + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + org.springframework.boot + spring-boot-starter-undertow + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-undertow + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.springframework.boot + spring-boot-starter-websocket + + + + mysql + mysql-connector-java + ${mysql.version} + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatisplus.version} + + + + com.github.yulichang + mybatis-plus-join-boot-starter + ${mybatisplus.join.version} + + + + com.baomidou + mybatis-plus-generator + ${mybatisplus.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + + + io.jsonwebtoken + jjwt-impl + ${jjwt.version} + + + io.jsonwebtoken + jjwt-jackson + ${jjwt.version} + + + + org.mapstruct + mapstruct + ${mapstruct.version} + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + + + + + org.projectlombok + lombok + provided + + + + com.github.xiaoymin + knife4j-openapi3-jakarta-spring-boot-starter + ${knife4j.version} + + + org.redisson + redisson + ${redisson.version} + + + + com.alibaba + easyexcel + ${easyexcel.version} + + + + net.sf.ehcache + ehcache + 1.2.3 + + + + org.springframework.boot + spring-boot-starter-cache + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.aspectj + aspectjweaver + + + + + com.aliyun + aliyun-java-sdk-core + 4.1.0 + + + com.aliyun + aliyun-java-sdk-dysmsapi + 1.1.0 + + + + joda-time + joda-time + 2.10 + + + + + org.apache.velocity + velocity-engine-core + 2.0 + + + + com.dahuatech.icc + java-sdk-oauth + 1.0.9.2 + + + + + org.apache.poi + poi-ooxml-schemas + 4.1.2 + + + org.apache.poi + poi-ooxml + 4.1.2 + + + org.apache.poi + poi + 4.1.2 + + + + org.apache.commons + commons-lang3 + + + org.apache.httpcomponents + httpclient + + + joda-time + joda-time + 2.10 + + + + eu.bitwalker + UserAgentUtils + 1.21 + + + + + com.ejlchina + okhttps + 3.2.0 + + + + + + cn.dev33 + sa-token-spring-boot3-starter + ${sa-token-spring-boot3-starter.version} + + + + + cn.dev33 + sa-token-jwt + ${sa-token-spring-boot3-starter.version} + + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.3.0 + + + + true + + lib/ + + false + + cn.workde.Application + + + + ./resources/ + + + ${project.build.directory} + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.6.0 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/lib/ + + + + + + + + maven-resources-plugin + + + + copy-resources + package + + copy-resources + + + + + src/main/resources + + *.properties + *.xml + *.yml + + + *.jar + + + + ${project.build.directory}/resources + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 3.1.1 + + true + true + + + + null + null + + + ZIP + + true + ${project.build.directory}/resources + + + + + + repackage + + + + + + + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + 3.1.0 + + + package + + run + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + maven_central + Maven Central + https://repo.maven.apache.org/maven2/ + + + \ No newline at end of file diff --git a/src/main/java/cn/workde/Application.java b/src/main/java/cn/workde/Application.java new file mode 100644 index 0000000..f1347be --- /dev/null +++ b/src/main/java/cn/workde/Application.java @@ -0,0 +1,22 @@ +package cn.workde; + +import com.mysql.cj.x.protobuf.MysqlxDatatypes; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.web.filter.ForwardedHeaderFilter; +import org.springframework.web.socket.config.annotation.EnableWebSocket; + +@SpringBootApplication +@EnableCaching +@EnableAsync +@EnableScheduling +@EnableWebSocket +public class Application { + public static void main(String[] args) { + SpringApplication.run(Application.class,args); + } +} diff --git a/src/main/java/cn/workde/MybatisPlusGenerator.java b/src/main/java/cn/workde/MybatisPlusGenerator.java new file mode 100644 index 0000000..97df5c2 --- /dev/null +++ b/src/main/java/cn/workde/MybatisPlusGenerator.java @@ -0,0 +1,128 @@ +package cn.workde; + + +import cn.workde.core.base.BaseEntity; +import cn.workde.core.base.BaseService; +import cn.workde.module.dss.core.BaseController; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.service.IService; +import com.baomidou.mybatisplus.generator.FastAutoGenerator; +import com.baomidou.mybatisplus.generator.config.DataSourceConfig; +import com.baomidou.mybatisplus.generator.config.OutputFile; +import com.baomidou.mybatisplus.generator.config.TemplateType; +import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert; +import com.baomidou.mybatisplus.generator.config.rules.DateType; +import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; +import org.apache.ibatis.annotations.Mapper; + + +import java.util.Collections; + +/** + * @Author liuj + * @Date 2023/5/11 10:20 + * @PackageName:cn.workde + * @ClassName: MybatisPlusGenerator + * @Description: TODO + * @Version 1.0 + */ +public class MybatisPlusGenerator { + /** JDBC相关配置 */ + private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; + private static final String URL = "jdbc:mysql://rm-bp18s305vwk8l073t4o.mysql.rds.aliyuncs.com:3306/data_station?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false"; + private static final String USER_NAME = "data_station"; + private static final String PASSWORD = "RtnHKn8j8rwSpCEs"; + + private static final String AUTHOR = "st"; + + /** 输出文件的路径 */ + public static String getWebRoot() { + return System.getProperty("user.dir"); + } + private static final String OUT_PATH = getWebRoot()+"\\src\\main\\java"; + + private static final String XML_OUT_PATH = getWebRoot()+"\\src\\main\\resources"; + + + public static void main(String[] args) { + /** + * 配置数据库 + */ + DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig.Builder(URL, USER_NAME, PASSWORD) + .typeConvert(new MySqlTypeConvert()); + + FastAutoGenerator fastAutoGenerator = FastAutoGenerator.create(dataSourceConfigBuilder); + /** + * 全局配置 + */ + fastAutoGenerator.globalConfig(builder -> { + builder.outputDir(OUT_PATH) + .author(AUTHOR) + .enableSpringdoc() + .dateType(DateType.TIME_PACK) + .commentDate("yyyy-MM-dd HH:mm:ss").build(); + }); + + fastAutoGenerator.packageConfig(builder -> { + builder.parent("cn.workde.module.xzzgydn.openApiDoc") + .entity("data.entity") + .service("service") + .mapper("mapper") + .controller("controller") + .pathInfo(Collections.singletonMap(OutputFile.xml, XML_OUT_PATH+"/mappers")) // 设置mapperXml生成路径 + .build(); + }); + + fastAutoGenerator.templateConfig(builder -> { + builder.disable(TemplateType.ENTITY,TemplateType.SERVICE,TemplateType.SERVICE_IMPL,TemplateType.CONTROLLER) + .entity("/templates/entity.java") + .service("/templates/service.java") + .serviceImpl("/templates/serviceImpl.java") + .controller("/templates/controller.java") + .build(); + }); + + fastAutoGenerator.strategyConfig(builder -> { + + builder.entityBuilder() + .superClass(BaseEntity.class) + .disableSerialVersionUID() + .enableChainModel() + .enableLombok() + .enableRemoveIsPrefix() + .naming(NamingStrategy.underline_to_camel)// 表映射 驼峰命名 + .columnNaming(NamingStrategy.underline_to_camel) // 字段映射 驼峰 + .addSuperEntityColumns("id", "created_id", "created_at", "updated_id", "updated_at") + .idType(IdType.ASSIGN_UUID) + .formatFileName("%sEntity").build(); + + builder.controllerBuilder() + .controllerBuilder() + .superClass(BaseController.class) + .enableRestStyle() + .formatFileName("%sController") + .build(); + + builder.serviceBuilder() + .superServiceClass(IService.class) + .formatServiceFileName("I%sService") + .superServiceImplClass(BaseService.class) + .formatServiceImplFileName("%sServiceImpl") + .build(); + + builder.mapperBuilder() + .superClass(BaseMapper.class) + .mapperAnnotation(Mapper.class) + .enableBaseResultMap() + .enableBaseColumnList() + .formatMapperFileName("%sMapper") + .build(); + + builder.addInclude("dss_xzzgydn_open_api_applyment") + .addTablePrefix("dss_xzzgydn_", "c_").build(); + builder.enableSchema(); + }); + fastAutoGenerator.execute(); + } +} diff --git a/src/main/java/cn/workde/core/annotation/ApiLog.java b/src/main/java/cn/workde/core/annotation/ApiLog.java new file mode 100644 index 0000000..09b0949 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/ApiLog.java @@ -0,0 +1,14 @@ +package cn.workde.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface ApiLog { + + String value() default ""; + String type() default "INFO"; +} diff --git a/src/main/java/cn/workde/core/annotation/BindMapper.java b/src/main/java/cn/workde/core/annotation/BindMapper.java new file mode 100644 index 0000000..b842032 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/BindMapper.java @@ -0,0 +1,13 @@ +package cn.workde.core.annotation; + +import com.baomidou.mybatisplus.core.mapper.Mapper; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Documented +public @interface BindMapper { + + Class> value(); +} diff --git a/src/main/java/cn/workde/core/annotation/FieldEncrypt.java b/src/main/java/cn/workde/core/annotation/FieldEncrypt.java new file mode 100644 index 0000000..af8f1f0 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/FieldEncrypt.java @@ -0,0 +1,11 @@ +package cn.workde.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface FieldEncrypt { +} \ No newline at end of file diff --git a/src/main/java/cn/workde/core/annotation/FieldSensitive.java b/src/main/java/cn/workde/core/annotation/FieldSensitive.java new file mode 100644 index 0000000..fe381a2 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/FieldSensitive.java @@ -0,0 +1,16 @@ +package cn.workde.core.annotation; + +import cn.hutool.core.util.DesensitizedUtil; +import com.fasterxml.jackson.annotation.JacksonAnnotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@JacksonAnnotation +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface FieldSensitive { + DesensitizedUtil.DesensitizedType type() default DesensitizedUtil.DesensitizedType.MOBILE_PHONE; +} diff --git a/src/main/java/cn/workde/core/annotation/Filter.java b/src/main/java/cn/workde/core/annotation/Filter.java new file mode 100644 index 0000000..2396bf6 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/Filter.java @@ -0,0 +1,22 @@ +package cn.workde.core.annotation; + +import cn.workde.core.annotation.data.Expression; +import cn.workde.core.annotation.data.InputType; + +import java.beans.Transient; + +public @interface Filter { + + /** + * 页面标题 + * @return + */ + String label() default ""; + + @Transient + Expression expression() default Expression.EQ; + + String placeholder() default ""; + + InputType type() default InputType.TEXT; +} diff --git a/src/main/java/cn/workde/core/annotation/Grape.java b/src/main/java/cn/workde/core/annotation/Grape.java new file mode 100644 index 0000000..a0c7317 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/Grape.java @@ -0,0 +1,161 @@ +package cn.workde.core.annotation; + +import cn.workde.core.annotation.data.*; +import com.baomidou.mybatisplus.core.mapper.Mapper; + +import java.beans.Transient; +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Grape { + + /** + * Entity 标题 + * 该标题被用在新增或者修改 dialog标题上 + * @return + */ + String title(); + + /** + * Entity的主键 默认为 id + * @return + */ + String primaryKey() default "id"; + + /** + * 列表页标题 + * @return + */ + String header() default ""; + + /** + * 列表查询默认排序字段 + * @return + */ + @Transient + String orderBy() default ""; + + /** + * 列表查询默认排序方向 asc or desc + * @return + */ + @Transient + String orderDir() default ""; + + /** + * 拥有的功能 + * @return + */ + @Transient + Power power() default @Power(); + + boolean isPage() default true; + + /** + * 是否使用树结构的表格 + * @return + */ + boolean isTree() default false; + + /** + * 页面类型 + * @return + */ + PageType pageType() default PageType.CRUD; + + /** + * 树结构的一些配置 + * @return + */ + @Transient + Tree tree() default @Tree(); + + /** + * 默认一行两列 + * @return + */ + @Transient + int cols() default 2; + + /** + * 新增 修改 弹框的 宽度 + * @return + */ + int formWidth() default 600; + + /** + * 新增 修改 弹框的 宽度 + * @return + */ + int labelWidth() default 100; + + /** + * table 操作 列的 宽度 + * @return + */ + int actionWidth() default 120; + + /** + * table toolbar 的动作 + * @return + */ + @Transient + GrapeAction[] toolbarList() default {}; + + /** + * table 操作列 的动作 + * @return + */ + @Transient + GrapeAction[] actionList() default {}; + + /** + * 默认 查询条件 {pid:id} + * @return + */ + @Transient + String[] params() default {}; + + /** + * 数据行为代理接口,对增、删、改、查等行为做逻辑处理 + * @return + */ + @Transient + Class>[] dataProxy() default {}; + + /** + * 关联组件的配置 + * @return + */ + @Transient + Dill dill() default @Dill(); + + String toTableName() default ""; + + @Transient + Class> mapper(); + + /** + * 新建 修改页面的 子表 + * @return + */ + @Transient + TabTable tabTable() default @TabTable(); + + /** + * 左右树结构 + * @return + */ + @Transient + TreeLink treeLink() default @TreeLink(); + + /** + * 新建窗口 + * @return + */ + boolean newWin() default false; + + String formSubmitUrl() default ""; +} diff --git a/src/main/java/cn/workde/core/annotation/GrapeAction.java b/src/main/java/cn/workde/core/annotation/GrapeAction.java new file mode 100644 index 0000000..ab7635c --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/GrapeAction.java @@ -0,0 +1,58 @@ +package cn.workde.core.annotation; + +import cn.workde.core.annotation.data.ActionType; +import cn.workde.core.annotation.data.Empty; + +import java.beans.Transient; + +public @interface GrapeAction { + + String label(); + + String showOn() default ""; + + /** + * type = dialog-form 时必填,给按钮取一个名字 + * @return + */ + String power() default ""; + + /** + * type = dialog-table + * @return + */ + Class clazz() default Empty.class; + + /** + * type = dialog-form + * @return + */ + @Transient + Class[] formClazz() default {}; + + /** + * ajax dialog-tree dialog-table comp dialog-form + * @return + */ + ActionType type() default ActionType.AUTO; + + String comp() default ""; + + String confirm() default ""; + + String getUrl() default ""; + + String postUrl() default ""; + @Transient + String[] params() default {}; + + int width() default 600; + + String userType() default ""; + + boolean checkBox() default true; + + boolean reload() default false; + + boolean self() default false; +} diff --git a/src/main/java/cn/workde/core/annotation/GrapeField.java b/src/main/java/cn/workde/core/annotation/GrapeField.java new file mode 100644 index 0000000..600f128 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/GrapeField.java @@ -0,0 +1,256 @@ +package cn.workde.core.annotation; + +import cn.workde.core.annotation.data.BoolType; +import cn.workde.core.annotation.data.Empty; +import cn.workde.core.annotation.data.Expression; +import cn.workde.core.annotation.data.InputType; +import cn.workde.core.constant.ExcelConst; + +import java.beans.Transient; +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface GrapeField { + + /** + * 组件标题 + * @return + */ + String label(); + + /** + * excel导入导出模板 表头 + * @return + */ + String excelLabel() default ""; + + /** + * excel 下拉数据验证 例:男,女 + * @return + */ + String[] excelDataValidation() default {}; + + /** + * excel 下拉数据验证类型 自定义:input,字典:dict + * @return + */ + String excelDataValidationType() default ExcelConst.VALID_INPUT; + + /** + * excel模板字典code + * @return + */ + @Transient + String excelTemDict() default ""; + + /** + * 字段名 + * @return + */ + String name() default ""; + + /** + * 显示字段 + * @return + */ + boolean named() default false; + /** + * 排列顺序 + * @return + */ + @Transient + int sort() default 10; + + String placeholder() default ""; + + /** + * 自动补全 off/on + * @return + */ + String autocomplete() default "off"; + + /** + * 是否显示清空按钮 + * @return + */ + boolean clearable() default true; + + /** + * 是否必填 + * @return + */ + boolean required() default false; + + /** + * 是否验证手机号 + * @return + */ + boolean phone() default false; + + /** + * 是否验证身份证 + * @return + */ + boolean idCard() default false; + + /** + * 组件类型 + * @return + */ + InputType type() default InputType.TEXT; + + /** + * 下拉组件的数据 {true:是,false:否} + * @return + */ + @Transient + String[] options() default {}; + + /** + * 布尔组件的数据设置 + * @return + */ + @Transient + BoolType boolType() default @BoolType(); + + /** + * 字典分类编码 + * @return + */ + @Transient + String dict() default ""; + + /** + * 日期,数字类型格式化 + * @return + */ + @Transient + String format() default "yyyy-MM-dd HH:mm:ss"; + + /** + * 是否支持排序 + * @return + */ + boolean sortable() default false; + + /** + * 是否在列表页面显示 + * @return + */ + @Transient + boolean isList() default true; + + /** + * 是否在新增页面显示 + * @return + */ + @Transient + boolean isAdd() default true; + + /** + * 是否在修改页面显示 + * @return + */ + @Transient + boolean isEdit() default true; + + /** + * 是否支持查询 + * @return + */ + @Transient + boolean isFilter() default false; + + /** + * 自动生成条件 + * @return + */ + @Transient + boolean autoFilter() default true; + + /** + * 查询的模式 like eq in + * @return + */ + @Transient + Expression expression() default Expression.EQ; + + /** + * 所占列数 + * @return + */ + @Transient + int col() default 1; + + /** + * 列表宽度 像素 或者 百分比 + * @return + */ + String width() default ""; + + /** + * 表单页面 显示条件 formData.value.type == '1' + * @return + */ + String showOn() default ""; + + /** + * 联动文本框名称 + * @return + */ + String dillName() default ""; + + /** + * 树型下拉框 是否允许选择父级 + * @return + */ + boolean disableBranchNodes() default false; + + /** + * 联动文本框的实体 + * @return + */ + @Transient + Class clazz() default Empty.class; + + /** + * 导入字段 + * @return + */ + @Transient + boolean imp() default false; + + /** + * 导出字段 + * @return + */ + @Transient + boolean exp() default false; + + /** + * 是否多选 + * @return + */ + boolean multiple() default false; + + /** + * 是否是加密字段 + * @return + */ + @Transient + boolean isSecret() default false; + + String showColumn() default ""; + + String showValue() default ""; + + boolean proxy() default false; + + String[] onSelect() default {}; + + boolean readonly() default false; + + boolean isFieldEncrypt() default false; +} diff --git a/src/main/java/cn/workde/core/annotation/Power.java b/src/main/java/cn/workde/core/annotation/Power.java new file mode 100644 index 0000000..28e82e6 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/Power.java @@ -0,0 +1,47 @@ +package cn.workde.core.annotation; + +public @interface Power { + + /** + * 新建 + * @return + */ + boolean add() default true; + + /** + * 编辑 + * @return + */ + boolean edit() default true; + + String editShowOn() default ""; + + /** + * 删除 + * @return + */ + boolean delete() default true; + + String deleteShowOn() default ""; + + /** + * 查看 + * @return + */ + boolean detail() default false; + + boolean print() default false; + /** + * 导入 + * @return + */ + boolean imp() default false; + + /** + * 导出 + * @return + */ + boolean exp() default false; + + boolean checkbox() default false; +} diff --git a/src/main/java/cn/workde/core/annotation/Tree.java b/src/main/java/cn/workde/core/annotation/Tree.java new file mode 100644 index 0000000..7d0d201 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/Tree.java @@ -0,0 +1,31 @@ +package cn.workde.core.annotation; + +import cn.workde.core.annotation.data.InputType; + +public @interface Tree { + + /** + * 树的ID + * @return + */ + String id() default "id"; + + /** + * 树的PID + * @return + */ + String pid() default "pid"; + + /** + * 父类 + * @return + */ + String expr() default ""; + + /** + * 新增 修改 时候的树组件 + * @return + */ + GrapeField grapeField() default @GrapeField(label = "选择上级", type = InputType.TREESELECT); + +} diff --git a/src/main/java/cn/workde/core/annotation/data/ActionType.java b/src/main/java/cn/workde/core/annotation/data/ActionType.java new file mode 100644 index 0000000..7e2781c --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/ActionType.java @@ -0,0 +1,25 @@ +package cn.workde.core.annotation.data; + +public enum ActionType { + + AUTO("auto"), + AJAX("ajax"), + TREE("dialog-tree"), + SELECT("dialog-tree"), + TABLE("dialog-table"), + COMP("comp"), + JUMP("jump"), + FORM("dialog-form"), + BATCH("batch-ids"), + OPEN("open"); + private String value; + + ActionType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + +} diff --git a/src/main/java/cn/workde/core/annotation/data/BoolType.java b/src/main/java/cn/workde/core/annotation/data/BoolType.java new file mode 100644 index 0000000..bf5bea5 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/BoolType.java @@ -0,0 +1,9 @@ +package cn.workde.core.annotation.data; + +public @interface BoolType { + + String trueText() default "是"; + + String falseText() default "否"; + +} diff --git a/src/main/java/cn/workde/core/annotation/data/DataProxy.java b/src/main/java/cn/workde/core/annotation/data/DataProxy.java new file mode 100644 index 0000000..fce497f --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/DataProxy.java @@ -0,0 +1,148 @@ +package cn.workde.core.annotation.data; + +import cn.hutool.json.JSONObject; +import cn.workde.module.grape.model.GrapeFieldModel; +import cn.workde.module.grape.model.GrapeModel; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface DataProxy { + + default Object afterNewDefaultValue(Map bean){ + return bean; + } + + default void afterBuild(GrapeModel grapeModel) { } + + // power.set("add", false) + default void afterBuildPower(JSONObject power) {} + + default void beforeValidate(JSONObject params, String mode) { + } + + /** + * 增加前 + */ + default void beforeAdd(MODEL model) { + } + + /** + * 增加后 + */ + default void afterAdd(MODEL model) { + } + + /** + * 修改前 + */ + default void beforeUpdate(MODEL model) { + } + + /** + * 修改后 + */ + default void afterUpdate(MODEL model) { + } + + /** + * 删除前 + */ + default void beforeDelete(MODEL model) { + } + + /** + * 删除后 + */ + default void afterDelete(MODEL model) { + } + + default IPage> fetchPageData(){ + return null; + } + + /** + * 查询前,返回值为:自定义查询条件 + */ + default void beforeFetch(QueryWrapper queryWrapper) { + + } + + /** + * 查询后结果处理 + */ + default void afterFetch(Collection> list) { + } + + + /** + * 获取表单组件后 + * @param formList + */ + default void afterFormBuild(List formList) { + + } + + /** + * 获取打印组件 + * @param printColumnList + */ + default void afterPrintBuild(List printColumnList) { + + } + + /** + * 导入前 + * @param model + */ + default void beforeImport(MODEL model) { + } + + /** + * 导入后 + * @param modelList + * @param errorMessageList + */ + default void afterImport(List modelList, List errorMessageList) { + + } + + + /** + * 导出前 + * @param index + * @param model + */ + default void beforeExport(Integer index, MODEL model) { + + } + + /** + * 导出后 + * @param index + * @param model + */ + default void afterExport(Integer index, MODEL model) { + + } + + default void beforeFilterDictData(String code, StringBuilder sb) { + + } + + default List> getOptionList(GrapeFieldModel grapeFieldModel){ + return new ArrayList<>(); + } + + default Map afterEditFormData(Map bean){ + return null; + } + + default void afterAddTabData(JSONObject params, MODEL model) {} + + default void afterUpdateTabData(JSONObject params, MODEL model) {} +} diff --git a/src/main/java/cn/workde/core/annotation/data/Dill.java b/src/main/java/cn/workde/core/annotation/data/Dill.java new file mode 100644 index 0000000..01ba0ee --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/Dill.java @@ -0,0 +1,17 @@ +package cn.workde.core.annotation.data; + +public @interface Dill { + + /** + * 显示字段 + * @return + */ + String named() default ""; + + /** + * 查询字段 + * @return + */ + String refId() default ""; + +} diff --git a/src/main/java/cn/workde/core/annotation/data/Empty.java b/src/main/java/cn/workde/core/annotation/data/Empty.java new file mode 100644 index 0000000..a10fc9a --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/Empty.java @@ -0,0 +1,4 @@ +package cn.workde.core.annotation.data; + +public class Empty { +} diff --git a/src/main/java/cn/workde/core/annotation/data/Expression.java b/src/main/java/cn/workde/core/annotation/data/Expression.java new file mode 100644 index 0000000..c3d443a --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/Expression.java @@ -0,0 +1,6 @@ +package cn.workde.core.annotation.data; + +public enum Expression { + + EQ, LIKE, RANGE, IN +} diff --git a/src/main/java/cn/workde/core/annotation/data/InputType.java b/src/main/java/cn/workde/core/annotation/data/InputType.java new file mode 100644 index 0000000..304c394 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/InputType.java @@ -0,0 +1,42 @@ +package cn.workde.core.annotation.data; + + +public enum InputType { + + EMPTY("empty"), + TEXT("text"), + NUMBER("number"), + DATE("date"), + DATETIME("datetime"), + BOOLEAN("bool"), + HIDDEN("hidden"), + TEXTAREA("textarea"), + SELECT("select"), + MAPPING("mapping"), + RADIO("radio"), + RADIOGROUP("radio-group"), + ICONSELECT("icon-select"), + TREESELECT("tree-select"), + TREEDIALOG("tree-dialog"), + EDITOR("editor"), + //单文件 + IMAGE("image"), + //多文件 + IMAGES("images"), + //文件 + FILE("file"), + DILL("dill"), + AUTOCOMPLETE("autocomplete"), + ; + + private String value; + + InputType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + +} diff --git a/src/main/java/cn/workde/core/annotation/data/PageType.java b/src/main/java/cn/workde/core/annotation/data/PageType.java new file mode 100644 index 0000000..7b387fd --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/PageType.java @@ -0,0 +1,18 @@ +package cn.workde.core.annotation.data; + +public enum PageType { + + CRUD("crud"), + + TREEFORM("treeForm"), + ; + private String value; + + PageType(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } +} diff --git a/src/main/java/cn/workde/core/annotation/data/TabTable.java b/src/main/java/cn/workde/core/annotation/data/TabTable.java new file mode 100644 index 0000000..130ebb3 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/TabTable.java @@ -0,0 +1,49 @@ +package cn.workde.core.annotation.data; + +import java.beans.Transient; + +public @interface TabTable { + + /** + * grape class + * @return + */ + Class grapeClass() default Empty.class; + + /** + * 批量选择的Grape class + * @return + */ + @Transient + Class selectClass() default Empty.class; + + // 子表标题 + String label() default ""; + + /** + * 关联字段 + * @return + */ + String join() default ""; + + /** + * 批量选择后 通过接口返回数据 + * @return + */ + String url() default ""; + + boolean add() default true; + + boolean edit() default true; + + boolean detail() default true; + + boolean showSummary() default false; + + String summaryText() default "合计"; + + int[] sums() default {}; + + boolean reconfirm() default false; + +} diff --git a/src/main/java/cn/workde/core/annotation/data/TreeLink.java b/src/main/java/cn/workde/core/annotation/data/TreeLink.java new file mode 100644 index 0000000..45cc2c1 --- /dev/null +++ b/src/main/java/cn/workde/core/annotation/data/TreeLink.java @@ -0,0 +1,24 @@ +package cn.workde.core.annotation.data; + +public @interface TreeLink { + + /** + * grape name + * @return + */ + Class grapeClass() default Empty.class; + + /** + * 关联的字段名 + * @return + */ + String pid() default "pid"; + + /** + * tree 所在宽度,总共24格 + * @return + */ + int span() default 6; + + String nav() default "请选择"; +} diff --git a/src/main/java/cn/workde/core/base/BaseEntity.java b/src/main/java/cn/workde/core/base/BaseEntity.java new file mode 100644 index 0000000..d675d82 --- /dev/null +++ b/src/main/java/cn/workde/core/base/BaseEntity.java @@ -0,0 +1,55 @@ +package cn.workde.core.base; + + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +public class BaseEntity implements Serializable { + + @TableId(type = IdType.ASSIGN_UUID) + @Schema(description = "id") + private String id; + + /** + * 创建时间 + */ + @TableField(value = "created_at", fill = FieldFill.INSERT) + @DateTimeFormat( pattern = "yyyy-MM-dd") + @JsonFormat( pattern = "yyyy-MM-dd", timezone = "GMT+8") + @Schema(description = "创建时间") + private Date createdAt; + + /** + * 创建人 + */ + @TableField(value = "created_id", fill = FieldFill.INSERT) + @Schema(description = "创建者") + private String createdId; + + /** + * 更新时间 + */ + @TableField(value = "updated_at", fill = FieldFill.UPDATE) + @DateTimeFormat( pattern = "yyyy-MM-dd") + @JsonFormat( pattern = "yyyy-MM-dd", timezone = "GMT+8") + @Schema(description = "更新时间") + private Date updatedAt; + + /** + * 更新人 + */ + @TableField(value = "updated_id", fill = FieldFill.UPDATE) + @Schema(description = "更新者") + private String updatedId; + +} diff --git a/src/main/java/cn/workde/core/base/BaseImportResultExcel.java b/src/main/java/cn/workde/core/base/BaseImportResultExcel.java new file mode 100644 index 0000000..f7c9d25 --- /dev/null +++ b/src/main/java/cn/workde/core/base/BaseImportResultExcel.java @@ -0,0 +1,21 @@ +package cn.workde.core.base; + +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import jakarta.validation.groups.Default; +import lombok.Data; + +@Data +public class BaseImportResultExcel { + + @ExcelIgnore + private Boolean isSuccess = true; + + @ExcelIgnore + private Boolean isAdd = true; + + @ExcelProperty(value = "失败原因") + @ColumnWidth(30) + private String failMsg = "这行数据和别的行重复了"; +} diff --git a/src/main/java/cn/workde/core/base/BaseService.java b/src/main/java/cn/workde/core/base/BaseService.java new file mode 100644 index 0000000..c0f4a38 --- /dev/null +++ b/src/main/java/cn/workde/core/base/BaseService.java @@ -0,0 +1,63 @@ +package cn.workde.core.base; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.text.CharSequenceUtil; +import cn.workde.core.data.dto.PageResult; +import cn.workde.core.data.vo.BaseRequest; +import cn.workde.core.exception.ResultException; +import cn.workde.core.factory.PageFactory; +import cn.workde.core.factory.PageResultFactory; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; + +import java.io.Serializable; +import java.util.Date; + +public class BaseService, T extends BaseEntity> extends ServiceImpl { + + @Transactional(rollbackFor = Exception.class) + public void add(T entity) { + this.save(entity); + } + + @Transactional(rollbackFor = Exception.class) + public void edit(T entity) { + this.updateById(entity); + } + + public void delete(String id) { + this.removeById(id); + } + + public T get(Serializable id) { + T result = getById(id); + if(result == null) { + throw new ResultException("数据不存在"); + } + + return result; + } + + public PageResult findPage(BaseRequest baseRequest) { + PageResult pageResult = PageResultFactory.createPageResult(this.page(PageFactory.defaultPage(), this.createWrapper(baseRequest))); + return pageResult; + } + + public LambdaQueryWrapper createWrapper(BaseRequest baseRequest) { + return new LambdaQueryWrapper<>(); + } + + @Override + public boolean saveOrUpdate(T entity) { + if (CharSequenceUtil.isBlank(entity.getId())) { + entity.setCreatedAt(new Date()); + return this.save(entity); + } else { + entity.setUpdatedAt(new Date()); + return this.updateById(entity); + } + } + +} diff --git a/src/main/java/cn/workde/core/base/BaseTreeService.java b/src/main/java/cn/workde/core/base/BaseTreeService.java new file mode 100644 index 0000000..775d0c5 --- /dev/null +++ b/src/main/java/cn/workde/core/base/BaseTreeService.java @@ -0,0 +1,49 @@ +package cn.workde.core.base; + +import cn.workde.core.util.TreeSorterUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import java.util.List; + +public class BaseTreeService , T extends TreeEntity> extends BaseService { + + @Override + public boolean saveOrUpdate(T entity) { + setTreePidNames(entity); + return super.saveOrUpdate(entity); + } + @Override + public boolean save(T entity) { + setTreePidNames(entity); + return super.save(entity); + } + + @Override + public boolean updateById(T entity) { + setTreePidNames(entity); + return super.updateById(entity); + } + + public void setTreePidNames(T entity) { + if(entity.getPid().equals("0")) { + entity.setTreeNames(entity.getNamed()); + entity.setTreeIds(entity.getPid()); + }else { + T parent = baseMapper.selectOne(new QueryWrapper().eq("id", entity.getPid())); + if(parent != null) { + entity.setTreeNames(parent.getTreeNames() + "/" + entity.getNamed()); + entity.setTreeIds(parent.getTreeIds() + "," + entity.getPid()); + } + } + } + + public List treeList() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.orderByAsc("sort_no"); + List treeList = list(queryWrapper); + TreeSorterUtil.tree(treeList); + return treeList; + } + +} diff --git a/src/main/java/cn/workde/core/base/BaseWrapper.java b/src/main/java/cn/workde/core/base/BaseWrapper.java new file mode 100644 index 0000000..9c647cf --- /dev/null +++ b/src/main/java/cn/workde/core/base/BaseWrapper.java @@ -0,0 +1,23 @@ +package cn.workde.core.base; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; + +import java.util.List; + +public interface BaseWrapper { + + public D toDto(T t); + + public List toDto(List list); + + default Page toDto(IPage t) { + List list = t.getRecords(); + List dtoList = toDto(list); + Page page = new Page<>(); + BeanUtil.copyProperties(t, page); + page.setRecords(dtoList); + return page; + } +} diff --git a/src/main/java/cn/workde/core/base/DropDownSetField.java b/src/main/java/cn/workde/core/base/DropDownSetField.java new file mode 100644 index 0000000..e26374c --- /dev/null +++ b/src/main/java/cn/workde/core/base/DropDownSetField.java @@ -0,0 +1,26 @@ +package cn.workde.core.base; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author msh + * @version 1.0 + * @date 2023/8/26 17:19 + */ + +@Documented +// 作用在字段上 +@Target(ElementType.FIELD) +// 运行时有效 +@Retention(RetentionPolicy.RUNTIME) +public @interface DropDownSetField { + // 固定下拉内容 + String[] source() default {}; + + // 动态下拉内容 + Class[] sourceClass() default {}; +} diff --git a/src/main/java/cn/workde/core/base/TreeEntity.java b/src/main/java/cn/workde/core/base/TreeEntity.java new file mode 100644 index 0000000..257cb6b --- /dev/null +++ b/src/main/java/cn/workde/core/base/TreeEntity.java @@ -0,0 +1,47 @@ +package cn.workde.core.base; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public abstract class TreeEntity extends BaseEntity { + + @TableId(type = IdType.ASSIGN_UUID) + private String id; + + private String pid; + + private Integer sortNo; + + private String treeNames; + + private String treeIds; + + @TableField(exist = false) + private Integer treeLeaf; + + @TableField(exist = false) + private Integer treeLevel; + + @TableField(exist = false) + private String parentName; + + @TableField(exist = false) + private List children; + + /** + * 返回树列表显示的值 + * @return + */ + public abstract String getNamed(); + + public void addChild(T child) { + if(children == null) this.children = new ArrayList(); + this.children.add(child); + } +} diff --git a/src/main/java/cn/workde/core/cache/ConfigCache.java b/src/main/java/cn/workde/core/cache/ConfigCache.java new file mode 100644 index 0000000..3ce75f8 --- /dev/null +++ b/src/main/java/cn/workde/core/cache/ConfigCache.java @@ -0,0 +1,107 @@ +package cn.workde.core.cache; + +import cn.hutool.core.lang.Dict; +import cn.hutool.crypto.symmetric.SymmetricAlgorithm; +import cn.hutool.crypto.symmetric.SymmetricCrypto; +import cn.workde.core.constant.CacheConst; +import cn.workde.core.constant.GrapeConst; +import cn.workde.core.util.CacheUtil; +import cn.workde.core.util.SpringUtil; +import cn.workde.module.upms.entity.GrapeConfig; +import cn.workde.module.upms.service.GrapeConfigService; + +import java.util.List; + +public class ConfigCache { + + public static final String CONFIG_KEY = "dict"; + + /** + * 密码是否加密 + */ + public static final String USER_PASSWORD_SALT = "sys.user.salt"; + + /** + * 账号初始化密码 + */ + public static final String USER_INIT_PASSWORD = "sys.user.initPassword"; + + public static final String LOGIN_CAPTCHA_CODE = "sys.login.captchaCode"; + + /** + * 用户TOKEN密钥 + */ + public static final String USER_TOKEN_SECRET = "sys.user.tokenSecret"; + + /** + * 用户TOKEN有效天数 + */ + public static final String USER_TOKEN_DAY = "sys.user.tokenDay"; + + /** + * 用户登录验证码长度 + */ + public static final String LOGIN_CAPTCHA_CODE_LENGTH = "sys.login.captchaCodeLength"; + + /** + * 用户密码输入错误次数 + */ + public static final String LOGIN_FAILED_TIMES = "sys.login.failedNumAfterLockAccount"; + + /** + * 用户锁定时间 + */ + public static final String LOGIN_FAILED_LOCK_MINUTE = "sys.login.failedNumAfterLockMinute"; + + public static Dict getConfigDict() { + Dict configDict = CacheUtil.get(CacheConst.UPMS_CONFIG_CACHE, CONFIG_KEY, ()->{ + GrapeConfigService configService = SpringUtil.getBean(GrapeConfigService.class); + List configList = configService.list(); + Dict dict = Dict.create(); + configList.stream().forEach(config -> { + dict.set(config.getParamKey(), config.getParamValue()); + }); + return dict; + }); + + return configDict; + } + + public static String getStr(String key) { + Dict dict = getConfigDict(); + return dict.getStr(key); + } + + public static String getStr(String key, String defaultValue) { + Dict dict = getConfigDict(); + String value = dict.getStr(key); + return value == null ? defaultValue : value; + } + + public static Integer getInt(String key) { + Dict dict = getConfigDict(); + return dict.getInt(key); + } + + public static Integer getInt(String key, Integer defaultValue) { + Dict dict = getConfigDict(); + Integer value = dict.getInt(key); + return value == null ? defaultValue : value; + } + + public static String getDecryptStr(String key) { + String dictStr = getStr(key); + SymmetricCrypto rc2 = new SymmetricCrypto(SymmetricAlgorithm.RC2, GrapeConst.RC2_KEY.getBytes()); + try { + return rc2.decryptStr(dictStr); + }catch (Exception e){ + return null; + } + } + + public static String getDecryptStr(String key, String defaultValue) { + String value = getStr(key); + String decryptStr = getDecryptStr(value); + return decryptStr == null ? defaultValue : value; + } +} diff --git a/src/main/java/cn/workde/core/config/GrapeAutoConfiguration.java b/src/main/java/cn/workde/core/config/GrapeAutoConfiguration.java new file mode 100644 index 0000000..b2d7f34 --- /dev/null +++ b/src/main/java/cn/workde/core/config/GrapeAutoConfiguration.java @@ -0,0 +1,99 @@ +package cn.workde.core.config; + +import cn.workde.core.db.handler.CustomMetaObjectHandler; +import cn.workde.core.db.interceptor.FieldEncryptInterceptor; +import cn.workde.core.db.interceptor.FieldResultInterceptor; +import cn.workde.core.db.interceptor.MybatisPlusPrintSqlInterceptor; +import cn.workde.core.db.interceptor.SqlLogInterceptor; +import cn.workde.module.grape.aop.ApiLogAspect; +import cn.workde.module.grape.event.ApiLogListener; +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer; +import com.baomidou.mybatisplus.core.MybatisConfiguration; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.baomidou.mybatisplus.extension.MybatisMapWrapperFactory; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GrapeAutoConfiguration { + +// @Bean +// public MybatisPlusPrintSqlInterceptor mybatisSQLInterceptor() { +// return new MybatisPlusPrintSqlInterceptor(false); +// } + + + @Bean + public SqlLogInterceptor sqlLogInterceptor() { + return new SqlLogInterceptor(); + } + + /** + * 解决map 返回 驼峰字段 + * @return + */ + @Bean + public ConfigurationCustomizer mybatisConfigurationCustomizer() { + return new ConfigurationCustomizer() { + @Override + public void customize(MybatisConfiguration configuration) { + configuration.setObjectWrapperFactory(new MybatisMapWrapperFactory()); + } + }; + } + + @Bean + public MetaObjectHandler metaObjectHandler() { + return new CustomMetaObjectHandler(); + } + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); + return interceptor; + } + + @Bean + public ApiLogAspect apiLogAspect() { + return new ApiLogAspect(); + } + + @Bean + public ApiLogListener apiLogListener(){ + return new ApiLogListener(); + } + + + + @Value("${redis:address}") + private String address; + @Value("${redis:password}") + private String password; + + @Bean + public RedissonClient redissonClient(){ + Config config = new Config(); + config.useSingleServer().setAddress(address).setPassword(password); + return Redisson.create(); + } + + + @Bean + public FieldEncryptInterceptor fieldEncryptInterceptor() { + return new FieldEncryptInterceptor(); + } + + @Bean + public FieldResultInterceptor resultInterceptor() { + return new FieldResultInterceptor(); + } + +} diff --git a/src/main/java/cn/workde/core/config/GrapeMvcConfigurer.java b/src/main/java/cn/workde/core/config/GrapeMvcConfigurer.java new file mode 100644 index 0000000..798392b --- /dev/null +++ b/src/main/java/cn/workde/core/config/GrapeMvcConfigurer.java @@ -0,0 +1,103 @@ +package cn.workde.core.config; + + +import cn.workde.core.constant.GrapeConst; +import cn.workde.core.databind.SensitiveFieldProcessModule; +import cn.workde.core.interceptor.GlobalInterceptor; +import cn.workde.module.upms.interceptor.UpmsInterceptor; + + +import com.dahuatech.icc.oauth.http.DefaultClient; +import com.dahuatech.icc.oauth.http.IClient; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.*; + +@Configuration +public class GrapeMvcConfigurer implements WebMvcConfigurer { + + private static final String ORIGINS[] = new String[]{"GET", "POST", "PUT", "DELETE"}; + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new UpmsInterceptor()) + .addPathPatterns(GrapeConst.API + "/**") + .excludePathPatterns(GrapeConst.API + "/auth/**", GrapeConst.API + "/statistic/**", GrapeConst.UPMS + "/admin/edit_password", GrapeConst.UPMS + "/admin/init_password", + GrapeConst.API + "/data/**", GrapeConst.UPMS + "/system/global", GrapeConst.API + "/field/**", "/t/**"); + registry.addInterceptor(new GlobalInterceptor()).addPathPatterns("/**"); +// registry.addInterceptor(new AppUserInterceptor()) +// .addPathPatterns(AppConst.APP + "/**") +// .excludePathPatterns(AppConst.APP + "/auth/login", AppConst.APP + "/auth/captcha", AppConst.APP + "/file/**", +// AppConst.APP + "/event_player/page",AppConst.APP + "/schedule_player/page", +// AppConst.APP + "/schedule_grade/submit",AppConst.APP+"/**/public/**",AppConst.APP+"/schedule/**"); + } + + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/deploy/sa-res/**").addResourceLocations("classpath:/html/sa-res/"); + registry.addResourceHandler("/deploy/**").addResourceLocations("classpath:/html/deploy/"); + registry.addResourceHandler("/cpanel/**").addResourceLocations("classpath:/html/dist/"); + registry.addResourceHandler("/upload/**").addResourceLocations("file:" + System.getProperty("user.dir") + "/upload/"); + } + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/cpanel/").setViewName("dist/index.html"); + registry.addRedirectViewController("/cpanel", "/cpanel/"); + + registry.addRedirectViewController("/", "/deploy/"); + registry.addRedirectViewController("/deploy", "/deploy/"); + registry.addViewController("/deploy/").setViewName("deploy/index.html"); + } + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/**") + .allowedOrigins("*") + .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") + //针对header单独设置,不然无法获取header中的请求信息,前端也无法拿到响应中的 header信息,OPTIONS请求也会经过拦截器,在进行登录拦截时候要注意特殊处理 + .allowedHeaders("*") + .exposedHeaders("access-control-allow-headers", + "access-control-allow-methods", + "access-control-allow-origin", + "access-control-max-age", + "X-Frame-Options") + .maxAge(3600) + .allowCredentials(false); + + /*registry.addMapping("/**") + .allowedOrigins("*") + .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE") + //针对header单独设置,不然无法获取header中的请求信息,前端也无法拿到响应中的header信息,OPTIONS请求也会经过拦截器,在进行登录拦截时候要注意特殊处理 + .allowedHeaders("*") + .exposedHeaders("access-control-allow-headers", + "access-control-allow-methods", + "access-control-allow-origin", + "access-control-max-age", + "X-Frame-Options") + .maxAge(3600);*/ + } + + @Bean + public ObjectMapper objectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); +// // 统一返回数据的输出风格 +// objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategy.SnakeCaseStrategy()); +// objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); +// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// objectMapper.setDateFormat(sdf); +// objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8")); +// +// SimpleModule simpleModule = new SimpleModule(); +// simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance); +// simpleModule.addSerializer(Long.class, ToStringSerializer.instance); +// simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); +// objectMapper.registerModule(simpleModule); + + objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new SensitiveFieldProcessModule())); +// objectMapper.setSerializerFactory(objectMapper.getSerializerFactory().withSerializerModifier(new MediaFieldProcessModule())); + return objectMapper; + } + +} diff --git a/src/main/java/cn/workde/core/config/UndertowWebServerCustomizerConfig.java b/src/main/java/cn/workde/core/config/UndertowWebServerCustomizerConfig.java new file mode 100644 index 0000000..f6475e6 --- /dev/null +++ b/src/main/java/cn/workde/core/config/UndertowWebServerCustomizerConfig.java @@ -0,0 +1,32 @@ +package cn.workde.core.config; + +import io.undertow.server.HandlerWrapper; +import io.undertow.server.HttpHandler; +import io.undertow.server.handlers.DisallowedMethodsHandler; +import io.undertow.util.HttpString; +import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.context.annotation.Configuration; + +/** + * @author liuhaoze + * @date 2023/7/17 11:05 + */ +@Configuration +public class UndertowWebServerCustomizerConfig implements WebServerFactoryCustomizer { + + @Override + public void customize(UndertowServletWebServerFactory factory) { + factory.addDeploymentInfoCustomizers(deploymentInfo -> { + deploymentInfo.addInitialHandlerChainWrapper(new HandlerWrapper() { + @Override + public HttpHandler wrap(HttpHandler handler) { + HttpString[] disallowedHttpMethods = {HttpString.tryFromString("TRACE"), + HttpString.tryFromString("TRACK")}; + return new DisallowedMethodsHandler(handler, disallowedHttpMethods); + } + }); + }); + } + +} diff --git a/src/main/java/cn/workde/core/constant/AppConst.java b/src/main/java/cn/workde/core/constant/AppConst.java new file mode 100644 index 0000000..e95f366 --- /dev/null +++ b/src/main/java/cn/workde/core/constant/AppConst.java @@ -0,0 +1,10 @@ +package cn.workde.core.constant; + +/** + * @author liuhaoze + * @date 2023/7/17 10:36 + */ +public interface AppConst { + + String APP = "/app"; +} diff --git a/src/main/java/cn/workde/core/constant/CacheConst.java b/src/main/java/cn/workde/core/constant/CacheConst.java new file mode 100644 index 0000000..d8218b3 --- /dev/null +++ b/src/main/java/cn/workde/core/constant/CacheConst.java @@ -0,0 +1,8 @@ +package cn.workde.core.constant; + +public interface CacheConst { + + String UPMS_CONFIG_CACHE = "upms_config"; + + String LOGIN_ERROR_CACHE = "login_error"; +} diff --git a/src/main/java/cn/workde/core/constant/ConfigConstant.java b/src/main/java/cn/workde/core/constant/ConfigConstant.java new file mode 100644 index 0000000..e1f9ced --- /dev/null +++ b/src/main/java/cn/workde/core/constant/ConfigConstant.java @@ -0,0 +1,39 @@ +package cn.workde.core.constant; + +public interface ConfigConstant { + String LOGIN_CAPTCHA_LENGTH = "login_captcha_length"; + String LOGIN_CAPTCHA_LINE_COUNT = "login_captcha_line_count"; + String LOGIN_CAPTCHA_EXPIRY_DATE = "login_captcha_expiry_date"; + + + String SMS_LENGTH = "sms_length"; + String SMS_WAITING_TIME = "sms_waiting_time"; + String SMS_EFFECTIVE_TIME = "sms_effective_time"; + String SMS_CODE = "sms_code"; + + String LOGIN_ERROR_COUNT_ADMIN = "login:error:count:admin"; + String LOGIN_ERROR_TIME_ADMIN = "login:error:time:admin"; + String LOGIN_ERROR_LOCK_TIME_ADMIN = "login:error:lock:time:admin"; + String LOGIN_BLACK_LIST_MESSAGE_ADMIN = "login:black:list:message:admin"; + + String LOGIN_ERROR_COUNT_API = "login:error:count:api"; + String LOGIN_ERROR_TIME_API = "login:error:time:api"; + String LOGIN_ERROR_LOCK_TIME_API = "login:error:lock:time:api"; + String LOGIN_BLACK_LIST_MESSAGE_API = "login:black:list:message:api"; + + String ZZD_ENVIRONMENT = "zzd_environment"; + String ZZD_ACCESSKEY = "zzd_accessKey"; + String ZZD_SECRETKEY = "zzd_secretKey"; + + String ZYDD_ACCESSKEY = "zydd_accessKey"; + String ZYDD_SECRETKEY = "zydd_secretKey"; + + String ZYDD_QRCODE_ACCESSKEY = "zzd_qrcode_accessKey"; + String ZYDD_QRCODE_SECRETKEY = "zzd_qrcode_secretKey"; + String ZYDD_QRCODE_CLIENTID = "zzd_qrcode_client_id"; + + + + String TYPE_APP = "app"; + +} diff --git a/src/main/java/cn/workde/core/constant/ExcelConst.java b/src/main/java/cn/workde/core/constant/ExcelConst.java new file mode 100644 index 0000000..9959c94 --- /dev/null +++ b/src/main/java/cn/workde/core/constant/ExcelConst.java @@ -0,0 +1,12 @@ +package cn.workde.core.constant; + +public interface ExcelConst { + + String IMPORT = "import"; + + String EXPORT = "export"; + + String VALID_INPUT = "input"; + + String VALID_DICT = "dict"; +} diff --git a/src/main/java/cn/workde/core/constant/FromTypeConst.java b/src/main/java/cn/workde/core/constant/FromTypeConst.java new file mode 100644 index 0000000..529ee38 --- /dev/null +++ b/src/main/java/cn/workde/core/constant/FromTypeConst.java @@ -0,0 +1,34 @@ +package cn.workde.core.constant; + +/** + * @author msh + * @version 1.0 + * @date 2023/9/13 15:44 + */ +public interface FromTypeConst { + /** + * 导出数据类型-企业信息表 + */ + String EXPORT_TYPE_COMPANY = "company"; + /** + * 导出数据类型-企业荣誉表 + */ + String EXPORT_TYPE_HONOUR = "honour"; + /** + * 导出数据类型-企业培育表 + */ + String EXPORT_TYPE_CULTIVATE = "cultivate"; + /** + * 导出数据类型-企业经纬度表 + */ + String EXPORT_TYPE_LONG_AND_LAT = "longAndLat"; + /** + * 导出数据类型-企业成效表 + */ + String EXPORT_TYPE_OUTPUT = "output"; + /** + * 导出数据类型-企业服务表 + */ + String EXPORT_TYPE_SERVER = "server"; + +} diff --git a/src/main/java/cn/workde/core/constant/GrapeConst.java b/src/main/java/cn/workde/core/constant/GrapeConst.java new file mode 100644 index 0000000..7dcbe3a --- /dev/null +++ b/src/main/java/cn/workde/core/constant/GrapeConst.java @@ -0,0 +1,39 @@ +package cn.workde.core.constant; + +public interface GrapeConst { + + String API = "/api"; + + String APP = "/app"; + + String API_V1 = "/api/v1"; + + String BUILD = API + "/build"; + + // 数据 + String DATA = API + "/data"; + + // 数据 + String MODIFY = API + "/modify"; + + String UPMS = API + "/upms"; + + String FORMILY = API + "/formily"; + + String FORMILY_BUILD = FORMILY + "/build"; + + String FORMILY_DATA = FORMILY + "/data"; + + String FORMILY_MODIFY = FORMILY + "/modify"; + + String RC2_KEY = "kj7967hdiv9sz0jbbps96tw8ikba44z2"; + + /** + * 重要说明:该值为项目生成后的缺省密钥 + * 在实际的应用中,一定要为不同的项目或服务,自行生成公钥和私钥,并将 PRIVATE_KEY 的引用改为服务的配置项。 + * 密钥的生成方式,xyz.grapehub.core.util.RsaUtil类的main函数动态生成。 + */ + String APP_PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJwq/96CJLuyjMrcctY0lNrlTIvUikj0bXjmTrY6srwzGA9HiC6saPnwOryrwTqAy/QTCnKW/EeepyJl61r4wlITU0sPbCY7ugPbD2g3cowHPpofb4RJOQfV+EPlLOnDrrYbCP8Z6YhD6P6nltfRxL0kyP/NGX7CUaiMiXZshTMVAgMBAAECgYA6PO7ek7oPJS7MGBnbOBCq8QfyvXg0bLLGe1yvKISvGn7Gc+6dOT6MtsGwynxszMtCYjdrNFMwgkHh2hBDBLGyRM/C1orRpcpCK4CdJNI4GAF/jtIJ1lnrHp11Tt7ng0wGSC00i/oIBIFVRbRhk04SWtLb0C3KaiL9CpBFlFCkAQJBAMm01Opv5V18EZkA7G0Jn0axqNDqKb0OiiXPzzYJ1q3H+VaKYBulQ2V2vlwaO+VJ2any0zbtJrNN+ChiJXO3xzUCQQDGNDXj0NgzAPFGouGhhgjieMCIk1dGfcUT3tdEljqH6XxzgpgGk9WaDcKGi94gcBpw+k4S2K/2Z8BWm0o4VthhAkBElm30DfqTcFXXjj3W0ffMJSs/ZvCsbd5B/0j5mhza2O4LJGCL5gVl4hvW28DUNemC5aQ2wCtxuyiQKteLYsmlAkA9MBES635TAI97xvzw6HgFslF92D6xPFKC9+BtBBO9sY8B+ecE4M6oaGcNMlC4ouMGzb8cgliQMSdnlTkse2MBAkBpy+wkyUvJzLtBq2IPM5vlw9Oxn/6yP2YyBG5AP1dHFDwz3q/pkBcp/ZSmH2FgjXOvjFdSsNdRnOtNiLpFO19l"; + String API_PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALeBXlI5ITR1D/kCtvu5wNqe45uJW12YhBvnYxkebZx3/TIvx6qeJGHGxLTL50N0UxUrPqzHCrdg6y52C/ofqM6BSiRuLvxcRKiRbROVlVqRoG3fu7ubChHhRkSqJqWjst9fYyYByB9jcnpzAG5KwV8KPFZYOiT4R8xhTr14Mji/AgMBAAECgYAY9WCFyxK9bBqTDLp55wbYSqS8bTnfCLUXMn55ASQkFEcnbKDkj4PKmgVRGIFI3Gkcck2g+aV3Ju3LMO+/bPpBeJks/Iyf5rvtKiwTte8zQ0CTWiBT7mhbqEwUyFtzGpp/57BdwgIy+x6WD3KVOTV1oeVVZUG7ysupcOaCAMj1yQJBAPZ6AIlLyW8rjx4eyFR7ZW4mEI7GgH+gwlAqcdX2Il71Fe6wNwerUxoWQQZAcpY4DQvlJ0pLhDOYtdbdGKNDFtsCQQC+mH4tp+YA/Jy1EUvRnPZ0ztTnsu8ctHz5MAy3NseVCNigrqQy2tGqzOC/CIKx5z0zHBHeGaO2FMdQprsNdzDtAkB346Q7JFgY8TEuT37WSSdvSqinKjr62bFq2RqCHrVdRw2iCqjZ3CYR/F0os1SJaT4/WPmhk9X8Wv2oQ+dmEo4dAkEArmTd32ynefOqd8sxssSKherSyIbjX0KOr3uVxvaqu+VyQeRKffXWrw/z/RgObjYFu4RNnQmc0HhGv7cvpGyRKQJAN1i4XmZ7lCFzNfttESb8/HszAjUhuRtXN2b5PFQk3qHVY5KgU3BruRMWjuLntJ4wgtE530XlypMrzOG2/WGmXQ=="; + String APP_PASSWORD = "ydool@2025"; +} diff --git a/src/main/java/cn/workde/core/constant/RedisConstant.java b/src/main/java/cn/workde/core/constant/RedisConstant.java new file mode 100644 index 0000000..4fa448e --- /dev/null +++ b/src/main/java/cn/workde/core/constant/RedisConstant.java @@ -0,0 +1,108 @@ +package cn.workde.core.constant; + +public interface RedisConstant { + + String CONFIG = "t_sys_config"; + + String TYPE_CONFIG = "t_sys_type_config"; + + String DICT = "t_sys_dict_data"; + + String CAPTCHA = "captcha"; + + String SMS = "sms"; + + String PHONE = "phone"; + + String BLACK_LIST_ADMIN = "black:list:admin:club:nfc"; + + String ERROR_COUNT_ADMIN = "error:count:admin:club:nfc"; + + String BLACK_LIST_API = "black:list:aoi"; + + String ERROR_COUNT_API = "error:count:api"; + + String LOGIN_ADMIN = "login_admin"; + + String ADMIN_AUTH_TICKET = "admin_auth_ticket_"; + + String HOME_PAGE = "home_page"; + + String STREET_LIST = "street_list"; + + String T_SYS_STREET = "t_sys_street"; + + String T_SYS_STREET_VILLAGE = "t_sys_street_village"; + + String T_SYS_VILLAGE = "t_sys_village"; + + String THESIS_LIST = "thesis_list"; + + String T_SYS_ADDRESS = "t_sys_address"; + + String ADDRESS_LIST = "address_list"; + String ADDRESS_LIST_TYPE = "address_list_type"; + String IDENTITY_VILLAGE_ADDRESS = "identity_village_address"; + String IDENTITY_TOWNSHIP_STREET_ADDRESS = "identity_township_street_address"; + String ADMIN_ADDRESS_LIST_TYPE = "admin_address_list_type"; + + String POINTSRANKING = "pointsRanking_"; + + String DEPTPOINTSRANKING = "deptPointsRanking_"; + + /** + * 默认缓存时间 + * 一小时 + */ + Integer DEFAULT_CACHE_TIME_SECOND = 60 * 60; + + /** + * 文章缓存 y:article:detail:articleId + * ARTICLE_MAP_OBJ 文章对象 + * ARTICLE_MAP_VIEWS 浏览数 触发文章详情接口 + * ARTICLE_MAP_LIKES 点赞数 触发点赞与取消点赞 + * ARTICLE_MAP_COMMENTS 评论数 评论总数更新到文章时ARTICLE_MAP重新设入 + */ + String ARTICLE_MAP = "y:article:detail:{}"; + + /** + * 龙游号缓存 y:lyh:map:type-addressId + * LYH_MAP:后台修改龙游号就删 + * LYH_MAP_OBJ:龙游号对象 + */ + String LYH_MAP = "y:lyh:map:{}-{}"; + + /** + * 我的缓存 y:user:map:userId + * USER_MAP_ATTENTION_IDS 我的关注ids + * USER_MAP_LIKE_IDS 我的点赞ids + * USER_MAP_COLLECT_IDS 我的收藏ids + */ + String USER_MAP = "y:user:map:{}"; + + /** + * 板块缓存 y:plate:plateId + * PLATE_MAP_IDS pageNum:pageSize + */ + String PLATE_MAP = "y:plate:map:{}"; + + /** + * 已删除的文章 + */ + String ARTICLE_DEL_LIST = "article:del"; + + /** + * 发送验证码过期时间列表 + */ + String LOGIN_AUTH_CODE_LIST_ADMIN = "login:auth:code:list:admin:club:nfc"; + + /** + * 验证码 + */ + String CAPTCHA_CODE_API = "captcha:code:api"; + /** + * ip请求验证码接口次数 + */ + String CAPTCHA_CODE_COUNT_API = "captcha:code:count:api"; + +} diff --git a/src/main/java/cn/workde/core/constant/ZZDConstant.java b/src/main/java/cn/workde/core/constant/ZZDConstant.java new file mode 100644 index 0000000..a8c9461 --- /dev/null +++ b/src/main/java/cn/workde/core/constant/ZZDConstant.java @@ -0,0 +1,7 @@ +package cn.workde.core.constant; + + +public interface ZZDConstant { + String DEV = "openplatform.dg-work.cn"; + String PRO = "openplatform-pro.ding.zj.gov.cn"; +} diff --git a/src/main/java/cn/workde/core/context/RequestGroupContext.java b/src/main/java/cn/workde/core/context/RequestGroupContext.java new file mode 100644 index 0000000..297cde0 --- /dev/null +++ b/src/main/java/cn/workde/core/context/RequestGroupContext.java @@ -0,0 +1,27 @@ +package cn.workde.core.context; + +public class RequestGroupContext { + + private static final ThreadLocal> GROUP_CLASS_HOLDER = new ThreadLocal<>(); + + /** + * 设置临时的校验分组 + */ + public static void set(Class groupValue) { + GROUP_CLASS_HOLDER.set(groupValue); + } + + /** + * 获取临时校验分组 + */ + public static Class get() { + return GROUP_CLASS_HOLDER.get(); + } + + /** + * 清除临时缓存的校验分组 + */ + public static void clear() { + GROUP_CLASS_HOLDER.remove(); + } +} diff --git a/src/main/java/cn/workde/core/context/RequestParamContext.java b/src/main/java/cn/workde/core/context/RequestParamContext.java new file mode 100644 index 0000000..e43d155 --- /dev/null +++ b/src/main/java/cn/workde/core/context/RequestParamContext.java @@ -0,0 +1,45 @@ +package cn.workde.core.context; + +import cn.hutool.core.lang.Dict; + +public class RequestParamContext { + + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + /** + * 保存请求参数 + */ + public static void set(Dict requestParam) { + CONTEXT_HOLDER.set(requestParam); + } + + /** + * 保存请求参数 + */ + public static void setObject(Object requestParam) { + + if (requestParam == null) { + return; + } + + if (requestParam instanceof Dict) { + CONTEXT_HOLDER.set((Dict) requestParam); + } else { + CONTEXT_HOLDER.set(Dict.parse(requestParam)); + } + } + + /** + * 获取请求参数 + */ + public static Dict get() { + return CONTEXT_HOLDER.get(); + } + + /** + * 清除请求参数 + */ + public static void clear() { + CONTEXT_HOLDER.remove(); + } +} diff --git a/src/main/java/cn/workde/core/data/dto/IResultCode.java b/src/main/java/cn/workde/core/data/dto/IResultCode.java new file mode 100644 index 0000000..d2122df --- /dev/null +++ b/src/main/java/cn/workde/core/data/dto/IResultCode.java @@ -0,0 +1,24 @@ +package cn.workde.core.data.dto; + +import java.io.Serializable; + +/** + * 业务代码接口 + */ +public interface IResultCode extends Serializable { + + /** + * 获取消息 + * + * @return + */ + String getMessage(); + + /** + * 获取状态码 + * + * @return + */ + int getCode(); + +} diff --git a/src/main/java/cn/workde/core/data/dto/NameCount.java b/src/main/java/cn/workde/core/data/dto/NameCount.java new file mode 100644 index 0000000..0ebbbf9 --- /dev/null +++ b/src/main/java/cn/workde/core/data/dto/NameCount.java @@ -0,0 +1,28 @@ +package cn.workde.core.data.dto; + +import lombok.Data; + +/** + * @author liuhaoze + * @date 2021/2/3 11:03 + */ +@Data +public class NameCount { + + private String name; + + private Object value; + + public NameCount() { + } + + public NameCount(String value) { + this.value = value; + } + + public NameCount(String name, Object value) { + this.name = name; + this.value = value; + } + +} diff --git a/src/main/java/cn/workde/core/data/dto/OptionResult.java b/src/main/java/cn/workde/core/data/dto/OptionResult.java new file mode 100644 index 0000000..6423fd7 --- /dev/null +++ b/src/main/java/cn/workde/core/data/dto/OptionResult.java @@ -0,0 +1,23 @@ +package cn.workde.core.data.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class OptionResult { + + private String label; + + private String value; + + private String key; + + private List children; + + public OptionResult(String label, String value) { + this.label = label; + this.value = value; + this.key = value; + } +} diff --git a/src/main/java/cn/workde/core/data/dto/PageResult.java b/src/main/java/cn/workde/core/data/dto/PageResult.java new file mode 100644 index 0000000..30e5a8e --- /dev/null +++ b/src/main/java/cn/workde/core/data/dto/PageResult.java @@ -0,0 +1,36 @@ +package cn.workde.core.data.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class PageResult implements Serializable { + + /** + * 第几页 + */ + private Integer pageNo = 1; + + /** + * 每页条数 + */ + private Integer pageSize = 20; + + /** + * 总页数 + */ + private Integer totalPage = 0; + + /** + * 总记录数 + */ + private Integer count = 0; + + /** + * 结果集 + */ + private List rows; + +} diff --git a/src/main/java/cn/workde/core/data/dto/Result.java b/src/main/java/cn/workde/core/data/dto/Result.java new file mode 100644 index 0000000..b0a1112 --- /dev/null +++ b/src/main/java/cn/workde/core/data/dto/Result.java @@ -0,0 +1,279 @@ +package cn.workde.core.data.dto; + +import cn.hutool.core.util.ObjectUtil; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.servlet.http.HttpServletResponse; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; +import org.springframework.lang.Nullable; + +import java.io.Serializable; +import java.util.List; +import java.util.Optional; + +@Getter +@Setter +@ToString +@NoArgsConstructor +public class Result implements Serializable { + + /** + * 默认成功消息 + */ + public static final String DEFAULT_SUCCESS_MESSAGE = "操作成功"; + /** + * 默认失败消息 + */ + public static final String DEFAULT_FAILURE_MESSAGE = "操作失败"; + + /** + * 默认为空消息 + */ + public static final String DEFAULT_NULL_MESSAGE = "暂无承载数据"; + + /** + * 默认未授权消息 + */ + public static final String DEFAULT_UNAUTHORIZED_MESSAGE = "签名认证失败"; + @Schema(description = "响应码") + private int code; + @Schema(description = "是否成功") + private boolean success; + @Schema(description = "数据") + private T data; + + private Integer count; + @Schema(description = "描述") + private String message; + +// private String captcha; + + private String[] checked; + + private String date; + + @Schema(description = "数据时间") + private String dataTime; + + @Schema(description = "轮数") + private String rounds; + + public Result(IResultCode resultCode) { + this(resultCode, null, resultCode.getMessage()); + } + + public Result(IResultCode resultCode, String message) { + this(resultCode, null, message); + } + + public Result(IResultCode resultCode, T data) { + this(resultCode, data, resultCode.getMessage()); + } + + public Result(IResultCode resultCode, T data, String message) { + this(resultCode.getCode(), data, message); + } + + private Result(int code, T data, String message) { + this.code = code; + this.data = data; + this.message = message; + this.success = ResultCode.SUCCESS.code == code; + } + + private Result(int code, int count, T data, String message) { + this(code, data, message); + this.count = count; + } + + + /** + * 判断返回是否为成功 + * + * @param result Result + * @return 是否成功 + */ + public static boolean isSuccess(@Nullable Result result) { + return Optional.ofNullable(result) + .map(x -> ObjectUtil.equals(ResultCode.SUCCESS.code, x.code)) + .orElse(Boolean.FALSE); + } + + /** + * 判断返回是否为成功 + * + * @param result Result + * @return 是否成功 + */ + public static boolean isNotSuccess(@Nullable Result result) { + return !Result.isSuccess(result); + } + + /** + * 返回Result + * + * @param data 数据 + * @param T 泛型标记 + * @return Result + */ + public static Result data(T data) { + return data(data, DEFAULT_SUCCESS_MESSAGE); + } + + /** + * 返回Result + * + * @param data 数据 + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result data(T data, String message) { + return data(HttpServletResponse.SC_OK, data, message); + } + + /** + * 返回Result + * + * @param data 数据 + * @param date 时间 + * @param T 泛型标记 + * @return Result + */ + public static Result dataAndDate(T data, String date) { + Result result = data(data, DEFAULT_SUCCESS_MESSAGE); + result.setDate(date); + return result; + } + + public static Result dataAndRounds(T data, String rounds) { + Result result = data(data, DEFAULT_SUCCESS_MESSAGE); + result.setRounds(rounds); + return result; + } + + /** + * 返回Result + * + * @param code 状态码 + * @param data 数据 + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result data(int code, T data, String message) { + return new Result<>(code, data, data == null ? DEFAULT_NULL_MESSAGE : message); + } + + public static Result data(int code, int count, T data, String message) { + return new Result<>(code, count, data, data == null ? DEFAULT_NULL_MESSAGE : message); + } + + public static Result> page(PageResult pageResult) { + return data(HttpServletResponse.SC_OK, pageResult.getCount(), pageResult.getRows(), null); + } + + /** + * 返回Result + * + * @param T 泛型标记 + * @return Result + */ + public static Result success() { + return new Result<>(ResultCode.SUCCESS, DEFAULT_SUCCESS_MESSAGE); + } + + /** + * 返回Result + * + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result success(String message) { + return new Result<>(ResultCode.SUCCESS, message); + } + + /** + * 返回Result + * + * @param resultCode 业务代码 + * @param T 泛型标记 + * @return Result + */ + public static Result success(IResultCode resultCode) { + return new Result<>(resultCode); + } + + /** + * 返回Result + * + * @param resultCode 业务代码 + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result success(IResultCode resultCode, String message) { + return new Result<>(resultCode, message); + } + + /** + * 返回Result + * + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result fail(String message) { + return new Result<>(ResultCode.FAILURE, message); + } + + /** + * 返回Result + * + * @param code 状态码 + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result fail(int code, String message) { + return new Result<>(code, null, message); + } + + /** + * 返回Result + * + * @param resultCode 业务代码 + * @param T 泛型标记 + * @return Result + */ + public static Result fail(IResultCode resultCode) { + return new Result<>(resultCode); + } + + /** + * 返回Result + * + * @param resultCode 业务代码 + * @param message 消息 + * @param T 泛型标记 + * @return Result + */ + public static Result fail(IResultCode resultCode, String message) { + return new Result<>(resultCode, message); + } + + /** + * 返回Result + * + * @param flag 成功状态 + * @return Result + */ + public static Result status(boolean flag) { + return flag ? success(DEFAULT_SUCCESS_MESSAGE) : fail(DEFAULT_FAILURE_MESSAGE); + } + + +} diff --git a/src/main/java/cn/workde/core/data/dto/ResultCode.java b/src/main/java/cn/workde/core/data/dto/ResultCode.java new file mode 100644 index 0000000..35c0912 --- /dev/null +++ b/src/main/java/cn/workde/core/data/dto/ResultCode.java @@ -0,0 +1,41 @@ +package cn.workde.core.data.dto; + +import jakarta.servlet.http.HttpServletResponse; +import lombok.AllArgsConstructor; +import lombok.Getter; + + + +@Getter +@AllArgsConstructor +public enum ResultCode implements IResultCode { + + /** + * 操作成功 + */ + SUCCESS(HttpServletResponse.SC_OK, "操作成功"), + + /** + * 业务异常 + */ + FAILURE(HttpServletResponse.SC_BAD_REQUEST, "业务异常"), + + /** + * 请求未授权 + */ + UN_AUTHORIZED(HttpServletResponse.SC_UNAUTHORIZED, "请求未授权"), + + NOT_LOGIN(HttpServletResponse.SC_UNAUTHORIZED, "请先登录"); + ; + + /** + * code编码 + */ + final int code; + /** + * 中文信息描述 + */ + final String message; + + +} diff --git a/src/main/java/cn/workde/core/data/vo/BaseRequest.java b/src/main/java/cn/workde/core/data/vo/BaseRequest.java new file mode 100644 index 0000000..df811f5 --- /dev/null +++ b/src/main/java/cn/workde/core/data/vo/BaseRequest.java @@ -0,0 +1,116 @@ +package cn.workde.core.data.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +@Data +public class BaseRequest implements Serializable { + + private String id; + /** + * 开始时间 + */ + private String searchBeginTime; + + /** + * 结束时间 + */ + private String searchEndTime; + + /** + * 分页:每页大小(默认20) + */ + private Integer perPage; + + /** + * 分页:第几页(从1开始) + */ + private Integer page; + + /** + * 排序字段 + */ + private String orderBy; + + /** + * 正序或者倒序排列(asc 或 desc) + */ + private String orderDir; + + /** + * 搜索的参数 + */ + private List params = new ArrayList<>(); + + /** + * 唯一请求号 + */ + private String requestNo; + + /** + * 业务节点id + */ + private String spanId; + + /** + * 当前登录用户的token + */ + private String token; + + /** + * 参数校验分组:分页 + */ + public @interface page { + } + + /** + * 参数校验分组:查询所有 + */ + public @interface list { + } + + /** + * 参数校验分组:增加 + */ + public @interface add { + } + + /** + * 参数校验分组:编辑 + */ + public @interface edit { + } + + /** + * 参数校验分组:删除 + */ + public @interface delete { + } + + /** + * 参数校验分组:详情 + */ + public @interface detail { + } + + /** + * 参数校验分组:导出 + */ + public @interface export { + } + + /** + * 参数校验分组:修改状态 + */ + public @interface updateStatus { + } + + /** + * 参数校验分组:批量删除 + */ + public @interface batchDelete { + } +} diff --git a/src/main/java/cn/workde/core/data/vo/CheckTreeRequest.java b/src/main/java/cn/workde/core/data/vo/CheckTreeRequest.java new file mode 100644 index 0000000..b03344c --- /dev/null +++ b/src/main/java/cn/workde/core/data/vo/CheckTreeRequest.java @@ -0,0 +1,12 @@ +package cn.workde.core.data.vo; + +import lombok.Data; + +@Data +public class CheckTreeRequest { + + private String id; + + private String ids; + +} diff --git a/src/main/java/cn/workde/core/data/vo/TableQueryVo.java b/src/main/java/cn/workde/core/data/vo/TableQueryVo.java new file mode 100644 index 0000000..655c865 --- /dev/null +++ b/src/main/java/cn/workde/core/data/vo/TableQueryVo.java @@ -0,0 +1,19 @@ +package cn.workde.core.data.vo; + +import lombok.Data; + +@Data +public class TableQueryVo { + + private Integer page = 1; + + private Integer pageSize = 20; + + private String orderBy; + + private String orderDir; + + private String pid; + + private String pidValue; +} diff --git a/src/main/java/cn/workde/core/databind/RequestDataTransfer.java b/src/main/java/cn/workde/core/databind/RequestDataTransfer.java new file mode 100644 index 0000000..3704a5f --- /dev/null +++ b/src/main/java/cn/workde/core/databind/RequestDataTransfer.java @@ -0,0 +1,46 @@ +package cn.workde.core.databind; + +import cn.hutool.core.lang.Dict; + +public class RequestDataTransfer { + + private static final ThreadLocal CONTEXT_HOLDER = new ThreadLocal<>(); + + public static final String KEY = "SKIP_SENSITIVE"; + + public static void skipSensitive() { + put(KEY, "__all__"); + } + + public static void skipSensitive(String fieldNames) { + put(KEY, fieldNames); + } + + public static void put(Dict requestData) { + CONTEXT_HOLDER.set(requestData); + } + + public static void put(final String key, final Object value) { + Dict data = getAll(); + if (null != data && !data.isEmpty()) { + data.put(key, value); + put(data); + } else { + put(Dict.create().set(key, value)); + } + } + + public static Dict getAll() { + return CONTEXT_HOLDER.get(); + } + + public static String get(String param) { + Dict dataMap = getAll(); + return null != dataMap && !dataMap.isEmpty() ? dataMap.getStr(param) : null; + } + + public static void clear() { + CONTEXT_HOLDER.remove(); + } + +} diff --git a/src/main/java/cn/workde/core/databind/SensitiveFieldProcessModule.java b/src/main/java/cn/workde/core/databind/SensitiveFieldProcessModule.java new file mode 100644 index 0000000..b73b42e --- /dev/null +++ b/src/main/java/cn/workde/core/databind/SensitiveFieldProcessModule.java @@ -0,0 +1,26 @@ +package cn.workde.core.databind; + +import cn.workde.core.annotation.FieldSensitive; +import com.fasterxml.jackson.databind.BeanDescription; +import com.fasterxml.jackson.databind.SerializationConfig; +import com.fasterxml.jackson.databind.ser.BeanPropertyWriter; +import com.fasterxml.jackson.databind.ser.BeanSerializerModifier; + +import java.util.ArrayList; +import java.util.List; + +public class SensitiveFieldProcessModule extends BeanSerializerModifier { + + @Override + public List changeProperties(SerializationConfig config, BeanDescription beanDesc, List beanProperties) { + List newWriters = new ArrayList<>(); + for (BeanPropertyWriter writer : beanProperties) { + FieldSensitive fs = writer.getAnnotation(FieldSensitive.class); + if(fs != null && writer.getType().isTypeOrSubTypeOf(String.class)) { + writer.assignSerializer(new SensitiveJsonSerializer(fs.type())); + } + newWriters.add(writer); + } + return newWriters; + } +} diff --git a/src/main/java/cn/workde/core/databind/SensitiveJsonSerializer.java b/src/main/java/cn/workde/core/databind/SensitiveJsonSerializer.java new file mode 100644 index 0000000..953372a --- /dev/null +++ b/src/main/java/cn/workde/core/databind/SensitiveJsonSerializer.java @@ -0,0 +1,45 @@ +package cn.workde.core.databind; + +import cn.hutool.core.util.DesensitizedUtil; +import cn.hutool.core.text.CharSequenceUtil; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonStreamContext; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.Objects; + +public class SensitiveJsonSerializer extends JsonSerializer { + + private final DesensitizedUtil.DesensitizedType type; + + + public SensitiveJsonSerializer(DesensitizedUtil.DesensitizedType type) { + this.type = type; + } + + @Override + public void serialize(Object value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException { + Object fieldValue = null; + String fieldNames = RequestDataTransfer.get(RequestDataTransfer.KEY); + if (Objects.equals("__all__", fieldNames)) { + fieldValue = value; + } else { + JsonStreamContext jsc = gen.getOutputContext(); + if(jsc != null) { + String currentName = CharSequenceUtil.toCamelCase(jsc.getCurrentName()); + if(null != currentName && CharSequenceUtil.split(fieldNames, ",").contains(currentName)) { + fieldValue = value; + } + } + + if(null == fieldValue) { + fieldValue = DesensitizedUtil.desensitized(value.toString(), this.type); + } + } + + gen.writeObject(fieldValue); + + } +} diff --git a/src/main/java/cn/workde/core/db/handler/CustomMetaObjectHandler.java b/src/main/java/cn/workde/core/db/handler/CustomMetaObjectHandler.java new file mode 100644 index 0000000..b6f5ee8 --- /dev/null +++ b/src/main/java/cn/workde/core/db/handler/CustomMetaObjectHandler.java @@ -0,0 +1,47 @@ +package cn.workde.core.db.handler; + +import cn.hutool.core.util.ObjectUtil; +import cn.workde.core.util.WebUtils; +import cn.workde.module.upms.entity.GrapeAdmin; +import cn.workde.module.upms.interceptor.UpmsInterceptor; +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.ReflectionException; + +import java.util.Date; + +@Slf4j +public class CustomMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + + try { + // 设置createAt(BaseEntity) + setFieldValByName("createdAt", new Date(), metaObject); +// GrapeAdmin admin = (GrapeAdmin) WebUtils.getRequest().getAttribute(UpmsInterceptor.ADMIN_LOGGER); +// if (ObjectUtil.isNotNull(admin)){ +// setFieldValByName("createdId", admin.getId(), metaObject); +// } + } catch (ReflectionException e) { + log.warn("CustomMetaObjectHandler处理过程中无相关字段,不做处理"); + } + + } + + @Override + public void updateFill(MetaObject metaObject) { + try { + // 设置updateAt(BaseEntity) + setFieldValByName("updatedAt", new Date(), metaObject); +// GrapeAdmin admin = (GrapeAdmin) WebUtils.getRequest().getAttribute(UpmsInterceptor.ADMIN_LOGGER); +// if (ObjectUtil.isNotNull(admin)){ +// setFieldValByName("updatedId",admin.getId() , metaObject); +// } + } catch (ReflectionException e) { + log.warn("CustomMetaObjectHandler处理过程中无相关字段,不做处理"); + } + + } +} diff --git a/src/main/java/cn/workde/core/db/interceptor/FieldEncryptInterceptor.java b/src/main/java/cn/workde/core/db/interceptor/FieldEncryptInterceptor.java new file mode 100644 index 0000000..fec617b --- /dev/null +++ b/src/main/java/cn/workde/core/db/interceptor/FieldEncryptInterceptor.java @@ -0,0 +1,66 @@ +package cn.workde.core.db.interceptor; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.workde.core.annotation.FieldEncrypt; +import cn.workde.core.util.AesUtils; +import org.apache.ibatis.binding.MapperMethod; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.ParameterMap; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Signature; + +import java.lang.reflect.Field; + +@Intercepts({ + @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}) +}) +public class FieldEncryptInterceptor implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + String methodName = invocation.getMethod().getName(); + if (!"update".equalsIgnoreCase(methodName) && !"insert".equalsIgnoreCase(methodName)) { + return invocation.proceed(); + } + + // 获取该sql语句放入的参数 + Object parameter = invocation.getArgs()[1]; + if (parameter instanceof ParameterMap) { + MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) invocation.getArgs()[1]; + parameter = paramMap.get("param1"); + } + + if (parameter instanceof MapperMethod.ParamMap) { + MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) invocation.getArgs()[1]; + try { + parameter = paramMap.get("et"); + } catch (Exception e) { + parameter = paramMap.get("param1"); + } + } + + if (parameter != null) { + this.encryptField(parameter); + } + return invocation.proceed(); + } + + private void encryptField(T t) throws IllegalAccessException { + Field[] declaredFields = t.getClass().getDeclaredFields(); + if (declaredFields != null && declaredFields.length > 0) { + for (Field field : declaredFields) { + if (field.isAnnotationPresent(FieldEncrypt.class)) { + field.setAccessible(true); + String fieldValue = (String) field.get(t); + if(CharSequenceUtil.isNotEmpty(fieldValue)) { + field.set(t, AesUtils.encrypt(fieldValue)); + } + } + } + } + } + +} diff --git a/src/main/java/cn/workde/core/db/interceptor/FieldResultInterceptor.java b/src/main/java/cn/workde/core/db/interceptor/FieldResultInterceptor.java new file mode 100644 index 0000000..d9a60c0 --- /dev/null +++ b/src/main/java/cn/workde/core/db/interceptor/FieldResultInterceptor.java @@ -0,0 +1,64 @@ +package cn.workde.core.db.interceptor; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.workde.core.annotation.FieldEncrypt; +import cn.workde.core.util.AesUtils; +import org.apache.ibatis.executor.resultset.ResultSetHandler; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Signature; +import org.springframework.util.CollectionUtils; + +import java.lang.reflect.Field; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.List; + +@Intercepts({ + @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = { Statement.class }), +}) +public class FieldResultInterceptor implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + Object returnValue = invocation.proceed(); + try { + // 当返回值类型为数组集合时,就判断是否需要进行数据解密 + if (returnValue instanceof ArrayList) { + List list = (List) returnValue; + if (CollectionUtils.isEmpty(list)) { + return returnValue; + } + for(Object object : list) { + decryptField(object); + } + } else { + Object object = returnValue; + decryptField(object); + } + } catch (Exception e) { + e.printStackTrace(); + return returnValue; + } + return returnValue; + } + + private void decryptField(T t) throws IllegalAccessException { + if (t == null) { + return; + } + Field[] declaredFields = t.getClass().getDeclaredFields(); + if (declaredFields != null && declaredFields.length > 0) { + for (Field field : declaredFields) { + if (field.isAnnotationPresent(FieldEncrypt.class)) { + field.setAccessible(true); + String fieldValue = (String) field.get(t); + if(CharSequenceUtil.isNotEmpty(fieldValue)) { + field.set(t, AesUtils.decrypt(fieldValue)); + } + } + } + } + } +} diff --git a/src/main/java/cn/workde/core/db/interceptor/MybatisPlusPrintSqlInterceptor.java b/src/main/java/cn/workde/core/db/interceptor/MybatisPlusPrintSqlInterceptor.java new file mode 100644 index 0000000..080ef18 --- /dev/null +++ b/src/main/java/cn/workde/core/db/interceptor/MybatisPlusPrintSqlInterceptor.java @@ -0,0 +1,223 @@ +package cn.workde.core.db.interceptor; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.text.CharSequenceUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.cache.CacheKey; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.ParameterMapping; +import org.apache.ibatis.mapping.ParameterMode; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.ResultHandler; +import org.apache.ibatis.session.RowBounds; +import org.apache.ibatis.type.TypeHandlerRegistry; + +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * 基于Mybatis Plus的SQL输出拦截器。 + * 完美的输出打印 SQL 及执行时长、statement。 + * 注意:该插件有性能损耗,不建议生产环境使用。 + * + * @author laiqi + * @date 2023-4-4 + */ +@RequiredArgsConstructor +@Slf4j +@Intercepts(value = { + @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}), + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}), + @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) +public class MybatisPlusPrintSqlInterceptor implements Interceptor { + + /** + * 是否输出到控制台,否的情况log输出。 + */ + private final boolean outConsole; + + // com.baomidou.mybatisplus.core.MybatisParameterHandler#setParameters + private static Map buildParameterValues(Configuration configuration, BoundSql boundSql) { + Object parameterObject = boundSql.getParameterObject(); + List parameterMappings = boundSql.getParameterMappings(); + if (parameterMappings != null) { + Map parameterValues = new HashMap<>(); + TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); + for (int i = 0; i < parameterMappings.size(); i++) { + ParameterMapping parameterMapping = parameterMappings.get(i); + if (parameterMapping.getMode() != ParameterMode.OUT) { + Object value; + String propertyName = parameterMapping.getProperty(); + if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params + value = boundSql.getAdditionalParameter(propertyName); + } else if (parameterObject == null) { + value = null; + } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { + value = parameterObject; + } else { + MetaObject metaObject = configuration.newMetaObject(parameterObject); + value = metaObject.getValue(propertyName); + } + parameterValues.put(i, new Value(value)); + } + } + return parameterValues; + } + return Collections.emptyMap(); + } + + public static String formatMessage(String now, long elapsed, String sql, String statement) { + // 打印 sql + String originalSql = sql.replaceAll("[\\s]+", " "); + String format = CharSequenceUtil.format( + "\n============== Sql Start ==============" + + "\nExecute ID :{}" + + "\nExecute SQL :{}" + + "\nExecute Time:{} ms" + + "\n============== Sql End ==============\n", + statement.replaceAll("\\(", "").replaceAll("\\)", ""), originalSql, elapsed); + return format; + } + + public static String getSqlWithValues(String statementQuery, Map parameterValues) { + final StringBuilder sb = new StringBuilder(); + + // iterate over the characters in the query replacing the parameter placeholders + // with the actual values + int currentParameter = 0; + for (int pos = 0; pos < statementQuery.length(); pos++) { + char character = statementQuery.charAt(pos); + if (statementQuery.charAt(pos) == '?' && currentParameter <= parameterValues.size()) { + // replace with parameter value + Object value = parameterValues.get(currentParameter); + sb.append(value != null ? value.toString() : new Value().toString()); + currentParameter++; + } else { + sb.append(character); + } + } + + return sb.toString(); + } + + @Override + public Object intercept(Invocation invocation) throws Throwable { + MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; + Object parameter = null; + if (invocation.getArgs().length > 1) { + parameter = invocation.getArgs()[1]; + } + String statement = mappedStatement.getId(); + BoundSql boundSql = mappedStatement.getBoundSql(parameter); + Configuration configuration = mappedStatement.getConfiguration(); + long start = System.currentTimeMillis(); + Object returnValue = invocation.proceed(); + long time = System.currentTimeMillis() - start; + showSql(configuration, boundSql, time, statement); + return returnValue; + } + + private void showSql(Configuration configuration, BoundSql boundSql, long elapsed, String statement) { + String logText = formatMessage(DateUtil.now(), elapsed, getSqlWithValues(boundSql.getSql(), buildParameterValues(configuration, boundSql)), statement); + System.err.println(logText); + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties0) { + } + + /** + * 基于p6spy的简易数据类型转换类。 + * + * @author laiqi + * @date 2023-4-4 + */ + public static class Value { + public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + public static final String databaseDialectDateFormat = NORM_DATETIME_PATTERN; + public static final String databaseDialectTimestampFormat = NORM_DATETIME_PATTERN; + + public static final String databaseDialectBooleanFormat = "numeric"; + + private Object value; + + public Value(Object valueToSet) { + this(); + this.value = valueToSet; + } + + public Value() { + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public String toString() { + return convertToString(this.value); + } + + public String convertToString(Object value) { + String result; + + if (value == null) { + result = "NULL"; + } else { + + if (value instanceof byte[]) { + result = new String((byte[]) value); + } else if (value instanceof Timestamp) { + result = new SimpleDateFormat(databaseDialectTimestampFormat).format(value); + } else if (value instanceof Date) { + result = new SimpleDateFormat(databaseDialectDateFormat).format(value); + } else if (value instanceof Boolean) { + if ("numeric".equals(databaseDialectBooleanFormat)) { + result = Boolean.FALSE.equals(value) ? "0" : "1"; + } else { + result = value.toString(); + } + } else { + result = value.toString(); + } + result = quoteIfNeeded(result, value); + } + + return result; + } + + private String quoteIfNeeded(String stringValue, Object obj) { + if (stringValue == null) { + return null; + } + if (Number.class.isAssignableFrom(obj.getClass()) || Boolean.class.isAssignableFrom(obj.getClass())) { + return stringValue; + } else { + return "'" + escape(stringValue) + "'"; + } + } + + private String escape(String stringValue) { + return stringValue.replaceAll("'", "''"); + } + + } +} + + diff --git a/src/main/java/cn/workde/core/db/interceptor/SqlLogInterceptor.java b/src/main/java/cn/workde/core/db/interceptor/SqlLogInterceptor.java new file mode 100644 index 0000000..50ae703 --- /dev/null +++ b/src/main/java/cn/workde/core/db/interceptor/SqlLogInterceptor.java @@ -0,0 +1,131 @@ +package cn.workde.core.db.interceptor; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.workde.core.util.WebUtils; +import com.baomidou.mybatisplus.core.toolkit.PluginUtils; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.SystemClock; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; +import org.apache.ibatis.session.ResultHandler; +import org.springframework.util.CollectionUtils; + +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.sql.Statement; +import java.util.*; + +@Intercepts({ + @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}), + @Signature(type = StatementHandler.class, method = "update", args = Statement.class), + @Signature(type = StatementHandler.class, method = "batch", args = Statement.class) +}) +public class SqlLogInterceptor implements Interceptor { + + private Method druidGetSqlMethod; + + @Override + public Object intercept(Invocation invocation) throws Throwable { + Statement statement; + Object firstArg = invocation.getArgs()[0]; + if (Proxy.isProxyClass(firstArg.getClass())) { + statement = (Statement) SystemMetaObject.forObject(firstArg).getValue("h.statement"); + } else { + statement = (Statement) firstArg; + } + MetaObject stmtMetaObj = SystemMetaObject.forObject(statement); + try { + statement = (Statement) stmtMetaObj.getValue("stmt.statement"); + } catch (Exception e) { + // do nothing + } + if (stmtMetaObj.hasGetter("delegate")) { + //Hikari + try { + statement = (Statement) stmtMetaObj.getValue("delegate"); + } catch (Exception ignored) { + + } + } + + String originalSql = statement.toString();; + originalSql = originalSql.replaceAll("[\\s]+", StringPool.SPACE); + int index = indexOfSqlStart(originalSql); + if (index > 0) { + originalSql = originalSql.substring(index); + } + + // 计算执行 SQL 耗时 + long start = SystemClock.now(); + Object result = invocation.proceed(); + long timing = SystemClock.now() - start; + + // SQL 打印执行结果 + Object target = PluginUtils.realTarget(invocation.getTarget()); + MetaObject metaObject = SystemMetaObject.forObject(target); + MappedStatement ms = (MappedStatement) metaObject.getValue("delegate.mappedStatement"); + // 打印 sql + + System.err.println( + CharSequenceUtil.format( + "\n============== Sql Start ==============" + + "\nExecute ID :{}" + + "\nExecute SQL :{}" + + "\nExecute Time:{} ms" + + "\n============== Sql End ==============\n", + ms.getId(), originalSql, timing)); + return result; + } + + @Override + public Object plugin(Object target) { + if (target instanceof StatementHandler) { + return Plugin.wrap(target, this); + } + return target; + } + + /** + * 获取此方法名的具体 Method + * + * @param clazz class 对象 + * @param methodName 方法名 + * @return 方法 + */ + private Method getMethodRegular(Class clazz, String methodName) { + if (Object.class.equals(clazz)) { + return null; + } + for (Method method : clazz.getDeclaredMethods()) { + if (method.getName().equals(methodName)) { + return method; + } + } + return getMethodRegular(clazz.getSuperclass(), methodName); + } + + /** + * 获取sql语句开头部分 + * + * @param sql ignore + * @return ignore + */ + private int indexOfSqlStart(String sql) { + String upperCaseSql = sql.toUpperCase(); + Set set = new HashSet<>(); + set.add(upperCaseSql.indexOf("SELECT ")); + set.add(upperCaseSql.indexOf("UPDATE ")); + set.add(upperCaseSql.indexOf("INSERT ")); + set.add(upperCaseSql.indexOf("DELETE ")); + set.remove(-1); + if (CollectionUtils.isEmpty(set)) { + return -1; + } + List list = new ArrayList<>(set); + list.sort(Comparator.naturalOrder()); + return list.get(0); + } +} diff --git a/src/main/java/cn/workde/core/excel/ImportDataListener.java b/src/main/java/cn/workde/core/excel/ImportDataListener.java new file mode 100644 index 0000000..9608f44 --- /dev/null +++ b/src/main/java/cn/workde/core/excel/ImportDataListener.java @@ -0,0 +1,31 @@ +package cn.workde.core.excel; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author zhujingang + * @date 2020/6/3 2:38 PM + */ +public class ImportDataListener extends AnalysisEventListener { + + private List dataList = new ArrayList(); + + + @Override + public void invoke(T t, AnalysisContext analysisContext) { + dataList.add(t); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + + } + + public List getDataList() { + return dataList; + } +} diff --git a/src/main/java/cn/workde/core/exception/GrapeDataProxyException.java b/src/main/java/cn/workde/core/exception/GrapeDataProxyException.java new file mode 100644 index 0000000..7a17b83 --- /dev/null +++ b/src/main/java/cn/workde/core/exception/GrapeDataProxyException.java @@ -0,0 +1,18 @@ +package cn.workde.core.exception; + +public class GrapeDataProxyException extends RuntimeException{ + + public GrapeDataProxyException(Boolean isOk) { + this.isOk = isOk; + } + + private Boolean isOk; + + public Boolean getOk() { + return isOk; + } + + public void setOk(Boolean ok) { + isOk = ok; + } +} diff --git a/src/main/java/cn/workde/core/exception/ImportDataException.java b/src/main/java/cn/workde/core/exception/ImportDataException.java new file mode 100644 index 0000000..2ec663a --- /dev/null +++ b/src/main/java/cn/workde/core/exception/ImportDataException.java @@ -0,0 +1,14 @@ +package cn.workde.core.exception; + +public class ImportDataException extends RuntimeException { + + private String errorMessage; + + public ImportDataException(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/src/main/java/cn/workde/core/exception/ImportDataVaildationException.java b/src/main/java/cn/workde/core/exception/ImportDataVaildationException.java new file mode 100644 index 0000000..ef8cd5b --- /dev/null +++ b/src/main/java/cn/workde/core/exception/ImportDataVaildationException.java @@ -0,0 +1,14 @@ +package cn.workde.core.exception; + +public class ImportDataVaildationException extends RuntimeException { + + private String errorMessage; + + public ImportDataVaildationException(String errorMessage) { + this.errorMessage = errorMessage; + } + + public String getErrorMessage() { + return errorMessage; + } +} diff --git a/src/main/java/cn/workde/core/exception/ResultException.java b/src/main/java/cn/workde/core/exception/ResultException.java new file mode 100644 index 0000000..80320be --- /dev/null +++ b/src/main/java/cn/workde/core/exception/ResultException.java @@ -0,0 +1,25 @@ +package cn.workde.core.exception; + +import cn.workde.core.data.dto.Result; + +public class ResultException extends RuntimeException { + + private Result Result; + + public ResultException(){ + this.Result = Result.success(); + } + + public ResultException(String msg) { + this.Result = Result.fail(msg); + } + + public ResultException(Result Result){ + this.Result = Result; + } + + public Result getResult() { + return Result; + } + +} diff --git a/src/main/java/cn/workde/core/exception/UnAuthorizedException.java b/src/main/java/cn/workde/core/exception/UnAuthorizedException.java new file mode 100644 index 0000000..8995f73 --- /dev/null +++ b/src/main/java/cn/workde/core/exception/UnAuthorizedException.java @@ -0,0 +1,5 @@ +package cn.workde.core.exception; + +public class UnAuthorizedException extends RuntimeException { + +} diff --git a/src/main/java/cn/workde/core/factory/PageFactory.java b/src/main/java/cn/workde/core/factory/PageFactory.java new file mode 100644 index 0000000..0b3ae3a --- /dev/null +++ b/src/main/java/cn/workde/core/factory/PageFactory.java @@ -0,0 +1,33 @@ +package cn.workde.core.factory; + +import cn.hutool.core.util.ObjectUtil; +import cn.workde.core.util.HttpServletUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.servlet.http.HttpServletRequest; + + +/** + * 分页参数快速获取 + */ +public class PageFactory { + + private static final String PAGE_NO_PARAM_NAME = "current"; + + private static final String PAGE_SIZE_PARAM_NAME = "pageSize"; + + public static Page defaultPage() { + int pageNo = 1; + int pageSize = 20; + + HttpServletRequest request = HttpServletUtil.getRequest(); + + // 第几页 + String pageNoStr = request.getParameter(PAGE_NO_PARAM_NAME); + if(ObjectUtil.isNotEmpty(pageNoStr)) pageNo = Integer.parseInt(pageNoStr); + + // 每页条数 + String pageSizeStr = request.getParameter(PAGE_SIZE_PARAM_NAME); + if(ObjectUtil.isNotEmpty(pageSizeStr)) pageSize = Integer.parseInt(pageSizeStr); + return new Page<>(pageNo, pageSize); + } +} diff --git a/src/main/java/cn/workde/core/factory/PageFactory2.java b/src/main/java/cn/workde/core/factory/PageFactory2.java new file mode 100644 index 0000000..ad91945 --- /dev/null +++ b/src/main/java/cn/workde/core/factory/PageFactory2.java @@ -0,0 +1,37 @@ +package cn.workde.core.factory; + +import cn.hutool.core.util.ObjectUtil; +import cn.workde.core.util.HttpServletUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jakarta.servlet.http.HttpServletRequest; + + +/** + * 分页参数快速获取 + */ +public class PageFactory2 { + + private static final String PAGE_NO_PARAM_NAME = "page"; + + private static final String PAGE_SIZE_PARAM_NAME = "pageSize"; + + public static Page defaultPage() { + int pageNo = 1; + int pageSize = 20; + + HttpServletRequest request = HttpServletUtil.getRequest(); + + // 第几页 + String pageNoStr = request.getParameter(PAGE_NO_PARAM_NAME); + if(ObjectUtil.isNotEmpty(pageNoStr)) { + pageNo = Integer.parseInt(pageNoStr); + } + + // 每页条数 + String pageSizeStr = request.getParameter(PAGE_SIZE_PARAM_NAME); + if(ObjectUtil.isNotEmpty(pageSizeStr)) { + pageSize = Integer.parseInt(pageSizeStr); + } + return new Page<>(pageNo, pageSize); + } +} diff --git a/src/main/java/cn/workde/core/factory/PageResultFactory.java b/src/main/java/cn/workde/core/factory/PageResultFactory.java new file mode 100644 index 0000000..0fc34bb --- /dev/null +++ b/src/main/java/cn/workde/core/factory/PageResultFactory.java @@ -0,0 +1,37 @@ +package cn.workde.core.factory; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.PageUtil; +import cn.workde.core.data.dto.PageResult; +import com.baomidou.mybatisplus.core.metadata.IPage; + +import java.util.List; + +public class PageResultFactory { + + /** + * 将mybatis-plus的page转成自定义的PageResult,扩展了totalPage总页数 + */ + public static PageResult createPageResult(IPage page) { + PageResult pageResult = new PageResult<>(); + pageResult.setRows(page.getRecords()); + pageResult.setCount(Convert.toInt(page.getTotal())); + pageResult.setPageNo(Convert.toInt(page.getCurrent())); + pageResult.setPageSize(Convert.toInt(page.getSize())); + pageResult.setTotalPage(PageUtil.totalPage(pageResult.getCount(), pageResult.getPageSize())); + return pageResult; + } + + /** + * 转成自定义PageResult + */ + public static PageResult createPageResult(List rows, Long count, Integer pageSize, Integer pageNo) { + PageResult pageResult = new PageResult<>(); + pageResult.setRows(rows); + pageResult.setCount(Convert.toInt(count)); + pageResult.setPageNo(pageNo); + pageResult.setPageSize(pageSize); + pageResult.setTotalPage(PageUtil.totalPage(pageResult.getCount(), pageSize)); + return pageResult; + } +} diff --git a/src/main/java/cn/workde/core/filter/CorsFilter.java b/src/main/java/cn/workde/core/filter/CorsFilter.java new file mode 100644 index 0000000..2ac66a5 --- /dev/null +++ b/src/main/java/cn/workde/core/filter/CorsFilter.java @@ -0,0 +1,36 @@ +package cn.workde.core.filter; + +import jakarta.servlet.*; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +/** + * 解决跨域 + * 参考:https://www.cnblogs.com/csguo/p/9597791.html + * + * @author zhouyuan + * @created 2019/11/29 13:48 + */ +//@Component +public class CorsFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) { + + } + + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { + HttpServletResponse response = (HttpServletResponse) res; + response.setHeader("Access-Control-Allow-Origin", "*"); + response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); + response.setHeader("Access-Control-Max-Age", "3600"); + response.setHeader("Access-Control-Allow-Headers", "x-requested-with"); + chain.doFilter(req, res); + System.out.println("跨域过滤器被调用"); + } + + /*@Override + public void destroy() { + }*/ +} diff --git a/src/main/java/cn/workde/core/filter/ResponseHeaderFilter.java b/src/main/java/cn/workde/core/filter/ResponseHeaderFilter.java new file mode 100644 index 0000000..4d73db6 --- /dev/null +++ b/src/main/java/cn/workde/core/filter/ResponseHeaderFilter.java @@ -0,0 +1,50 @@ +package cn.workde.core.filter; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +/** + * @version 1.0 + * @description TODO + * @author shentao + * @date 2023/12/7 16:37 + */ + +/** + * 响应头过滤器,用于设置HTTP响应头的安全性选项 + */ +//@Component +public class ResponseHeaderFilter extends OncePerRequestFilter { + + + /** + * 重写doFilterInternal方法,实现对HTTP响应头的安全性选项设置 + * + * @param httpServletRequest HTTP请求对象 + * @param httpServletResponse HTTP响应对象 + * @param filterChain 过滤器链 + * @throws ServletException Servlet异常 + * @throws IOException IO异常 + */ + @Override + protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException { + // 新增X-Content-Type-Options响应头,防止MIME类型嗅探攻击 + httpServletResponse.addHeader("X-Content-Type-Options", "nosniff"); + // 新增Strict-Transport-Security响应头,启用HSTS(HTTP Strict Transport Security) + httpServletResponse.addHeader("Strict-Transport-Security ", "max-age=16070400"); + // 新增X-Frame-Options响应头,防止点击劫持攻击 + httpServletResponse.addHeader("X-Frame-Options", "DENY"); + // 新增X-XSS-Protection响应头,启用XSS保护 + httpServletResponse.addHeader("X-XSS-Protection", "1; mode=block"); + // 调用过滤器链,继续处理请求 + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + +} + diff --git a/src/main/java/cn/workde/core/handler/ExcelDataValidationHandler.java b/src/main/java/cn/workde/core/handler/ExcelDataValidationHandler.java new file mode 100644 index 0000000..8eda555 --- /dev/null +++ b/src/main/java/cn/workde/core/handler/ExcelDataValidationHandler.java @@ -0,0 +1,68 @@ +package cn.workde.core.handler; + + +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.DataValidation; +import org.apache.poi.ss.usermodel.DataValidationConstraint; +import org.apache.poi.ss.usermodel.DataValidationHelper; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddressList; + +import java.util.List; +import java.util.Map; + +/** + * @author liuhaoze + * @date 2021/12/17 10:13 + */ +public class ExcelDataValidationHandler implements CellWriteHandler { + + private Map dataValidation; + + public ExcelDataValidationHandler(Map dataValidation){ + this.dataValidation = dataValidation; + } + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) { + + } + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + if(isHead){ + Sheet sheet = writeSheetHolder.getSheet(); + DataValidationHelper helper = sheet.getDataValidationHelper(); + dataValidation.forEach((k, v) -> { + // 设置下拉单元格的首行 末行 首列 末列 + CellRangeAddressList rangeList = new CellRangeAddressList(1, 100000, k, k); + // 下拉列表约束数据 + DataValidationConstraint constraint = helper.createExplicitListConstraint(v); + // 设置约束 + DataValidation validation = helper.createValidation(constraint, rangeList); + // 阻止输入非下拉选项的值 + validation.setErrorStyle(DataValidation.ErrorStyle.STOP); + validation.setShowErrorBox(true); + validation.setSuppressDropDownArrow(true); + validation.createErrorBox("提示", "此值与单元格定义格式不一致"); + sheet.addValidationData(validation); + }); + } + } +} diff --git a/src/main/java/cn/workde/core/handler/GlobalExceptionHandler.java b/src/main/java/cn/workde/core/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..6b66ba2 --- /dev/null +++ b/src/main/java/cn/workde/core/handler/GlobalExceptionHandler.java @@ -0,0 +1,79 @@ +package cn.workde.core.handler; + +import cn.workde.core.data.dto.Result; +import cn.workde.core.data.dto.ResultCode; +import cn.workde.core.exception.ResultException; +import cn.workde.core.exception.UnAuthorizedException; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.ConstraintViolationException; +import org.springframework.http.HttpStatus; +import org.springframework.validation.BindException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author zhujingang + * @date 2020/5/20 9:17 AM + */ +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(Exception.class) + public Result globalException(Exception e, HttpServletResponse response) { + e.printStackTrace(); + System.out.println(e.getMessage()); + return Result.fail("服务器错误,请联系管理员"); + } + + + @ExceptionHandler(ConstraintViolationException.class) + public Result handlerConstraintViolationException(ConstraintViolationException e) { + return Result.fail(e.getConstraintViolations().iterator().next().getMessage()); + } + + @ExceptionHandler(BindException.class) + public Result handlerBindException(BindException e) { + for (Field field : e.getTarget().getClass().getDeclaredFields()) { + FieldError fieldError = e.getBindingResult().getFieldError(field.getName()); + if (fieldError != null) { + return Result.fail(fieldError.getDefaultMessage()); + } + } + return Result.fail(e.getBindingResult().getAllErrors().get(0).getDefaultMessage()); + } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) { + BindingResult bindingResult = e.getBindingResult(); + Map maps = null; + if (bindingResult.hasErrors()) { + List fieldErrors = bindingResult.getFieldErrors(); + maps = new HashMap<>(fieldErrors.size()); + Map finalMaps = maps; + fieldErrors.forEach(error -> finalMaps.put(error.getField(), error.getDefaultMessage())); + return Result.fail(fieldErrors.get(0).getDefaultMessage()); + } + return Result.fail("参数校验失败"); + } + + @ExceptionHandler(ResultException.class) + public Result handlerResultException(ResultException e) { + return e.getResult(); + } + + @ExceptionHandler(UnAuthorizedException.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Result handlerUnAuthorizedException(UnAuthorizedException e) { + return Result.fail(ResultCode.UN_AUTHORIZED.getCode(),ResultCode.UN_AUTHORIZED.getMessage()); + } + + +} diff --git a/src/main/java/cn/workde/core/interceptor/GlobalInterceptor.java b/src/main/java/cn/workde/core/interceptor/GlobalInterceptor.java new file mode 100644 index 0000000..aac1769 --- /dev/null +++ b/src/main/java/cn/workde/core/interceptor/GlobalInterceptor.java @@ -0,0 +1,14 @@ +package cn.workde.core.interceptor; + +import cn.workde.core.databind.RequestDataTransfer; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.Data; +import org.springframework.web.servlet.HandlerInterceptor; +public class GlobalInterceptor implements HandlerInterceptor { + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + RequestDataTransfer.clear(); + } +} diff --git a/src/main/java/cn/workde/core/invoke/DataProxyInvoke.java b/src/main/java/cn/workde/core/invoke/DataProxyInvoke.java new file mode 100644 index 0000000..6a0a8a1 --- /dev/null +++ b/src/main/java/cn/workde/core/invoke/DataProxyInvoke.java @@ -0,0 +1,25 @@ +package cn.workde.core.invoke; +import cn.workde.core.annotation.data.DataProxy; +import cn.workde.core.util.SpringUtil; +import cn.workde.module.grape.model.GrapeModel; + +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.stream.Stream; + +public class DataProxyInvoke { + + public static void invoke(GrapeModel grapeModel, Consumer consumer) { + if(grapeModel == null) { + return; + } + Stream.of(grapeModel.getGrape().dataProxy()).forEach(proxy -> consumer.accept(SpringUtil.getBean(proxy))); + } + + public static Object invokeOnce(GrapeModel grapeModel, Function function){ + if(grapeModel.getGrape().dataProxy().length>0){ + return function.apply(SpringUtil.getBean(grapeModel.getGrape().dataProxy()[0])); + } + return null; + } +} diff --git a/src/main/java/cn/workde/core/ip/IpIndex.java b/src/main/java/cn/workde/core/ip/IpIndex.java new file mode 100644 index 0000000..e2e8527 --- /dev/null +++ b/src/main/java/cn/workde/core/ip/IpIndex.java @@ -0,0 +1,9 @@ +package cn.workde.core.ip; + +public class IpIndex { + public long startip; + public long endip; + public int local_offset; + public int local_length; + +} diff --git a/src/main/java/cn/workde/core/ip/IpSearch.java b/src/main/java/cn/workde/core/ip/IpSearch.java new file mode 100644 index 0000000..51b2612 --- /dev/null +++ b/src/main/java/cn/workde/core/ip/IpSearch.java @@ -0,0 +1,198 @@ +package cn.workde.core.ip; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.HashMap; + +/** + * 最新一代文件结构 高性能解析IP数据库 qqzeng-ip.dat + * 编码:UTF8 字节序:Little-Endian + * For detailed information and guide: http://qqzeng.com/ + * + * @author qqzeng-ip 于 2015-08-01 + */ +public class IpSearch { + + private static IpSearch instance = null; + + private byte[] data; + + private HashMap prefixMap; + + private long firstStartIpOffset;// 索引区第一条流位置 + // private int lastStartIpOffset;//索引区最后一条流位置 + private long prefixStartOffset;// 前缀区第一条的流位置 + private long prefixEndOffset;// 前缀区最后一条的流位置 + // private int ipCount; //ip段数量 + private long prefixCount; // 前缀数量 + + public IpSearch() { + try { + //项目地址 + String property = System.getProperty("user.dir"); + Path path = Paths.get(property, "ip", "qqzeng-ip-utf8.dat"); + data = Files.readAllBytes(path); + } catch (IOException e) { + e.printStackTrace(); + } + + firstStartIpOffset = BytesToLong(data[0], data[1], data[2], data[3]); + // lastStartIpOffset = BytesToLong(data[4], data[5], data[6], data[7]); + prefixStartOffset = BytesToLong(data[8], data[9], data[10], data[11]); + prefixEndOffset = BytesToLong(data[12], data[13], data[14], data[15]); + + // ipCount = (lastStartIpOffset - firstStartIpOffset) / 12 + 1; //索引区块每组 + // 12字节 + prefixCount = (prefixEndOffset - prefixStartOffset) / 9 + 1; // 前缀区块每组 + // 9字节 + + // 初始化前缀对应索引区区间 + byte[] indexBuffer = Arrays.copyOfRange(data, (int) prefixStartOffset, (int) prefixEndOffset + 9); + prefixMap = new HashMap(); + for (int k = 0; k < prefixCount; k++) { + int i = k * 9; + int prefix = (int) (indexBuffer[i] & 0xFFL); + + PrefixIndex pf = new PrefixIndex(); + pf.start_index = BytesToLong(indexBuffer[i + 1], indexBuffer[i + 2], indexBuffer[i + 3], indexBuffer[i + 4]); + pf.end_index = BytesToLong(indexBuffer[i + 5], indexBuffer[i + 6], indexBuffer[i + 7], indexBuffer[i + 8]); + prefixMap.put(prefix, pf); + + } + + } + + public synchronized static IpSearch getInstance() { + if (null == instance) + instance = new IpSearch(); + return instance; + } + + public static void main(String[] args) { + + IpSearch finder = IpSearch.getInstance(); + + String ip = "210.51.200.123"; + String result = finder.Get(ip); + System.out.println(ip); + System.out.println(result); + + /* + * 1.197.224.9 亚洲|中国|河南|周口|商水|电信|411623|China|CN|114.60604|33.53912 + */ + + } + + public String Get(String ip) { + String[] ips = ip.split("\\."); + int prefix = Integer.valueOf(ips[0]); + long intIP = ipToLong(ip); + + long high = 0; + long low = 0; + + if (prefixMap.containsKey(prefix)) { + low = prefixMap.get(prefix).start_index; + high = prefixMap.get(prefix).end_index; + + } else { + return ""; + } + + long my_index = low == high ? low : BinarySearch(low, high, intIP); + + IpIndex ipindex = new IpIndex(); + GetIndex((int) my_index, ipindex); + + if ((ipindex.startip <= intIP) && (ipindex.endip >= intIP)) { + return GetLocal(ipindex.local_offset, ipindex.local_length); + } else { + return ""; + } + + } + + // / + // / 二分逼近算法 + // / + public long BinarySearch(long low, long high, long k) { + long M = 0; + while (low <= high) { + long mid = (low + high) / 2; + + long endipNum = GetEndIp(mid); + if (endipNum >= k) { + M = mid; + if (mid == 0) { + break; // 防止溢出 + } + high = mid - 1; + } else + low = mid + 1; + } + return M; + } + + // / + // / 在索引区解析 + // / + // / ip第left个索引 + private void GetIndex(int left, IpIndex ipindex) { + int left_offset = (int) firstStartIpOffset + (left * 12); + ipindex.startip = BytesToLong(data[left_offset], data[1 + left_offset], data[2 + left_offset], data[3 + left_offset]); + ipindex.endip = BytesToLong(data[4 + left_offset], data[5 + left_offset], data[6 + left_offset], data[7 + left_offset]); + ipindex.local_offset = (int) BytesToLong3(data[8 + left_offset], data[9 + left_offset], data[10 + left_offset]); + ipindex.local_length = (int) data[11 + left_offset]; + } + + // / + // / 只获取结束ip的数值 + // / + // / 索引区第left个索引 + // / 返回结束ip的数值 + private long GetEndIp(long left) { + int left_offset = (int) firstStartIpOffset + (int) (left * 12); + return BytesToLong(data[4 + left_offset], data[5 + left_offset], data[6 + left_offset], data[7 + left_offset]); + + } + + // / + // / 返回地址信息 + // / + // / 地址信息的流位置 + // / 地址信息的流长度 + // / + private String GetLocal(int local_offset, int local_length) { + byte[] bytes = new byte[local_length]; + bytes = Arrays.copyOfRange(data, local_offset, local_offset + local_length); + return new String(bytes, StandardCharsets.UTF_8); + + } + + // / + // / 字节转整形 小节序 + // / + private long BytesToLong(byte a, byte b, byte c, byte d) { + return (a & 0xFFL) | ((b << 8) & 0xFF00L) | ((c << 16) & 0xFF0000L) | ((d << 24) & 0xFF000000L); + + } + + private long BytesToLong3(byte a, byte b, byte c) { + return (a & 0xFFL) | ((b << 8) & 0xFF00L) | ((c << 16) & 0xFF0000L); + + } + + public long ipToLong(String ip) { + String[] quads = ip.split("\\."); + long result = 0; + result += Integer.parseInt(quads[3]); + result += Long.parseLong(quads[2]) << 8L; + result += Long.parseLong(quads[1]) << 16L; + result += Long.parseLong(quads[0]) << 24L; + return result; + } +} diff --git a/src/main/java/cn/workde/core/ip/PrefixIndex.java b/src/main/java/cn/workde/core/ip/PrefixIndex.java new file mode 100644 index 0000000..bb3eca7 --- /dev/null +++ b/src/main/java/cn/workde/core/ip/PrefixIndex.java @@ -0,0 +1,7 @@ +package cn.workde.core.ip; + +public class PrefixIndex { + public long start_index; + public long end_index; + +} diff --git a/src/main/java/cn/workde/core/meta/MetaUtil.java b/src/main/java/cn/workde/core/meta/MetaUtil.java new file mode 100644 index 0000000..bf7765f --- /dev/null +++ b/src/main/java/cn/workde/core/meta/MetaUtil.java @@ -0,0 +1,87 @@ +package cn.workde.core.meta; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.workde.core.meta.schema.ObjectViews; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.InputStream; +import java.io.StringReader; + +public class MetaUtil { + + private static final String REMOTE_SCHEMA = "object-views_2.0.xsd"; + + private static final String INDENT_STRING = " "; + private static final String[] INDENT_PROPERTIES = { + "com.sun.xml.internal.bind.indentString", + "com.sun.xml.bind.indentString" + }; + + private static Marshaller marshaller; + private static Unmarshaller unmarshaller; + private static DocumentBuilderFactory documentBuilderFactory; + + public static void init() throws JAXBException { + if(unmarshaller != null) { + return; + } + + JAXBContext context = JAXBContext.newInstance(ObjectViews.class); + unmarshaller = context.createUnmarshaller(); + marshaller = context.createMarshaller(); + marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); + + for (String name : INDENT_PROPERTIES) { + try { + marshaller.setProperty(name, INDENT_STRING); + break; + } catch (Exception e) { + e.printStackTrace(); + } + } + +// SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); +// Schema schema = schemaFactory.newSchema(); +// +// unmarshaller.setSchema(schema); +// marshaller.setSchema(schema); + + } + + public static ObjectViews fromXML(String xml) throws JAXBException { + if (CharSequenceUtil.isEmpty(xml)) { + return null; + } + + //if (!xml.trim().startsWith("\n"); + sb.append("\n") + .append(xml) + .append("\n"); + return sb.toString(); + } +} diff --git a/src/main/java/cn/workde/core/meta/loader/AbstractLoader.java b/src/main/java/cn/workde/core/meta/loader/AbstractLoader.java new file mode 100644 index 0000000..744e35b --- /dev/null +++ b/src/main/java/cn/workde/core/meta/loader/AbstractLoader.java @@ -0,0 +1,27 @@ +package cn.workde.core.meta.loader; + +import lombok.extern.slf4j.Slf4j; + +import java.util.AbstractMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +@Slf4j +public class AbstractLoader { + + private static final Set, String>> visited = new HashSet<>(); + + protected boolean isVisited(Class type, String name) { + synchronized (visited) { + Map.Entry, String> key = new AbstractMap.SimpleImmutableEntry<>(type, name); + if (visited.contains(key)) { + log.error("存在重复 {} 名称: {}", type.getSimpleName(), name); + return true; + } + visited.add(key); + return false; + } + } + +} diff --git a/src/main/java/cn/workde/core/meta/loader/MenuLoader.java b/src/main/java/cn/workde/core/meta/loader/MenuLoader.java new file mode 100644 index 0000000..db39c48 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/loader/MenuLoader.java @@ -0,0 +1,4 @@ +package cn.workde.core.meta.loader; + +public class MenuLoader { +} diff --git a/src/main/java/cn/workde/core/meta/loader/ViewLoader.java b/src/main/java/cn/workde/core/meta/loader/ViewLoader.java new file mode 100644 index 0000000..20e5423 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/loader/ViewLoader.java @@ -0,0 +1,130 @@ +package cn.workde.core.meta.loader; + +import cn.hutool.core.io.resource.ResourceUtil; +import cn.hutool.core.util.XmlUtil; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import cn.workde.core.meta.MetaUtil; +import cn.workde.core.meta.schema.ObjectViews; +import cn.workde.core.meta.schema.views.AbstractView; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.w3c.dom.*; + +import javax.xml.bind.JAXBException; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Collections; +import java.util.List; + +@Slf4j +public class ViewLoader extends AbstractLoader { + + void process(URL url, boolean update) throws IOException, JAXBException { + final ObjectViews all; + try(InputStream stream = url.openStream()) { + all = MetaUtil.fromXML(stream); + } + + //getList(all.getMenus()).forEach(menuItem -> importMenu(menuItem, getFileName(url))); + getList(all.getViews()).forEach(view -> importView(view, getFileName(url))); + } + + + private static List getList(List list) { + return list != null ? list : Collections.emptyList(); + } + + private static String getFileName(URL url) { + final String urlStr = url.getFile(); + return urlStr.substring(urlStr.lastIndexOf('/') + 1); + } + + private void importView(AbstractView view, String sourceFile) { + + } + + @SneakyThrows + public static JSONObject findFileURL() { + URL url = ResourceUtil.getResource("views/DMS.xml"); + new ViewLoader().process(url, true); + + String xml = ResourceUtil.readUtf8Str("views/DMS.xml"); + ObjectViews objectViews = MetaUtil.fromXML(xml); + return JSONUtil.parseObj(objectViews); + } + + @SneakyThrows + public static JSONObject readView(String id) { + String xml = ResourceUtil.readUtf8Str("views/" + id); + Document doc = XmlUtil.parseXml(xml); + Element root = doc.getDocumentElement(); + JSONObject attributes = getNodeAttributes(root); + JSONObject view = new JSONObject(); + if(root.hasAttributes()) { + view.putAll(attributes); + } + + JSONArray views = new JSONArray(); + NodeList nodeList = root.getChildNodes(); + for(int i = 0; i < nodeList.getLength(); i++) { + Node item = nodeList.item(i); + if(item instanceof Element) { + String name = item.getNodeName(); + JSONObject object = new JSONObject(); + object.set("type", name); + JSONObject props = getNodeAttributes(item); + if(item.hasChildNodes()) { + String key = props.containsKey("child") ? props.getStr("child") : "child"; + object.set(key, getChildNodes(item)); + } + + if(item.hasAttributes()) { + props.remove("child"); + object.putAll(props); + } + views.add(object); + } + } + view.set("views", views); + return view; + } + + public static JSONArray getChildNodes(Node element) { + JSONArray elementList = new JSONArray(); + if(element.hasChildNodes()) { + NodeList childNodes = element.getChildNodes(); + for(int i = 0; i< childNodes.getLength(); i++) { + Node item = childNodes.item(i); + if(item instanceof Element) { + JSONObject object = new JSONObject(); + String name = item.getNodeName(); + object.set("name", name); + if(item.hasAttributes()) object.putAll(getNodeAttributes(item)); + elementList.add(object); + } + } + } + + return elementList; + } + + public static JSONObject getNodeAttributes(Node element) { + JSONObject object = new JSONObject(); + if(element.hasAttributes()) { + NamedNodeMap attributes = element.getAttributes(); + for(int i = 0; i < attributes.getLength(); i++) { + Node attr = attributes.item(i); + String name = attr.getNodeName(); + object.set(name, attr.getNodeValue()); + } + } + + return object; + } + + + +} diff --git a/src/main/java/cn/workde/core/meta/schema/ObjectViews.java b/src/main/java/cn/workde/core/meta/schema/ObjectViews.java new file mode 100644 index 0000000..55a0af0 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/ObjectViews.java @@ -0,0 +1,61 @@ +package cn.workde.core.meta.schema; + +import cn.workde.core.meta.schema.actions.AbstractAction; +import cn.workde.core.meta.schema.actions.ActionMethod; +import cn.workde.core.meta.schema.actions.ActionView; +import cn.workde.core.meta.schema.views.AbstractView; +import cn.workde.core.meta.schema.views.FormView; +import cn.workde.core.meta.schema.views.GridView; +import cn.workde.core.meta.schema.views.Selection; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "object-views") +public class ObjectViews { + + public static final String NAMESPACE = "http://axelor.com/xml/ns/object-views"; + + @XmlElements(value = { + @XmlElement(name = "form", type = FormView.class), + @XmlElement(name = "grid", type = GridView.class) + }) + private List views; + + @XmlElement(name = "selection", type = Selection.class) + private List selections; + + @XmlElements(value = { + @XmlElement(name = "action-view", type = ActionView.class), + @XmlElement(name = "action-method", type = ActionMethod.class) + }) + private List actions; + + + public List getViews() { + return views; + } + + public void setViews(List views) { + this.views = views; + } + + public List getSelections() { + return selections; + } + + public void setSelections(List selections) { + this.selections = selections; + } + + public List getActions() { + return actions; + } + + public void setActions(List actions) { + this.actions = actions; + } + +} diff --git a/src/main/java/cn/workde/core/meta/schema/actions/AbstractAction.java b/src/main/java/cn/workde/core/meta/schema/actions/AbstractAction.java new file mode 100644 index 0000000..bc3761b --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/actions/AbstractAction.java @@ -0,0 +1,37 @@ +package cn.workde.core.meta.schema.actions; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; + +@XmlType(name = "AbstractAction") +public abstract class AbstractAction { + + @XmlAttribute + private String id; + + @XmlAttribute + private String model; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + @XmlType + public abstract static class Element { + + @XmlAttribute + private String id; + } +} diff --git a/src/main/java/cn/workde/core/meta/schema/actions/ActionMethod.java b/src/main/java/cn/workde/core/meta/schema/actions/ActionMethod.java new file mode 100644 index 0000000..9f85a2a --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/actions/ActionMethod.java @@ -0,0 +1,43 @@ +package cn.workde.core.meta.schema.actions; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +@XmlType +public class ActionMethod extends AbstractAction { + + @XmlElement(name = "call") + private Call call; + + public Call getCall() { + return call; + } + + public void setCall(Call call) { + this.call = call; + } + + public static class Call extends Element { + + @XmlAttribute private String method; + + @XmlAttribute(name = "class") private String controller; + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getController() { + return controller; + } + + public void setController(String controller) { + this.controller = controller; + } + } +} diff --git a/src/main/java/cn/workde/core/meta/schema/actions/ActionView.java b/src/main/java/cn/workde/core/meta/schema/actions/ActionView.java new file mode 100644 index 0000000..a508896 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/actions/ActionView.java @@ -0,0 +1,37 @@ +package cn.workde.core.meta.schema.actions; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +@XmlType +public class ActionView extends AbstractAction { + + @XmlAttribute private String title; + + @XmlAttribute private String icon; + + @XmlAttribute private Boolean home; + + @XmlElement + private String domain; + + @XmlElement(name = "view") + private List views; + + @XmlType + public static class View extends Element{ + + @XmlAttribute private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + +} diff --git a/src/main/java/cn/workde/core/meta/schema/actions/package-info.java b/src/main/java/cn/workde/core/meta/schema/actions/package-info.java new file mode 100644 index 0000000..72c4c4c --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/actions/package-info.java @@ -0,0 +1,2 @@ +@javax.xml.bind.annotation.XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD) +package cn.workde.core.meta.schema.actions; diff --git a/src/main/java/cn/workde/core/meta/schema/package-info.java b/src/main/java/cn/workde/core/meta/schema/package-info.java new file mode 100644 index 0000000..0b1e268 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/package-info.java @@ -0,0 +1,2 @@ +@javax.xml.bind.annotation.XmlAccessorType(javax.xml.bind.annotation.XmlAccessType.FIELD) +package cn.workde.core.meta.schema; diff --git a/src/main/java/cn/workde/core/meta/schema/views/AbstractView.java b/src/main/java/cn/workde/core/meta/schema/views/AbstractView.java new file mode 100644 index 0000000..acece78 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/views/AbstractView.java @@ -0,0 +1,41 @@ +package cn.workde.core.meta.schema.views; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; + +@XmlType +public abstract class AbstractView { + + @XmlAttribute + private String id; + + @XmlAttribute + private String title; + + @XmlAttribute + private String model; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } +} diff --git a/src/main/java/cn/workde/core/meta/schema/views/FormView.java b/src/main/java/cn/workde/core/meta/schema/views/FormView.java new file mode 100644 index 0000000..0f8fb2c --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/views/FormView.java @@ -0,0 +1,7 @@ +package cn.workde.core.meta.schema.views; + +import javax.xml.bind.annotation.XmlType; + +@XmlType +public class FormView extends AbstractView { +} diff --git a/src/main/java/cn/workde/core/meta/schema/views/GridView.java b/src/main/java/cn/workde/core/meta/schema/views/GridView.java new file mode 100644 index 0000000..a9137a3 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/views/GridView.java @@ -0,0 +1,7 @@ +package cn.workde.core.meta.schema.views; + +import javax.xml.bind.annotation.XmlType; + +@XmlType +public class GridView extends AbstractView { +} diff --git a/src/main/java/cn/workde/core/meta/schema/views/MenuItem.java b/src/main/java/cn/workde/core/meta/schema/views/MenuItem.java new file mode 100644 index 0000000..7b2d948 --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/views/MenuItem.java @@ -0,0 +1,90 @@ +package cn.workde.core.meta.schema.views; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlType; + + +@XmlType +public class MenuItem { + + @XmlAttribute(name = "id") + private String xmlId; + + @XmlAttribute private String name; + + @XmlAttribute private String label; + + @XmlAttribute private String parent; + + @XmlAttribute private String icon; + + @XmlAttribute private String action; + + @XmlAttribute private String type; + + @XmlAttribute private Integer order; + + public String getXmlId() { + return xmlId; + } + + public void setXmlId(String xmlId) { + this.xmlId = xmlId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Integer getOrder() { + return order; + } + + public void setOrder(Integer order) { + this.order = order; + } +} diff --git a/src/main/java/cn/workde/core/meta/schema/views/Selection.java b/src/main/java/cn/workde/core/meta/schema/views/Selection.java new file mode 100644 index 0000000..d56aa0d --- /dev/null +++ b/src/main/java/cn/workde/core/meta/schema/views/Selection.java @@ -0,0 +1,57 @@ +package cn.workde.core.meta.schema.views; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.XmlValue; +import java.util.List; + +@XmlType +public class Selection { + + @XmlAttribute private String id; + + @XmlElement(name = "option", type = Option.class) + private List