Browse Source

first commit

main
wang 12 hours ago
commit
c2b222ec52
  1. BIN
      .DS_Store
  2. 37
      .gitignore
  3. 51
      .superpowers/brainstorm/62699-1778123142/content/operate-log-page-layout.html
  4. 1
      .superpowers/brainstorm/62699-1778123142/state/server-stopped
  5. 3
      .superpowers/brainstorm/62699-1778123142/state/server.log
  6. 1
      .superpowers/brainstorm/62699-1778123142/state/server.pid
  7. 21
      LICENSE
  8. BIN
      docs/.DS_Store
  9. 8825
      logs/sa-admin/dev/debug/debug.log
  10. 425
      logs/sa-admin/dev/error/error.log
  11. 32
      logs/sa-admin/dev/info/info.log
  12. 2
      logs/sa-admin/dev/slow-sql/slow-sql.log
  13. 103
      logs/sa-admin/dev/tomcat-logs/logs/access_log.2026-06-02.log
  14. 34
      logs/sa-admin/dev/warn/warn.log
  15. 465
      smart-flow-api/pom.xml
  16. 67
      smart-flow-api/sa-admin/pom.xml
  17. 37
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/AdminApplication.java
  18. 41
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/MvcConfig.java
  19. 43
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java
  20. 54
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java
  21. 14
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java
  22. 65
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java
  23. 140
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java
  24. 33
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java
  25. 66
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java
  26. 59
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java
  27. 43
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java
  28. 26
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java
  29. 67
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java
  30. 44
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java
  31. 22
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java
  32. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java
  33. 51
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java
  34. 43
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java
  35. 110
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java
  36. 185
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java
  37. 203
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java
  38. 39
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java
  39. 91
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java
  40. 34
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java
  41. 68
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java
  42. 53
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java
  43. 34
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.java
  44. 42
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java
  45. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java
  46. 41
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.java
  47. 51
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java
  48. 208
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java
  49. 78
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java
  50. 44
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java
  51. 142
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java
  52. 54
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java
  53. 92
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java
  54. 37
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java
  55. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java
  56. 55
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java
  57. 134
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java
  58. 16
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java
  59. 235
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java
  60. 43
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java
  61. 61
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java
  62. 66
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java
  63. 48
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java
  64. 150
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java
  65. 97
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java
  66. 26
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java
  67. 29
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java
  68. 35
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java
  69. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java
  70. 44
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java
  71. 45
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.java
  72. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java
  73. 86
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java
  74. 84
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java
  75. 57
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java
  76. 140
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java
  77. 55
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java
  78. 95
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java
  79. 37
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java
  80. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java
  81. 55
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java
  82. 77
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/controller/LeaveController.java
  83. 32
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/dao/LeaveDao.java
  84. 97
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/entity/LeaveEntity.java
  85. 46
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/form/LeaveAddForm.java
  86. 36
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/form/LeaveQueryForm.java
  87. 47
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/form/LeaveUpdateForm.java
  88. 59
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/vo/LeaveVO.java
  89. 19
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/manager/LeaveManager.java
  90. 89
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/service/LeaveService.java
  91. 33
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java
  92. 138
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java
  93. 123
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java
  94. 17
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java
  95. 111
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java
  96. 38
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java
  97. 75
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java
  98. 32
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java
  99. 57
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java
  100. 36
      smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java

BIN
.DS_Store

Binary file not shown.

37
.gitignore

@ -0,0 +1,37 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
# 保留 .idea 与模块 *.iml 以便克隆后可直接打开工程;仅忽略本机/会话文件
.idea/workspace.xml
.idea/tasks.xml
.idea/dataSources/
.idea/dataSources.local.xml
.idea/shelf/
.idea/httpRequests/
.idea/usage.statistics.xml
.idea/statistics.xml
.idea/dictionaries/
.idea/libraries/
.idea/aws.xml
*.iws
*.ipr
.idea/*
### front ###
**/dist
**/node_modules
**/.vscode
**/.env
**/.log

51
.superpowers/brainstorm/62699-1778123142/content/operate-log-page-layout.html

@ -0,0 +1,51 @@
<h2>操作日志管理页(拟)</h2>
<p class="subtitle">这是基于你现有风格的一版布局草图:筛选区 + 表格分页 + 详情弹窗(不在此页展示)。看完告诉我是否需要调整筛选项/列。</p>
<div class="section">
<div class="mockup">
<div class="mockup-header">筛选区</div>
<div class="mockup-body">
<div style="display:flex;flex-wrap:wrap;gap:12px;align-items:center">
<div class="mock-input" style="width:220px">用户名/账号(模糊)</div>
<div class="mock-input" style="width:220px">操作模块(下拉)</div>
<div class="mock-input" style="width:220px">操作类型(下拉)</div>
<div class="mock-input" style="width:280px">时间范围(起止)</div>
<div class="mock-input" style="width:260px">请求关键字(URL/内容)</div>
<button class="mock-button">查询</button>
<button class="mock-button" style="opacity:.8">重置</button>
</div>
<p class="subtitle" style="margin-top:10px">自动脱敏:password/token/authorization;超长参数截断;异常请求也记录。</p>
</div>
</div>
</div>
<div class="section">
<div class="mockup">
<div class="mockup-header">表格列(可配置)</div>
<div class="mockup-body">
<div class="placeholder" style="height:180px">
列建议:时间|账号(loginName)|姓名(actualName)|角色|模块|类型|URL|方法|IP|地区|结果|操作(详情)
</div>
<div style="display:flex;justify-content:flex-end;margin-top:10px">
<div class="placeholder" style="width:260px;height:34px">分页:pageNum / pageSize / total</div>
</div>
</div>
</div>
</div>
<div class="options">
<div class="option" data-choice="ok" onclick="toggleSelect(this)">
<div class="letter">A</div>
<div class="content">
<h3>就按这个布局做</h3>
<p>如果你更偏向现有 `support/operate-log` 的样式,我也可以完全复用那一套组件结构。</p>
</div>
</div>
<div class="option" data-choice="adjust" onclick="toggleSelect(this)">
<div class="letter">B</div>
<div class="content">
<h3>需要调整筛选项/列</h3>
<p>你告诉我必须要的筛选与列,我按你的习惯改到位。</p>
</div>
</div>
</div>

1
.superpowers/brainstorm/62699-1778123142/state/server-stopped

@ -0,0 +1 @@
{"reason":"idle timeout","timestamp":1778125002586}

3
.superpowers/brainstorm/62699-1778123142/state/server.log

@ -0,0 +1,3 @@
{"type":"server-started","port":56120,"host":"127.0.0.1","url_host":"localhost","url":"http://localhost:56120","screen_dir":"/Users/wang/sanduoyun/developspace/smart-flow-master/.superpowers/brainstorm/62699-1778123142/content","state_dir":"/Users/wang/sanduoyun/developspace/smart-flow-master/.superpowers/brainstorm/62699-1778123142/state"}
{"type":"screen-added","file":"/Users/wang/sanduoyun/developspace/smart-flow-master/.superpowers/brainstorm/62699-1778123142/content/operate-log-page-layout.html"}
{"type":"server-stopped","reason":"idle timeout"}

1
.superpowers/brainstorm/62699-1778123142/state/server.pid

@ -0,0 +1 @@
62708

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 1024-lab
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

BIN
docs/.DS_Store

Binary file not shown.

8825
logs/sa-admin/dev/debug/debug.log

File diff suppressed because it is too large

425
logs/sa-admin/dev/error/error.log

@ -0,0 +1,425 @@
[2026-06-02 18:55:20,327][ERROR][http-nio-1024-exec-6] 解析ip地址出错 (SmartIpUtil.java:80)
java.lang.NullPointerException: Cannot invoke "org.lionsoul.ip2region.xdb.Searcher.search(String)" because "net.lab1024.sa.base.common.util.SmartIpUtil.IP_SEARCHER" is null
at net.lab1024.sa.base.common.util.SmartIpUtil.getRegion(SmartIpUtil.java:78) ~[classes/:?]
at net.lab1024.sa.admin.module.system.login.service.LoginService.saveLoginLog(LoginService.java:427) ~[classes/:?]
at net.lab1024.sa.admin.module.system.login.service.LoginService.login(LoginService.java:237) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at com.alibaba.druid.support.spring.stat.DruidStatInterceptor.invoke(DruidStatInterceptor.java:70) ~[druid-1.2.23.jar:?]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.admin.module.system.login.service.LoginService$$SpringCGLIB$$1.login(<generated>) ~[classes/:?]
at net.lab1024.sa.admin.module.system.login.controller.LoginController.login(LoginController.java:45) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:89) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.aroundController(OperateLogAspect.java:100) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.admin.module.system.login.controller.LoginController$$SpringCGLIB$$0.login(<generated>) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:73) ~[druid-1.2.23.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet.doFilter(SaFirewallCheckFilterForJakartaServlet.java:68) ~[sa-token-spring-boot3-starter-1.41.0.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:107) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
[2026-06-02 18:55:20,407][ERROR][http-nio-1024-exec-6] 解析ip地址出错 (SmartIpUtil.java:80)
java.lang.NullPointerException: Cannot invoke "org.lionsoul.ip2region.xdb.Searcher.search(String)" because "net.lab1024.sa.base.common.util.SmartIpUtil.IP_SEARCHER" is null
at net.lab1024.sa.base.common.util.SmartIpUtil.getRegion(SmartIpUtil.java:78) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.enqueueLog(OperateLogAspect.java:233) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.aroundController(OperateLogAspect.java:107) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.admin.module.system.login.controller.LoginController$$SpringCGLIB$$0.login(<generated>) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:73) ~[druid-1.2.23.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet.doFilter(SaFirewallCheckFilterForJakartaServlet.java:68) ~[sa-token-spring-boot3-starter-1.41.0.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:107) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
[2026-06-02 18:55:20,858][ERROR][http-nio-1024-exec-2] 解析ip地址出错 (SmartIpUtil.java:80)
java.lang.NullPointerException: Cannot invoke "org.lionsoul.ip2region.xdb.Searcher.search(String)" because "net.lab1024.sa.base.common.util.SmartIpUtil.IP_SEARCHER" is null
at net.lab1024.sa.base.common.util.SmartIpUtil.getRegion(SmartIpUtil.java:78) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.enqueueLog(OperateLogAspect.java:233) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.aroundController(OperateLogAspect.java:107) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.base.module.support.changelog.controller.ChangeLogController$$SpringCGLIB$$0.queryPage(<generated>) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:73) ~[druid-1.2.23.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet.doFilter(SaFirewallCheckFilterForJakartaServlet.java:68) ~[sa-token-spring-boot3-starter-1.41.0.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:107) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
[2026-06-02 18:56:04,416][ERROR][http-nio-1024-exec-7] 解析ip地址出错 (SmartIpUtil.java:80)
java.lang.NullPointerException: Cannot invoke "org.lionsoul.ip2region.xdb.Searcher.search(String)" because "net.lab1024.sa.base.common.util.SmartIpUtil.IP_SEARCHER" is null
at net.lab1024.sa.base.common.util.SmartIpUtil.getRegion(SmartIpUtil.java:78) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.enqueueLog(OperateLogAspect.java:233) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.aroundController(OperateLogAspect.java:107) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.admin.module.flow.controller.DefController$$SpringCGLIB$$0.add(<generated>) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:73) ~[druid-1.2.23.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet.doFilter(SaFirewallCheckFilterForJakartaServlet.java:68) ~[sa-token-spring-boot3-starter-1.41.0.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:107) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]
[2026-06-02 18:56:27,871][ERROR][http-nio-1024-exec-9] 解析ip地址出错 (SmartIpUtil.java:80)
java.lang.NullPointerException: Cannot invoke "org.lionsoul.ip2region.xdb.Searcher.search(String)" because "net.lab1024.sa.base.common.util.SmartIpUtil.IP_SEARCHER" is null
at net.lab1024.sa.base.common.util.SmartIpUtil.getRegion(SmartIpUtil.java:78) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.enqueueLog(OperateLogAspect.java:233) ~[classes/:?]
at net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect.aroundController(OperateLogAspect.java:107) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:637) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:627) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:71) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.10.jar:6.1.10]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.10.jar:6.1.10]
at net.lab1024.sa.base.module.support.changelog.controller.ChangeLogController$$SpringCGLIB$$0.queryPage(<generated>) ~[classes/:?]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[?:?]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014) ~[spring-webmvc-6.1.10.jar:6.1.10]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:914) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.1.10.jar:6.1.10]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.25.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:91) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at com.alibaba.druid.support.jakarta.WebStatFilter.doFilter(WebStatFilter.java:73) ~[druid-1.2.23.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at cn.dev33.satoken.filter.SaFirewallCheckFilterForJakartaServlet.doFilter(SaFirewallCheckFilterForJakartaServlet.java:68) ~[sa-token-spring-boot3-starter-1.41.0.jar:?]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.ServerHttpObservationFilter.doFilterInternal(ServerHttpObservationFilter.java:107) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.1.10.jar:6.1.10]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.1.10.jar:6.1.10]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:164) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:140) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:663) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:389) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:904) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) ~[tomcat-embed-core-10.1.25.jar:10.1.25]
at java.base/java.lang.Thread.run(Thread.java:1583) [?:?]

32
logs/sa-admin/dev/info/info.log

@ -0,0 +1,32 @@
[2026-06-02 18:54:57,776][INFO ][background-preinit] HV000001: Hibernate Validator 8.0.1.Final (Version.java:21)
[2026-06-02 18:54:57,850][INFO ][main] Starting AdminApplication using Java 21.0.11 with PID 66984 (/Users/wang/sanduoyun/developspace/smart-flow-master/smart-flow-api/sa-admin/target/classes started by wang in /Users/wang/sanduoyun/developspace/smart-flow-master) (StartupInfoLogger.java:50)
[2026-06-02 18:54:57,853][INFO ][main] The following 1 profile is active: "dev" (SpringApplication.java:660)
[2026-06-02 18:54:59,079][INFO ][main] Multiple Spring Data modules found, entering strict repository configuration mode (RepositoryConfigurationDelegate.java:295)
[2026-06-02 18:54:59,081][INFO ][main] Bootstrapping Spring Data Redis repositories in DEFAULT mode. (RepositoryConfigurationDelegate.java:143)
[2026-06-02 18:54:59,110][INFO ][main] Finished Spring Data repository scanning in 12 ms. Found 0 Redis repository interfaces. (RepositoryConfigurationDelegate.java:211)
[2026-06-02 18:55:00,573][INFO ][main] {dataSource-1} inited (DruidDataSource.java:1002)
[2026-06-02 18:55:01,181][INFO ][main] Tomcat initialized with port 1024 (http) (TomcatWebServer.java:111)
[2026-06-02 18:55:01,188][INFO ][main] Initializing ProtocolHandler ["http-nio-1024"] (DirectJDKLog.java:173)
[2026-06-02 18:55:01,189][INFO ][main] Starting service [Tomcat] (DirectJDKLog.java:173)
[2026-06-02 18:55:01,189][INFO ][main] Starting Servlet engine: [Apache Tomcat/10.1.25] (DirectJDKLog.java:173)
[2026-06-02 18:55:01,226][INFO ][main] Initializing Spring embedded WebApplicationContext (DirectJDKLog.java:173)
[2026-06-02 18:55:01,226][INFO ][main] Root WebApplicationContext: initialization completed in 3328 ms (ServletWebServerApplicationContext.java:296)
[2026-06-02 18:55:01,736][INFO ][main] ################# 系统配置缓存初始化完毕:2 ################### (ConfigService.java:58)
[2026-06-02 18:55:02,021][INFO ][main] Redisson 3.25.0 (Version.java:43)
[2026-06-02 18:55:02,144][INFO ][redisson-netty-2-5] 1 connections initialized for 127.0.0.1/127.0.0.1:6379 (ConnectionPool.java:137)
[2026-06-02 18:55:02,185][INFO ][redisson-netty-2-19] 24 connections initialized for 127.0.0.1/127.0.0.1:6379 (ConnectionPool.java:137)
[2026-06-02 18:55:03,293][INFO ][main] ==== SmartJob ==== client-manager init (SmartJobClientManager.java:67)
[2026-06-02 18:55:03,584][INFO ][main] 不需要登录的URL:[/login, /login/sendEmailCode/{loginName}, /login/getTwoFactorLoginFlag, /login/getCaptcha] (UrlConfig.java:134)
[2026-06-02 18:55:03,891][INFO ][main] 【warm-flow】,加载完成 (BeanConfig.java:152)
[2026-06-02 18:55:04,326][INFO ][main] Exposing 1 endpoint beneath base path '/actuator' (EndpointLinksResolver.java:60)
[2026-06-02 18:55:04,399][INFO ][main] Starting ProtocolHandler ["http-nio-1024"] (DirectJDKLog.java:173)
[2026-06-02 18:55:04,403][INFO ][main] Tomcat started on port 1024 (http) with context path '/' (TomcatWebServer.java:243)
[2026-06-02 18:55:04,419][INFO ][main] Started AdminApplication in 7.041 seconds (process running for 8.728) (StartupInfoLogger.java:56)
[2026-06-02 18:55:04,535][INFO ][RMI TCP Connection(3)-127.0.0.1] Initializing Spring DispatcherServlet 'dispatcherServlet' (DirectJDKLog.java:173)
[2026-06-02 18:55:04,535][INFO ][RMI TCP Connection(3)-127.0.0.1] Initializing Servlet 'dispatcherServlet' (FrameworkServlet.java:532)
[2026-06-02 18:55:04,536][INFO ][RMI TCP Connection(3)-127.0.0.1] Completed initialization in 1 ms (FrameworkServlet.java:554)
[2026-06-02 18:55:13,355][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:84)
[2026-06-02 18:56:13,428][INFO ][SmartJobLauncher-0] ==== SmartJob ==== job list empty (SmartJobLauncher.java:84)
[2026-06-02 18:56:47,505][INFO ][SpringApplicationShutdownHook] ==== SmartJob ==== destroy job (SmartJobLauncher.java:151)
[2026-06-02 18:56:47,516][INFO ][SpringApplicationShutdownHook] {dataSource-1} closing ... (DruidDataSource.java:2204)
[2026-06-02 18:56:47,518][INFO ][SpringApplicationShutdownHook] {dataSource-1} closed (DruidDataSource.java:2277)

2
logs/sa-admin/dev/slow-sql/slow-sql.log

@ -0,0 +1,2 @@
[2026-05-15 16:16:09,470][ERROR][smart-heart-beat] slow sql 1447 millis. select * from t_heart_beat_record where project_path = ? and server_ip = ? and process_no =? ["/Users/wang/sanduoyun/developspace/smart-flow-master","198.18.0.1;172.20.10.11;127.0.0.1",50714] (StatFilter.java:518)
[2026-05-15 17:51:47,396][ERROR][smart-reload] slow sql 2133 millis. SELECT tag,args,identification,update_time,create_time FROM t_reload_item [] (StatFilter.java:518)

103
logs/sa-admin/dev/tomcat-logs/logs/access_log.2026-06-02.log

@ -0,0 +1,103 @@
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 OPTIONS /login/getLoginInfo HTTP/1.1 200 (33561 ms) http-nio-1024-exec-1 (0 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 GET /login/getLoginInfo HTTP/1.1 200 (36716 ms) http-nio-1024-exec-1 (124 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/0 HTTP/1.1 200 (1125 ms) http-nio-1024-exec-2 (0 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 OPTIONS /oa/notice/employee/query HTTP/1.1 200 (931 ms) http-nio-1024-exec-3 (0 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 OPTIONS /oa/notice/employee/query HTTP/1.1 200 (1093 ms) http-nio-1024-exec-4 (0 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 OPTIONS /support/changeLog/queryPage HTTP/1.1 200 (1020 ms) http-nio-1024-exec-6 (0 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 OPTIONS /support/feedback/query HTTP/1.1 200 (1252 ms) http-nio-1024-exec-5 (0 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 POST /oa/notice/employee/query HTTP/1.1 200 (11817 ms) http-nio-1024-exec-5 (124 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 POST /support/changeLog/queryPage HTTP/1.1 200 (11223 ms) http-nio-1024-exec-10 (124 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 POST /support/feedback/query HTTP/1.1 200 (11884 ms) http-nio-1024-exec-1 (124 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 POST /oa/notice/employee/query HTTP/1.1 200 (12371 ms) http-nio-1024-exec-9 (124 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/0 HTTP/1.1 200 (18045 ms) http-nio-1024-exec-8 (124 byte)
[02/Jun/2026:18:55:08 +0800] - 127.0.0.1 GET /login/getTwoFactorLoginFlag HTTP/1.1 200 (56754 ms) http-nio-1024-exec-2 (91 byte)
[02/Jun/2026:18:55:09 +0800] - 127.0.0.1 GET /login/getCaptcha HTTP/1.1 200 (642008 ms) http-nio-1024-exec-3 (4043 byte)
[02/Jun/2026:18:55:19 +0800] - 127.0.0.1 OPTIONS /login HTTP/1.1 200 (1155 ms) http-nio-1024-exec-4 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 POST /login HTTP/1.1 200 (1098225 ms) http-nio-1024-exec-6 (57493 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /support/dict/getAllDictData HTTP/1.1 200 (581 ms) http-nio-1024-exec-5 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /support/message/getUnreadCount HTTP/1.1 200 (610 ms) http-nio-1024-exec-7 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 GET /support/message/getUnreadCount HTTP/1.1 200 (56566 ms) http-nio-1024-exec-1 (87 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 GET /support/dict/getAllDictData HTTP/1.1 200 (96085 ms) http-nio-1024-exec-10 (1570 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/0 HTTP/1.1 200 (2259 ms) http-nio-1024-exec-8 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /oa/notice/employee/query HTTP/1.1 200 (3373 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /support/feedback/query HTTP/1.1 200 (949 ms) http-nio-1024-exec-4 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /oa/notice/employee/query HTTP/1.1 200 (1076 ms) http-nio-1024-exec-3 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 OPTIONS /support/changeLog/queryPage HTTP/1.1 200 (2471 ms) http-nio-1024-exec-2 (0 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/0 HTTP/1.1 200 (70447 ms) http-nio-1024-exec-4 (88 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 POST /support/changeLog/queryPage HTTP/1.1 200 (178257 ms) http-nio-1024-exec-2 (159 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 POST /support/feedback/query HTTP/1.1 200 (180456 ms) http-nio-1024-exec-7 (160 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 POST /oa/notice/employee/query HTTP/1.1 200 (233612 ms) http-nio-1024-exec-6 (159 byte)
[02/Jun/2026:18:55:20 +0800] - 127.0.0.1 POST /oa/notice/employee/query HTTP/1.1 200 (233414 ms) http-nio-1024-exec-1 (159 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 OPTIONS /support/tableColumn/getColumns/30001 HTTP/1.1 200 (803 ms) http-nio-1024-exec-3 (0 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 OPTIONS /support/tableColumn/getColumns/30001 HTTP/1.1 200 (872 ms) http-nio-1024-exec-10 (0 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/132 HTTP/1.1 200 (859 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 OPTIONS /oa/notice/query HTTP/1.1 200 (827 ms) http-nio-1024-exec-8 (0 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 OPTIONS /oa/noticeType/getAll HTTP/1.1 200 (726 ms) http-nio-1024-exec-5 (0 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/132 HTTP/1.1 200 (50806 ms) http-nio-1024-exec-6 (88 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 GET /oa/noticeType/getAll HTTP/1.1 200 (52185 ms) http-nio-1024-exec-2 (88 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/30001 HTTP/1.1 200 (58510 ms) http-nio-1024-exec-4 (90 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 POST /oa/notice/query HTTP/1.1 200 (95796 ms) http-nio-1024-exec-7 (160 byte)
[02/Jun/2026:18:55:32 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/30001 HTTP/1.1 200 (49720 ms) http-nio-1024-exec-1 (90 byte)
[02/Jun/2026:18:55:33 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/257 HTTP/1.1 200 (600 ms) http-nio-1024-exec-3 (0 byte)
[02/Jun/2026:18:55:33 +0800] - 127.0.0.1 OPTIONS /leave/queryPage HTTP/1.1 200 (600 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:55:33 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/257 HTTP/1.1 200 (79931 ms) http-nio-1024-exec-8 (88 byte)
[02/Jun/2026:18:55:33 +0800] - 127.0.0.1 POST /leave/queryPage HTTP/1.1 200 (82516 ms) http-nio-1024-exec-10 (160 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/253 HTTP/1.1 200 (678 ms) http-nio-1024-exec-2 (0 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 OPTIONS /flow/definition/queryPage HTTP/1.1 200 (766 ms) http-nio-1024-exec-6 (0 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 OPTIONS /support/tableColumn/getColumns/10001 HTTP/1.1 200 (743 ms) http-nio-1024-exec-5 (0 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 OPTIONS /support/tableColumn/getColumns/10001 HTTP/1.1 200 (687 ms) http-nio-1024-exec-4 (0 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/10001 HTTP/1.1 200 (84075 ms) http-nio-1024-exec-7 (90 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/253 HTTP/1.1 200 (87686 ms) http-nio-1024-exec-1 (88 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 POST /flow/definition/queryPage HTTP/1.1 200 (100290 ms) http-nio-1024-exec-3 (160 byte)
[02/Jun/2026:18:55:39 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/10001 HTTP/1.1 200 (56289 ms) http-nio-1024-exec-7 (90 byte)
[02/Jun/2026:18:55:46 +0800] - 127.0.0.1 OPTIONS /flow/execute/toDoPage?pageNum=1&pageSize=10 HTTP/1.1 200 (743 ms) http-nio-1024-exec-8 (0 byte)
[02/Jun/2026:18:55:46 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/254 HTTP/1.1 200 (898 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:55:46 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/254 HTTP/1.1 200 (57345 ms) http-nio-1024-exec-5 (88 byte)
[02/Jun/2026:18:55:46 +0800] - 127.0.0.1 GET /flow/execute/toDoPage?pageNum=1&pageSize=10 HTTP/1.1 200 (280605 ms) http-nio-1024-exec-10 (160 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/253 HTTP/1.1 200 (1449 ms) http-nio-1024-exec-2 (0 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 OPTIONS /support/tableColumn/getColumns/10001 HTTP/1.1 200 (1400 ms) http-nio-1024-exec-1 (0 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 OPTIONS /flow/definition/queryPage HTTP/1.1 200 (1443 ms) http-nio-1024-exec-6 (0 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 OPTIONS /support/tableColumn/getColumns/10001 HTTP/1.1 200 (1449 ms) http-nio-1024-exec-4 (0 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/253 HTTP/1.1 200 (57837 ms) http-nio-1024-exec-7 (88 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/10001 HTTP/1.1 200 (68804 ms) http-nio-1024-exec-8 (90 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 POST /flow/definition/queryPage HTTP/1.1 200 (68877 ms) http-nio-1024-exec-3 (160 byte)
[02/Jun/2026:18:55:53 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/10001 HTTP/1.1 200 (70754 ms) http-nio-1024-exec-9 (90 byte)
[02/Jun/2026:18:55:54 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/254 HTTP/1.1 200 (914 ms) http-nio-1024-exec-5 (0 byte)
[02/Jun/2026:18:55:54 +0800] - 127.0.0.1 OPTIONS /flow/execute/toDoPage?pageNum=1&pageSize=10 HTTP/1.1 200 (914 ms) http-nio-1024-exec-10 (0 byte)
[02/Jun/2026:18:55:54 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/254 HTTP/1.1 200 (90798 ms) http-nio-1024-exec-6 (88 byte)
[02/Jun/2026:18:55:54 +0800] - 127.0.0.1 GET /flow/execute/toDoPage?pageNum=1&pageSize=10 HTTP/1.1 200 (313977 ms) http-nio-1024-exec-2 (160 byte)
[02/Jun/2026:18:55:55 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/255 HTTP/1.1 200 (928 ms) http-nio-1024-exec-1 (0 byte)
[02/Jun/2026:18:55:55 +0800] - 127.0.0.1 OPTIONS /flow/execute/donePage?pageNum=1&pageSize=10 HTTP/1.1 200 (928 ms) http-nio-1024-exec-4 (0 byte)
[02/Jun/2026:18:55:55 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/255 HTTP/1.1 200 (59595 ms) http-nio-1024-exec-8 (88 byte)
[02/Jun/2026:18:55:55 +0800] - 127.0.0.1 GET /flow/execute/donePage?pageNum=1&pageSize=10 HTTP/1.1 200 (315290 ms) http-nio-1024-exec-7 (160 byte)
[02/Jun/2026:18:55:56 +0800] - 127.0.0.1 OPTIONS /flow/execute/copyPage?pageNum=1&pageSize=10 HTTP/1.1 200 (972 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:55:56 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/256 HTTP/1.1 200 (972 ms) http-nio-1024-exec-3 (0 byte)
[02/Jun/2026:18:55:56 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/256 HTTP/1.1 200 (68533 ms) http-nio-1024-exec-10 (88 byte)
[02/Jun/2026:18:55:56 +0800] - 127.0.0.1 GET /flow/execute/copyPage?pageNum=1&pageSize=10 HTTP/1.1 200 (248546 ms) http-nio-1024-exec-5 (160 byte)
[02/Jun/2026:18:55:57 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/253 HTTP/1.1 200 (75474 ms) http-nio-1024-exec-1 (88 byte)
[02/Jun/2026:18:55:57 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/10001 HTTP/1.1 200 (77439 ms) http-nio-1024-exec-6 (90 byte)
[02/Jun/2026:18:55:57 +0800] - 127.0.0.1 POST /flow/definition/queryPage HTTP/1.1 200 (84910 ms) http-nio-1024-exec-2 (160 byte)
[02/Jun/2026:18:55:57 +0800] - 127.0.0.1 GET /support/tableColumn/getColumns/10001 HTTP/1.1 200 (67450 ms) http-nio-1024-exec-4 (90 byte)
[02/Jun/2026:18:56:03 +0800] - 127.0.0.1 OPTIONS /flow/definition/add HTTP/1.1 200 (1770 ms) http-nio-1024-exec-8 (0 byte)
[02/Jun/2026:18:56:04 +0800] - 127.0.0.1 POST /flow/definition/add HTTP/1.1 200 (591842 ms) http-nio-1024-exec-7 (90 byte)
[02/Jun/2026:18:56:04 +0800] - 127.0.0.1 OPTIONS /flow/definition/queryPage HTTP/1.1 200 (1749 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:56:04 +0800] - 127.0.0.1 POST /flow/definition/queryPage HTTP/1.1 200 (145708 ms) http-nio-1024-exec-3 (465 byte)
[02/Jun/2026:18:56:08 +0800] - 127.0.0.1 GET /warm-flow-ui/index.html?id=2061763773549461506&disabled=false&Authorization=Bearer%20769d485013454588bae0683951df166e HTTP/1.1 200 (7228 ms) http-nio-1024-exec-10 (5765 byte)
[02/Jun/2026:18:56:08 +0800] - 127.0.0.1 GET /warm-flow-ui/css/index-Da60mrLX.css HTTP/1.1 200 (6007 ms) http-nio-1024-exec-1 (378939 byte)
[02/Jun/2026:18:56:08 +0800] - 127.0.0.1 GET /warm-flow-ui/js/index-Bfpt7KC4.js HTTP/1.1 200 (28252 ms) http-nio-1024-exec-5 (2923865 byte)
[02/Jun/2026:18:56:08 +0800] - 127.0.0.1 GET /warm-flow-ui/config HTTP/1.1 200 (14453 ms) http-nio-1024-exec-6 (87 byte)
[02/Jun/2026:18:56:08 +0800] - 127.0.0.1 GET /warm-flow/query-def/2061763773549461506 HTTP/1.1 200 (172483 ms) http-nio-1024-exec-2 (2058 byte)
[02/Jun/2026:18:56:11 +0800] - 127.0.0.1 GET /warm-flow/handler-feedback HTTP/1.1 200 (4043 ms) http-nio-1024-exec-8 (54 byte)
[02/Jun/2026:18:56:11 +0800] - 127.0.0.1 GET /warm-flow/node-ext HTTP/1.1 200 (5785 ms) http-nio-1024-exec-4 (934 byte)
[02/Jun/2026:18:56:23 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/256 HTTP/1.1 200 (1103 ms) http-nio-1024-exec-7 (0 byte)
[02/Jun/2026:18:56:23 +0800] - 127.0.0.1 OPTIONS /flow/execute/copyPage?pageNum=1&pageSize=10 HTTP/1.1 200 (1103 ms) http-nio-1024-exec-9 (0 byte)
[02/Jun/2026:18:56:23 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/256 HTTP/1.1 200 (70857 ms) http-nio-1024-exec-10 (88 byte)
[02/Jun/2026:18:56:23 +0800] - 127.0.0.1 GET /flow/execute/copyPage?pageNum=1&pageSize=10 HTTP/1.1 200 (221223 ms) http-nio-1024-exec-3 (160 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 OPTIONS /oa/notice/employee/query HTTP/1.1 200 (526 ms) http-nio-1024-exec-6 (0 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 OPTIONS /support/helpDoc/queryHelpDocByRelationId/0 HTTP/1.1 200 (839 ms) http-nio-1024-exec-5 (0 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 OPTIONS /oa/notice/employee/query HTTP/1.1 200 (1537 ms) http-nio-1024-exec-1 (0 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 OPTIONS /support/changeLog/queryPage HTTP/1.1 200 (1546 ms) http-nio-1024-exec-2 (0 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 GET /support/helpDoc/queryHelpDocByRelationId/0 HTTP/1.1 200 (69491 ms) http-nio-1024-exec-4 (88 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 POST /support/changeLog/queryPage HTTP/1.1 200 (73561 ms) http-nio-1024-exec-9 (159 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 POST /oa/notice/employee/query HTTP/1.1 200 (118811 ms) http-nio-1024-exec-8 (159 byte)
[02/Jun/2026:18:56:27 +0800] - 127.0.0.1 POST /oa/notice/employee/query HTTP/1.1 200 (132858 ms) http-nio-1024-exec-2 (159 byte)

34
logs/sa-admin/dev/warn/warn.log

@ -0,0 +1,34 @@
[2026-06-02 18:54:59,550][WARN ][main] Bean 'mybatisPlusConfig' of type [net.lab1024.sa.base.config.MybatisPlusConfig$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:54:59,556][WARN ][main] Bean 'paginationInterceptor' of type [com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:54:59,559][WARN ][main] Bean 'myBatisPlugin' of type [net.lab1024.sa.admin.module.system.datascope.MyBatisPlugin] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:54:59,563][WARN ][main] Bean 'dataSourceConfig' of type [net.lab1024.sa.base.config.DataSourceConfig$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:54:59,565][WARN ][main] Bean 'jdkRegexpMethodPointcut' of type [org.springframework.aop.support.JdkRegexpMethodPointcut] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:54:59,567][WARN ][main] Bean 'defaultPointcutAdvisor' of type [org.springframework.aop.support.DefaultPointcutAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,576][WARN ][main] Bean 'druidDataSource' of type [com.alibaba.druid.pool.DruidDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,912][WARN ][main] [net.lab1024.sa.base.module.support.operatelog.OperateLogDao.deleteByIds] Has been loaded by XML or SqlProvider or Mybatis's Annotation, so ignoring this injection for [class com.baomidou.mybatisplus.core.injector.methods.DeleteByIds] (AbstractMethod.java:407)
[2026-06-02 18:55:00,956][WARN ][main] Bean 'sqlSessionFactory' of type [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,958][WARN ][main] Bean 'org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration' of type [org.springframework.boot.autoconfigure.sql.init.DataSourceInitializationConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,964][WARN ][main] Bean 'spring.sql.init-org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties' of type [org.springframework.boot.autoconfigure.sql.init.SqlInitializationProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,967][WARN ][main] Bean 'dataSourceScriptDatabaseInitializer' of type [org.springframework.boot.autoconfigure.sql.init.SqlDataSourceScriptDatabaseInitializer] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,971][WARN ][main] Bean 'mybatis-plus-com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties' of type [com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,976][WARN ][main] Bean 'mybatisDatabaseIdProviderConfig' of type [net.lab1024.sa.base.config.MybatisDatabaseIdProviderConfig$$SpringCGLIB$$0] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,976][WARN ][main] Bean 'databaseIdProvider' of type [org.apache.ibatis.mapping.VendorDatabaseIdProvider] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,979][WARN ][main] Bean 'com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration' of type [com.baomidou.mybatisplus.autoconfigure.MybatisPlusAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,983][WARN ][main] Bean 'sqlSessionTemplate' of type [org.mybatis.spring.SqlSessionTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,985][WARN ][main] Bean 'reloadItemDao' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,989][WARN ][main] Bean 'reloadItemDao' of type [jdk.proxy2.$Proxy131] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,998][WARN ][main] Bean 'reloadResultDao' of type [org.mybatis.spring.mapper.MapperFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:00,999][WARN ][main] Bean 'reloadResultDao' of type [jdk.proxy2.$Proxy133] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:01,008][WARN ][main] Bean 'reloadCommand' of type [net.lab1024.sa.base.module.support.reload.ReloadCommand] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [smartReloadManager]? Check the corresponding BeanPostProcessor declaration and its dependencies. (PostProcessorRegistrationDelegate.java:437)
[2026-06-02 18:55:02,045][WARN ][main] Can not find io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider in the classpath, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. Check whether you have a dependency on 'io.netty:netty-resolver-dns-native-macos' (DnsServerAddressStreamProviders.java:70)
[2026-06-02 18:55:04,288][WARN ][main] Cannot find template location: [classpath:/templates/] (please add some templates, check your FreeMarker configuration, or set spring.freemarker.check-template-location=false) (FreeMarkerAutoConfiguration.java:66)
[2026-06-02 18:55:04,408][WARN ][main]
-------------【sa-admin】 服务已成功启动 (sa-admin started successfully)-------------
当前启动环境: dev , 开发环境
返回码初始化: 完成15个返回码初始化
服务本机地址: http://localhost:1024/
服务外网地址: http://198.18.0.1:1024/
Swagger地址: http://localhost:1024/swagger-ui/index.html
knife4j地址: http://localhost:1024/doc.html
-------------------------------------------------------------------------------------
(WebServerListener.java:66)

465
smart-flow-api/pom.xml

@ -0,0 +1,465 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.lab1024</groupId>
<artifactId>sa-parent</artifactId>
<version>3.0.1</version>
<packaging>pom</packaging>
<name>sa-parent</name>
<description>SmartFlow project</description>
<modules>
<module>sa-base</module>
<module>sa-admin</module>
</modules>
<properties>
<java.version>21</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<springboot.version>3.3.1</springboot.version>
<spring-mock.version>2.0.8</spring-mock.version>
<spring-security-crypto.version>6.4.3</spring-security-crypto.version>
<mysql.version>8.3.0</mysql.version>
<kingbase8.version>8.6.0</kingbase8.version>
<mybatis-plus.version>3.5.7</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version>
<knife4j.version>4.4.0</knife4j.version>
<fastjson.version>2.0.52</fastjson.version>
<druid.version>1.2.23</druid.version>
<google-linkedhashmap.version>1.4.2</google-linkedhashmap.version>
<google-guava.version>20.0</google-guava.version>
<user-agent-utils.version>1.21</user-agent-utils.version>
<reflections.version>0.9.11</reflections.version>
<commons-io.version>2.15.0</commons-io.version>
<commons-lang3.version>3.12.0</commons-lang3.version>
<commons-collections4.version>4.4</commons-collections4.version>
<commons-compress.version>1.26.0</commons-compress.version>
<commons-codec.version>1.13</commons-codec.version>
<commons-text.version>1.9</commons-text.version>
<xerces.version>2.12.0</xerces.version>
<fast-excel.version>1.0.0</fast-excel.version>
<poi.version>5.2.4</poi.version>
<ooxml-schemas.version>1.4</ooxml-schemas.version>
<aws-java-sdk.version>1.11.842</aws-java-sdk.version>
<log4j-spring-boot.version>2.23.1</log4j-spring-boot.version>
<hutool.version>5.8.29</hutool.version>
<velocity-engine-core.version>2.3</velocity-engine-core.version>
<jjwt.version>0.9.1</jjwt.version>
<jwks-rsa.version>0.9.0</jwks-rsa.version>
<velocity-tools.version>3.1</velocity-tools.version>
<sa-token.version>1.41.0</sa-token.version>
<warm-flow.version>1.7.3</warm-flow.version>
<ip2region.version>2.7.0</ip2region.version>
<bcprov.version>1.80</bcprov.version>
<jackson-datatype-jsr310.version>2.13.4</jackson-datatype-jsr310.version>
<jackson-dataformat-yaml.version>2.16.1</jackson-dataformat-yaml.version>
<smartdb.version>1.2.0</smartdb.version>
<redisson.version>3.25.0</redisson.version>
<snakeyaml.version>2.2</snakeyaml.version>
<freemarker.version>2.3.33</freemarker.version>
<jsoup.version>1.18.1</jsoup.version>
<tika.version>3.1.0</tika.version>
</properties>
<dependencyManagement>
<dependencies>
<!--BOM begin-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--BOM end-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 人大金仓 JDBC -->
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>${kingbase8.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatis-plus.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>${spring-security-crypto.version}</version>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>${p6spy.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.googlecode.concurrentlinkedhashmap</groupId>
<artifactId>concurrentlinkedhashmap-lru</artifactId>
<version>${google-linkedhashmap.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google-guava.version}</version>
</dependency>
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>${user-agent-utils.version}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>${commons-collections4.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
</dependency>
<dependency>
<artifactId>commons-codec</artifactId>
<groupId>commons-codec</groupId>
<version>${commons-codec.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>${aws-java-sdk.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>${commons-text.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>jwks-rsa</artifactId>
<version>${jwks-rsa.version}</version>
</dependency>
<!--velocity begin-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity-engine-core.version}</version>
</dependency>
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools-generic</artifactId>
<version>${velocity-tools.version}</version>
</dependency>
<!--velocity end-->
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 Redis (使用 jackson 序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- sa-token end -->
<!-- warm-flow-mybatis-plus-sb3-starter -->
<dependency>
<groupId>org.dromara.warm</groupId>
<artifactId>warm-flow-mybatis-plus-sb3-starter</artifactId>
<version>${warm-flow.version}</version>
</dependency>
<dependency>
<groupId>org.dromara.warm</groupId>
<artifactId>warm-flow-plugin-ui-sb-web</artifactId>
<version>${warm-flow.version}</version>
</dependency>
<dependency>
<groupId>org.dromara.warm</groupId>
<artifactId>warm-flow-mybatis-plus-core</artifactId>
<version>${warm-flow.version}</version>
</dependency>
<!-- warm-flow-mybatis-plus-sb3-starter end -->
<!--ip 地址-->
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>${ip2region.version}</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk18on</artifactId>
<version>${bcprov.version}</version>
</dependency>
<dependency>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>${fast-excel.version}</version>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>${ooxml-schemas.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson-datatype-jsr310.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson-dataformat-yaml.version}</version>
</dependency>
<dependency>
<groupId>net.1024lab</groupId>
<artifactId>smartdb</artifactId>
<version>${smartdb.version}</version>
</dependency>
<!-- redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>${tika.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.name}-${profiles.active}-${project.version}</finalName>
<resources>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<excludes>
<exclude>dev/*</exclude>
<exclude>test/*</exclude>
<exclude>pre/*</exclude>
<exclude>prod/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/${profiles.active}</directory>
<filtering>true</filtering>
<includes>
<include>*.yaml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources/${profiles.active}</directory>
<filtering>false</filtering>
<includes>
<include>*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<compilerArgument>-parameters</compilerArgument>
<source>21</source>
<target>21</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
</plugin>
</plugins>
</build>
<profiles>
<!--开发环境-->
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--测试环境-->
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
<!--预发布环境-->
<profile>
<id>pre</id>
<properties>
<profiles.active>pre</profiles.active>
</properties>
</profile>
<!--生产环境-->
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
</profile>
</profiles>
</project>

67
smart-flow-api/sa-admin/pom.xml

@ -0,0 +1,67 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>net.lab1024</groupId>
<artifactId>sa-parent</artifactId>
<version>3.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>sa-admin</artifactId>
<version>3.0.1</version>
<packaging>jar</packaging>
<name>sa-admin</name>
<description>sa-admin project</description>
<dependencies>
<dependency>
<groupId>net.lab1024</groupId>
<artifactId>sa-base</artifactId>
<version>${project.version}</version>
</dependency>
<!-- sa-admin 源码直接使用 MP / MyBatis / warm-flow 类型;显式加入编译 classpath,避免 IDEA 未展开 sa-base 传递依赖时报「程序包不存在」 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.warm</groupId>
<artifactId>warm-flow-mybatis-plus-core</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.warm</groupId>
<artifactId>warm-flow-mybatis-plus-sb3-starter</artifactId>
</dependency>
<dependency>
<groupId>org.dromara.warm</groupId>
<artifactId>warm-flow-plugin-ui-sb-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>net.lab1024.sa.admin.AdminApplication</mainClass>
<!-- 将 sa-base 中 system 作用域的 kingbase8.jar 打进可执行包,否则运行期 ClassNotFound -->
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

37
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/AdminApplication.java

@ -0,0 +1,37 @@
package net.lab1024.sa.admin;
import net.lab1024.sa.base.listener.Ip2RegionListener;
import net.lab1024.sa.base.listener.LogVariableListener;
import org.apache.ibatis.annotations.Mapper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* SmartAdmin 项目启动类
*
* @Date 2022-08-29 21:00:58
* @Author wzh
*/
@EnableCaching
@EnableScheduling
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@ComponentScan(AdminApplication.COMPONENT_SCAN)
@MapperScan(value = AdminApplication.COMPONENT_SCAN, annotationClass = Mapper.class)
@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
public class AdminApplication {
public static final String COMPONENT_SCAN = "net.lab1024.sa";
public static void main(String[] args) {
SpringApplication application = new SpringApplication(AdminApplication.class);
// 添加 日志监听器,使 log4j2-spring.xml 可以间接读取到配置文件的属性
application.addListeners(new LogVariableListener(), new Ip2RegionListener());
application.run(args);
}
}

41
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/MvcConfig.java

@ -0,0 +1,41 @@
package net.lab1024.sa.admin.config;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.interceptor.AdminInterceptor;
import net.lab1024.sa.base.config.SwaggerConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* web相关配置
*
* @Date 2021-09-02 20:21:10
* @Author wzh
*/
@Configuration
public class MvcConfig implements WebMvcConfigurer {
@Resource
private AdminInterceptor adminInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(adminInterceptor)
.excludePathPatterns(SwaggerConfig.SWAGGER_WHITELIST)
.addPathPatterns("/**")
// 以上是sa-token案例,下面才是需要排除的地址
.excludePathPatterns("/warm-flow-ui/**", "/warm-flow/**");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/warm-flow-ui/**").addResourceLocations("classpath:/META-INF/resources/warm-flow-ui/");
}
}

43
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java

@ -0,0 +1,43 @@
package net.lab1024.sa.admin.config;
import net.lab1024.sa.base.module.support.operatelog.core.OperateLogAspect;
import net.lab1024.sa.base.module.support.operatelog.core.OperateLogConfig;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
/**
* 操作日志切面 配置
*
* @Date 2022-05-30 21:22:12
* @Author wzh
*/
@Configuration
public class OperateLogAspectConfig extends OperateLogAspect {
/**
* 配置信息
*/
@Override
public OperateLogConfig getOperateLogConfig() {
return OperateLogConfig.builder()
.corePoolSize(1)
.queueCapacity(10000)
.ignoreUrlPatterns(Arrays.asList(
"/support/operateLog/",
"/support/file/upload",
"/support/file/downLoad",
"/support/captcha",
"/support/heartBeat",
"/login/sendEmailCode"
))
.maxParamLength(4000)
.maxResultLength(4000)
.recordResponse(true)
// 先关闭查询类日志(GET / QUERY),避免日志量过大;需要时改为 true
.recordQuery(false)
.build();
}
}

54
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java

@ -0,0 +1,54 @@
package net.lab1024.sa.admin.constant;
import net.lab1024.sa.base.constant.CacheKeyConst;
/**
* 缓存 key
*
* @Date 2022-01-07 18:59:22
* @Author wzh
*/
public class AdminCacheConst extends CacheKeyConst {
public static class Department {
/**
* 部门列表
*/
public static final String DEPARTMENT_LIST_CACHE = "department_list_cache";
/**
* 部门map
*/
public static final String DEPARTMENT_MAP_CACHE = "department_map_cache";
/**
* 部门树
*/
public static final String DEPARTMENT_TREE_CACHE = "department_tree_cache";
/**
* 某个部门以及下级的id列表
*/
public static final String DEPARTMENT_SELF_CHILDREN_CACHE = "department_self_children_cache";
/**
* 部门路径 缓存
*/
public static final String DEPARTMENT_PATH_CACHE = "department_path_cache";
}
/**
* 分类相关缓存
*/
public static class Category {
public static final String CATEGORY_ENTITY = "category_cache";
public static final String CATEGORY_SUB = "category_sub_cache";
public static final String CATEGORY_TREE = "category_tree_cache";
}
}

14
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java

@ -0,0 +1,14 @@
package net.lab1024.sa.admin.constant;
import net.lab1024.sa.base.constant.RedisKeyConst;
/**
* redis key 常量类
*
* @Date 2022-01-07 18:59:22
* @Author wzh
*/
public class AdminRedisKeyConst extends RedisKeyConst {
}

65
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java

@ -0,0 +1,65 @@
package net.lab1024.sa.admin.constant;
import net.lab1024.sa.base.constant.SwaggerTagConst;
/**
* swagger
*
* @Date 2022-01-07 18:59:22
* @Author wzh
*/
public class AdminSwaggerTagConst extends SwaggerTagConst {
public static class Business {
public static final String MANAGER_CATEGORY = "ERP进销存-分类管理";
public static final String MANAGER_GOODS = "ERP进销存-商品管理";
public static final String OA_BANK = "OA办公-银行卡信息";
public static final String OA_ENTERPRISE = "OA办公-企业";
public static final String OA_INVOICE = "OA办公-发票信息";
public static final String OA_NOTICE = "OA办公-通知公告";
}
public static class System {
public static final String SYSTEM_LOGIN = "系统-员工登录";
public static final String SYSTEM_EMPLOYEE = "系统-员工管理";
public static final String SYSTEM_DEPARTMENT = "系统-部门管理";
public static final String SYSTEM_MENU = "系统-菜单";
public static final String SYSTEM_DATA_SCOPE = "系统-系统-数据范围";
public static final String SYSTEM_ROLE = "系统-角色";
public static final String SYSTEM_ROLE_DATA_SCOPE = "系统-角色-数据范围";
public static final String SYSTEM_ROLE_EMPLOYEE = "系统-角色-员工";
public static final String SYSTEM_ROLE_MENU = "系统-角色-菜单";
public static final String SYSTEM_POSITION = "系统-职务管理";
public static final String SYSTEM_MESSAGE = "系统-消息";
}
public static class Flow {
public static final String FLOW_DEFINITION = "工作流-流程定义";
public static final String FLOW_INSTANCE = "工作流-流程实例";
}
}

140
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/interceptor/AdminInterceptor.java

@ -0,0 +1,140 @@
package net.lab1024.sa.admin.interceptor;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.exception.SaTokenException;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.strategy.SaAnnotationStrategy;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.login.service.LoginService;
import net.lab1024.sa.base.common.annoation.NoNeedLogin;
import net.lab1024.sa.base.common.code.SystemErrorCode;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.common.util.SmartResponseUtil;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import java.lang.reflect.Method;
/**
* admin 拦截器
*
* @Date 2023/7/26 20:20:33
* @Author wzh
*/
@Component
@Slf4j
public class AdminInterceptor implements HandlerInterceptor {
@Resource
private LoginService loginService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// OPTIONS请求直接return
if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
response.setStatus(HttpStatus.NO_CONTENT.value());
return false;
}
boolean isHandler = handler instanceof HandlerMethod;
if (!isHandler) {
return true;
}
try {
// --------------- 第一步: 根据token 获取用户 ---------------
String tokenValue = StpUtil.getTokenValue();
String loginId = (String) StpUtil.getLoginIdByToken(tokenValue);
RequestEmployee requestEmployee = loginService.getLoginEmployee(loginId, request);
// --------------- 第二步: 校验 登录 ---------------
Method method = ((HandlerMethod) handler).getMethod();
NoNeedLogin noNeedLogin = ((HandlerMethod) handler).getMethodAnnotation(NoNeedLogin.class);
if (noNeedLogin != null) {
checkActiveTimeout(requestEmployee);
return true;
}
if (requestEmployee == null) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID));
return false;
}
// 检测token 活跃频率
checkActiveTimeout(requestEmployee);
// --------------- 第三步: 校验 权限 ---------------
SmartRequestUtil.setRequestUser(requestEmployee);
if (SaAnnotationStrategy.instance.isAnnotationPresent.apply(method, SaIgnore.class)) {
return true;
}
// 如果是超级管理员的话,不需要校验权限
if (requestEmployee.getAdministratorFlag()) {
return true;
}
SaAnnotationStrategy.instance.checkMethodAnnotation.accept(method);
} catch (SaTokenException e) {
/*
* sa-token 异常状态码
* 具体请看 https://sa-token.cc/doc.html#/fun/exception-code
*/
int code = e.getCode();
if (code == 11041 || code == 11051) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.NO_PERMISSION));
} else if (code == 11016) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_ACTIVE_TIMEOUT));
} else if (code >= 11011 && code <= 11015) {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.LOGIN_STATE_INVALID));
} else {
SmartResponseUtil.write(response, ResponseDTO.error(UserErrorCode.PARAM_ERROR));
}
return false;
} catch (Throwable e) {
SmartResponseUtil.write(response, ResponseDTO.error(SystemErrorCode.SYSTEM_ERROR));
log.error(e.getMessage(), e);
return false;
}
// 通过验证
return true;
}
/**
* 检测token 最低活跃频率单位如果 token 超过此时间没有访问系统就会被冻结
*/
private void checkActiveTimeout(RequestEmployee requestEmployee) {
// 用户不在线,也不用检测
if (requestEmployee == null) {
return;
}
StpUtil.checkActiveTimeout();
StpUtil.updateLastActiveToNow();
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 清除上下文
SmartRequestUtil.remove();
}
}

33
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java

@ -0,0 +1,33 @@
package net.lab1024.sa.admin.module.business.category.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
* 分类类型 枚举
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@AllArgsConstructor
@Getter
public enum CategoryTypeEnum implements BaseEnum {
/**
* 1 商品
*/
GOODS(1, "商品"),
/**
* 2 自定义
*/
CUSTOM(2, "自定义"),
;
private final Integer value;
private final String desc;
}

66
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java

@ -0,0 +1,66 @@
package net.lab1024.sa.admin.module.business.category.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO;
import net.lab1024.sa.admin.module.business.category.service.CategoryService;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 类目
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_CATEGORY)
public class CategoryController {
@Resource
private CategoryService categoryService;
@Operation(summary = "添加类目")
@PostMapping("/category/add")
@SaCheckPermission("category:add")
public ResponseDTO<String> add(@RequestBody @Valid CategoryAddForm addForm) {
return categoryService.add(addForm);
}
@Operation(summary = "更新类目 ")
@PostMapping("/category/update")
@SaCheckPermission("category:update")
public ResponseDTO<String> update(@RequestBody @Valid CategoryUpdateForm updateForm) {
return categoryService.update(updateForm);
}
@Operation(summary = "查询类目详情")
@GetMapping("/category/{categoryId}")
public ResponseDTO<CategoryVO> queryDetail(@PathVariable Long categoryId) {
return categoryService.queryDetail(categoryId);
}
@Operation(summary = "查询类目层级树")
@PostMapping("/category/tree")
@SaCheckPermission("category:tree")
public ResponseDTO<List<CategoryTreeVO>> queryTree(@RequestBody @Valid CategoryTreeQueryForm queryForm) {
return categoryService.queryTree(queryForm);
}
@Operation(summary = "删除类目")
@GetMapping("/category/delete/{categoryId}")
@SaCheckPermission("category:delete")
public ResponseDTO<String> delete(@PathVariable Long categoryId) {
return categoryService.delete(categoryId);
}
}

59
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java

@ -0,0 +1,59 @@
package net.lab1024.sa.admin.module.business.category.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 类目 dao
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Mapper
public interface CategoryDao extends BaseMapper<CategoryEntity> {
/**
* 根据父级id 类型 查询子类
*
* @param parentIdList 父级id集合
* @param deletedFlag 删除标识
* @return 列表
*/
List<CategoryEntity> queryByParentId(@Param("parentIdList") List<Long> parentIdList,
@Param("deletedFlag") Boolean deletedFlag);
/**
* 根据父级id 类型 查询子类
*
* @param parentIdList 父级id集合
* @param categoryType {@link CategoryTypeEnum}
* @param deletedFlag 删除标识
* @return 列表
*/
List<CategoryEntity> queryByParentIdAndType(@Param("parentIdList") List<Long> parentIdList,
@Param("categoryType") Integer categoryType,
@Param("deletedFlag") Boolean deletedFlag);
/**
* 某个类型的所有
*/
List<CategoryEntity> queryByType(@Param("categoryType") Integer categoryType,
@Param("deletedFlag") Boolean deletedFlag);
/**
* 根据类型和id查询
*/
CategoryEntity selectByTypeAndId(@Param("categoryType") Integer categoryType, @Param("categoryId") Long categoryId);
/**
* 查看类目 具体条件 看sql
*/
CategoryEntity selectOne(CategoryEntity entity);
}

43
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java

@ -0,0 +1,43 @@
package net.lab1024.sa.admin.module.business.category.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
* 类目 基础属性 DTO
*
* @author 胡克
* @date 2021/1/20 16:17
*/
@Data
public class CategoryBaseDTO {
@Schema(description = "类目名称", required = true)
@NotBlank(message = "类目名称不能为空")
@Length(max = 20, message = "类目名称最多20字符")
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
@CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误")
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
@Length(max = 200, message = "备注最多200字符")
private String remark;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
}

26
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java

@ -0,0 +1,26 @@
package net.lab1024.sa.admin.module.business.category.domain.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 类目 基础属性 DTO
*
* @author 胡克
* @date 2021/1/20 16:17
*/
@Data
public class CategorySimpleDTO {
@Schema(description = "类目id")
private Long categoryId;
@Schema(description = "类目名称")
private String categoryName;
@Schema(description = "类目层级全称")
private String categoryFullName;
@Schema(description = "父级id")
private Long parentId;
}

67
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java

@ -0,0 +1,67 @@
package net.lab1024.sa.admin.module.business.category.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 类目 实体类
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Data
@TableName("t_category")
public class CategoryEntity implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.AUTO)
private Long categoryId;
/**
* 类目名称
*/
private String categoryName;
/**
* 类目 类型
*
* @see CategoryTypeEnum
*/
private Integer categoryType;
/**
* 父级类目id
*/
private Long parentId;
/**
* 是否禁用
*/
private Boolean disabledFlag;
/**
* 排序
*/
private Integer sort;
/**
* 删除状态
*/
private Boolean deletedFlag;
/**
* 备注
*/
private String remark;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

44
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java

@ -0,0 +1,44 @@
package net.lab1024.sa.admin.module.business.category.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
* 类目 添加
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Data
public class CategoryAddForm {
@Schema(description = "类目名称", required = true)
@NotBlank(message = "类目名称不能为空")
@Length(max = 20, message = "类目名称最多20字符")
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
@CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误")
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
@Length(max = 200, message = "备注最多200字符")
private String remark;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
}

22
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java

@ -0,0 +1,22 @@
package net.lab1024.sa.admin.module.business.category.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
/**
* 类目 层级树查询
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Data
public class CategoryTreeQueryForm {
@SchemaEnum(desc = "分类类型|可选", value = CategoryTypeEnum.class)
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.category.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 类目 更新
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Data
public class CategoryUpdateForm extends CategoryAddForm {
@Schema(description = "类目id")
@NotNull(message = "类目id不能为空")
private Long categoryId;
}

51
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java

@ -0,0 +1,51 @@
package net.lab1024.sa.admin.module.business.category.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.time.LocalDateTime;
import java.util.List;
/**
* 类目
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Data
public class CategoryTreeVO {
@Schema(description = "类目名称", required = true)
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
private String remark;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "类目id")
private Long categoryId;
private LocalDateTime updateTime;
private LocalDateTime createTime;
private String label;
private Long value;
private String categoryFullName;
private List<CategoryTreeVO> children;
}

43
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java

@ -0,0 +1,43 @@
package net.lab1024.sa.admin.module.business.category.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.time.LocalDateTime;
/**
* 类目
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Data
public class CategoryVO {
@Schema(description = "类目名称", required = true)
private String categoryName;
@SchemaEnum(desc = "分类类型", value = CategoryTypeEnum.class)
private Integer categoryType;
@Schema(description = "父级类目id|可选")
private Long parentId;
@Schema(description = "排序|可选")
private Integer sort;
@Schema(description = "备注|可选")
private String remark;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "类目id")
private Long categoryId;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

110
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java

@ -0,0 +1,110 @@
package net.lab1024.sa.admin.module.business.category.manager;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.business.category.dao.CategoryDao;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 类目 查询 缓存
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Service
@Slf4j
public class CategoryCacheManager {
@Resource
private CategoryDao categoryDao;
/**
* 根据类目id 移除缓存
*/
@CacheEvict(value = {AdminCacheConst.Category.CATEGORY_ENTITY, AdminCacheConst.Category.CATEGORY_SUB, AdminCacheConst.Category.CATEGORY_TREE}, allEntries = true)
public void removeCache() {
log.info("clear CATEGORY ,CATEGORY_SUB ,CATEGORY_TREE");
}
/**
* 查詢类目
*
*/
@Cacheable(AdminCacheConst.Category.CATEGORY_ENTITY)
public CategoryEntity queryCategory(Long categoryId) {
return categoryDao.selectById(categoryId);
}
/**
* 查询类目 子级
*
*/
@Cacheable(AdminCacheConst.Category.CATEGORY_SUB)
public List<CategoryEntity> querySubCategory(Long categoryId) {
return categoryDao.queryByParentId(Lists.newArrayList(categoryId), false);
}
/**
* 查询类目 层级树
* 优先查询缓存
*/
@Cacheable(AdminCacheConst.Category.CATEGORY_TREE)
public List<CategoryTreeVO> queryCategoryTree(Long parentId, Integer categoryType) {
List<CategoryEntity> allCategoryEntityList = categoryDao.queryByType(categoryType, false);
List<CategoryEntity> categoryEntityList = allCategoryEntityList.stream().filter(e -> e.getParentId().equals(parentId)).collect(Collectors.toList());
List<CategoryTreeVO> treeList = SmartBeanUtil.copyList(categoryEntityList, CategoryTreeVO.class);
treeList.forEach(e -> {
e.setLabel(e.getCategoryName());
e.setValue(e.getCategoryId());
e.setCategoryFullName(e.getCategoryName());
});
// 递归设置子类
this.queryAndSetSubCategory(treeList, allCategoryEntityList);
return treeList;
}
/**
* 递归查询设置类目子类
* 从缓存查询子类
*
*/
private void queryAndSetSubCategory(List<CategoryTreeVO> treeList, List<CategoryEntity> allCategoryEntityList) {
if (CollectionUtils.isEmpty(treeList)) {
return;
}
List<Long> parentIdList = treeList.stream().map(CategoryTreeVO::getValue).collect(Collectors.toList());
List<CategoryEntity> categoryEntityList = allCategoryEntityList.stream().filter(e -> parentIdList.contains(e.getParentId())).collect(Collectors.toList());
Map<Long, List<CategoryEntity>> categorySubMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getParentId));
treeList.forEach(e -> {
List<CategoryEntity> childrenEntityList = categorySubMap.getOrDefault(e.getValue(), Lists.newArrayList());
List<CategoryTreeVO> childrenVOList = SmartBeanUtil.copyList(childrenEntityList, CategoryTreeVO.class);
childrenVOList.forEach(item -> {
item.setLabel(item.getCategoryName());
item.setValue(item.getCategoryId());
item.setCategoryFullName(e.getCategoryFullName() + StringConst.SEPARATOR_SLASH + item.getCategoryName());
});
// 递归查询
this.queryAndSetSubCategory(childrenVOList, allCategoryEntityList);
e.setChildren(childrenVOList);
});
}
}

185
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java

@ -0,0 +1,185 @@
package net.lab1024.sa.admin.module.business.category.service;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.category.domain.dto.CategorySimpleDTO;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager;
import net.lab1024.sa.base.common.constant.StringConst;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 类目 查询 业务类
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Service
@Slf4j
public class CategoryQueryService {
private static final Long DEFAULT_CATEGORY_PARENT_ID = 0L;
@Resource
private CategoryCacheManager categoryCacheManager;
/**
* 根据 id 查询未删除的类目
*
* @param categoryId
* @return 可能 null
*/
public Optional<CategoryEntity> queryCategory(Long categoryId) {
if (null == categoryId) {
return Optional.empty();
}
CategoryEntity entity = categoryCacheManager.queryCategory(categoryId);
if (null == entity || entity.getDeletedFlag()) {
return Optional.empty();
}
return Optional.of(entity);
}
/**
* 根据 类目id集合 查询未删除的类目集合
*/
public Map<Long, CategoryEntity> queryCategoryList(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return Collections.emptyMap();
}
categoryIdList = categoryIdList.stream().distinct().collect(Collectors.toList());
Map<Long, CategoryEntity> categoryEntityMap = Maps.newHashMap();
for (Long categoryId : categoryIdList) {
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (categoryEntity != null) {
categoryEntityMap.put(categoryId, categoryEntity);
}
}
return categoryEntityMap;
}
/**
* 根据类目id 递归查询该id的所有子类id 递归查询
* 同时存入缓存
* 注意查询出来的集合 不包含传递的父类参数
*/
public List<Long> queryCategorySubId(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return Collections.emptyList();
}
//所有子类
List<CategoryEntity> categoryEntityList = Lists.newArrayList();
categoryIdList.forEach(e -> {
categoryEntityList.addAll(categoryCacheManager.querySubCategory(e));
});
Map<Long, List<CategoryEntity>> subTypeMap = categoryEntityList.stream().collect(Collectors.groupingBy(CategoryEntity::getCategoryId));
// 递归查询子类
categoryIdList = subTypeMap.values().stream().flatMap(Collection::stream).map(CategoryEntity::getCategoryId).distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(categoryIdList)) {
return Lists.newArrayList();
}
categoryIdList.addAll(this.queryCategorySubId(categoryIdList));
return categoryIdList;
}
/**
* 处理类目名称
*/
public List<String> queryCategoryName(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return null;
}
Map<Long, CategoryEntity> categoryMap = this.queryCategoryList(categoryIdList);
List<String> categoryNameList = Lists.newArrayList();
categoryIdList.forEach(e -> {
CategoryEntity categoryEntity = categoryMap.get(e);
if (categoryEntity != null) {
categoryNameList.add(categoryMap.get(e).getCategoryName());
}
});
return categoryNameList;
}
/**
* 根据类目id 查询类目名称
*/
public String queryCategoryName(Long categoryId) {
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
return null;
}
return categoryEntity.getCategoryName();
}
/**
* 根据类目id 查询类目详情 包含类目全称 医考/医师资格/临床执业
*/
public CategorySimpleDTO queryCategoryInfo(Long categoryId) {
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
return null;
}
String fullName = this.queryFullName(categoryId);
// 返回DTO
CategorySimpleDTO categoryDTO = new CategorySimpleDTO();
categoryDTO.setCategoryId(categoryId);
categoryDTO.setCategoryName(categoryEntity.getCategoryName());
categoryDTO.setCategoryFullName(fullName);
categoryDTO.setParentId(categoryEntity.getParentId());
return categoryDTO;
}
/**
* 递归查询分类和所有父级类目
* ps:特别注意返回的集合中 包含自己
*/
public List<CategoryEntity> queryCategoryAndParent(Long categoryId) {
List<CategoryEntity> parentCategoryList = Lists.newArrayList();
CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
return parentCategoryList;
}
// 父级始终放在第一位
parentCategoryList.add(0, categoryEntity);
Long parentId = categoryEntity.getParentId();
if (Objects.equals(DEFAULT_CATEGORY_PARENT_ID, parentId)) {
return parentCategoryList;
}
parentCategoryList.addAll(0, this.queryCategoryAndParent(parentId));
return parentCategoryList;
}
/**
* 查询 分类全称 医考/医师资格/临床执业
*/
public String queryFullName(Long categoryId) {
List<CategoryEntity> parentCategoryList = this.queryCategoryAndParent(categoryId);
// 拼接父级类目名称 斜杠分隔返回
List<String> nameList = parentCategoryList.stream().map(CategoryEntity::getCategoryName).collect(Collectors.toList());
return StrUtil.join(StringConst.SEPARATOR_SLASH, nameList);
}
/**
* 查询 分类全称 医考/医师资格/临床执业
*/
public Map<Long, String> queryFullName(List<Long> categoryIdList) {
if (CollectionUtils.isEmpty(categoryIdList)) {
return Maps.newHashMap();
}
// 循环内查询的缓存 还ok
return categoryIdList.stream().collect(Collectors.toMap(Function.identity(), this::queryFullName));
}
}

203
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java

@ -0,0 +1,203 @@
package net.lab1024.sa.admin.module.business.category.service;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import net.lab1024.sa.admin.module.business.category.dao.CategoryDao;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryAddForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryTreeQueryForm;
import net.lab1024.sa.admin.module.business.category.domain.form.CategoryUpdateForm;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryTreeVO;
import net.lab1024.sa.admin.module.business.category.domain.vo.CategoryVO;
import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
/**
* 类目
*
* @Date 2021/08/05 21:26:58
* @Author wzh
*/
@Service
public class CategoryService {
@Resource
private CategoryDao categoryDao;
@Resource
private CategoryQueryService categoryQueryService;
@Resource
private CategoryCacheManager categoryCacheManager;
/**
* 添加类目
*/
public ResponseDTO<String> add(CategoryAddForm addForm) {
// 校验类目
CategoryEntity categoryEntity = SmartBeanUtil.copy(addForm, CategoryEntity.class);
ResponseDTO<String> res = this.checkCategory(categoryEntity, false);
if (!res.getOk()) {
return res;
}
// 没有父类则使用默认父类
Long parentId = null == addForm.getParentId() ? NumberUtils.LONG_ZERO : addForm.getParentId();
categoryEntity.setParentId(parentId);
categoryEntity.setSort(null == addForm.getSort() ? 0 : addForm.getSort());
categoryEntity.setDeletedFlag(false);
// 保存数据
categoryDao.insert(categoryEntity);
// 更新缓存
categoryCacheManager.removeCache();
return ResponseDTO.ok();
}
/**
* 更新类目
* 不能更新父级类目
*
*/
public ResponseDTO<String> update(CategoryUpdateForm updateForm) {
// 校验类目
Long categoryId = updateForm.getCategoryId();
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
CategoryEntity categoryEntity = SmartBeanUtil.copy(updateForm, CategoryEntity.class);
/*
不更新类目类型
不更新父类id
*/
Integer categoryType = optional.get().getCategoryType();
categoryEntity.setCategoryType(categoryType);
categoryEntity.setParentId(optional.get().getParentId());
ResponseDTO<String> responseDTO = this.checkCategory(categoryEntity, true);
if (!responseDTO.getOk()) {
return responseDTO;
}
categoryDao.updateById(categoryEntity);
// 更新缓存
categoryCacheManager.removeCache();
return ResponseDTO.ok();
}
/**
* 新增/更新 类目时的 校验
*
*/
private ResponseDTO<String> checkCategory(CategoryEntity categoryEntity, boolean isUpdate) {
// 校验父级是否存在
Long parentId = categoryEntity.getParentId();
Integer categoryType = categoryEntity.getCategoryType();
if (null != parentId) {
if (Objects.equals(categoryEntity.getCategoryId(), parentId)) {
return ResponseDTO.userErrorParam("父级类目怎么和自己相同了");
}
if (!Objects.equals(parentId, NumberUtils.LONG_ZERO)) {
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(parentId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "父级类目不存在~");
}
CategoryEntity parent = optional.get();
if (!Objects.equals(categoryType, parent.getCategoryType())) {
return ResponseDTO.userErrorParam("与父级类目类型不一致");
}
}
} else {
// 如果没有父类 使用默认父类
parentId = NumberUtils.LONG_ZERO;
}
// 校验同父类下 名称是否重复
CategoryEntity queryEntity = new CategoryEntity();
queryEntity.setParentId(parentId);
queryEntity.setCategoryType(categoryType);
queryEntity.setCategoryName(categoryEntity.getCategoryName());
queryEntity.setDeletedFlag(false);
queryEntity = categoryDao.selectOne(queryEntity);
if (null != queryEntity) {
if (isUpdate) {
if (!Objects.equals(queryEntity.getCategoryId(), categoryEntity.getCategoryId())) {
return ResponseDTO.userErrorParam("同级下已存在相同类目~");
}
} else {
return ResponseDTO.userErrorParam("同级下已存在相同类目~");
}
}
return ResponseDTO.ok();
}
/**
* 查询 类目详情
*
*/
public ResponseDTO<CategoryVO> queryDetail(Long categoryId) {
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
CategoryVO adminVO = SmartBeanUtil.copy(optional.get(), CategoryVO.class);
return ResponseDTO.ok(adminVO);
}
/**
* 根据父级id 查询所有子类 返回层级树
* 如果父类id 为空 返回所有类目层级
*
*/
public ResponseDTO<List<CategoryTreeVO>> queryTree(CategoryTreeQueryForm queryForm) {
if (null == queryForm.getParentId()) {
if (null == queryForm.getCategoryType()) {
return ResponseDTO.userErrorParam("类目类型不能为空");
}
queryForm.setParentId(NumberUtils.LONG_ZERO);
}
List<CategoryTreeVO> treeList = categoryCacheManager.queryCategoryTree(queryForm.getParentId(), queryForm.getCategoryType());
return ResponseDTO.ok(treeList);
}
/**
* 删除类目
* 如果有未删除的子类 则无法删除
*
*/
public ResponseDTO<String> delete(Long categoryId) {
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
List<Long> categorySubId = categoryQueryService.queryCategorySubId(Lists.newArrayList(categoryId));
if (CollectionUtils.isNotEmpty(categorySubId)) {
return ResponseDTO.userErrorParam("请先删除子级类目");
}
// 更新数据
CategoryEntity categoryEntity = new CategoryEntity();
categoryEntity.setCategoryId(categoryId);
categoryEntity.setDeletedFlag(true);
categoryDao.updateById(categoryEntity);
// 更新缓存
categoryCacheManager.removeCache();
return ResponseDTO.ok();
}
}

39
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java

@ -0,0 +1,39 @@
package net.lab1024.sa.admin.module.business.goods.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
* 商品状态
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@AllArgsConstructor
@Getter
public enum GoodsStatusEnum implements BaseEnum {
/**
* 1 预约中
*/
APPOINTMENT(1, "预约中"),
/**
* 2 售卖
*/
SELL(2, "售卖中"),
/**
* 3 售罄
*/
SELL_OUT(3, "售罄"),
;
private final Integer value;
private final String desc;
}

91
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java

@ -0,0 +1,91 @@
package net.lab1024.sa.admin.module.business.goods.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import net.lab1024.sa.admin.module.business.goods.service.GoodsService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.ValidateList;
import net.lab1024.sa.base.common.util.SmartExcelUtil;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
/**
* 商品业务
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@RestController
@Tag(name = AdminSwaggerTagConst.Business.MANAGER_GOODS)
public class GoodsController {
@Resource
private GoodsService goodsService;
@Operation(summary = "分页查询 ")
@PostMapping("/goods/query")
@SaCheckPermission("goods:query")
public ResponseDTO<PageResult<GoodsVO>> query(@RequestBody @Valid GoodsQueryForm queryForm) {
return goodsService.query(queryForm);
}
@Operation(summary = "添加商品 ")
@PostMapping("/goods/add")
@SaCheckPermission("goods:add")
public ResponseDTO<String> add(@RequestBody @Valid GoodsAddForm addForm) {
return goodsService.add(addForm);
}
@Operation(summary = "更新商品 ")
@PostMapping("/goods/update")
@SaCheckPermission("goods:update")
public ResponseDTO<String> update(@RequestBody @Valid GoodsUpdateForm updateForm) {
return goodsService.update(updateForm);
}
@Operation(summary = "删除 @author 卓大")
@GetMapping("/goods/delete/{goodsId}")
@SaCheckPermission("goods:delete")
public ResponseDTO<String> delete(@PathVariable Long goodsId) {
return goodsService.delete(goodsId);
}
@Operation(summary = "批量 @author 卓大")
@PostMapping("/goods/batchDelete")
@SaCheckPermission("goods:batchDelete")
public ResponseDTO<String> batchDelete(@RequestBody @Valid ValidateList<Long> idList) {
return goodsService.batchDelete(idList);
}
// --------------- 导出和导入 -------------------
@Operation(summary = "导入 @author 卓大")
@PostMapping("/goods/importGoods")
@SaCheckPermission("goods:importGoods")
public ResponseDTO<String> importGoods(@RequestParam MultipartFile file) {
return goodsService.importGoods(file);
}
@Operation(summary = "导出 @author 卓大")
@GetMapping("/goods/exportGoods")
@SaCheckPermission("goods:exportGoods")
public void exportGoods(HttpServletResponse response) throws IOException {
List<GoodsExcelVO> goodsList = goodsService.getAllGoods();
SmartExcelUtil.exportExcel(response,"商品列表.xlsx","商品",GoodsExcelVO.class, goodsList);
}
}

34
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java

@ -0,0 +1,34 @@
package net.lab1024.sa.admin.module.business.goods.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 商品
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Mapper
public interface GoodsDao extends BaseMapper<GoodsEntity> {
/**
* 分页 查询商品
*
*/
List<GoodsVO> query(Page page, @Param("query") GoodsQueryForm query);
/**
* 批量更新删除状态
*/
void batchUpdateDeleted(@Param("goodsIdList")List<Long> goodsIdList,@Param("deletedFlag")Boolean deletedFlag);
}

68
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java

@ -0,0 +1,68 @@
package net.lab1024.sa.admin.module.business.goods.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 商品 实体类
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
@TableName("t_goods")
public class GoodsEntity {
@TableId(type = IdType.AUTO)
private Long goodsId;
/**
* 商品状态:[1:预约中,2:售卖中,3:售罄]
*/
private Integer goodsStatus;
/**
* 商品分类
*/
private Long categoryId;
/**
* 商品名称
*/
private String goodsName;
/**
* 产地
*/
private String place;
/**
* 商品价格
*/
private BigDecimal price;
/**
* 上架状态
*/
private Boolean shelvesFlag;
/**
* 删除状态
*/
private Boolean deletedFlag;
/**
* 备注
*/
private String remark;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

53
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java

@ -0,0 +1,53 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import java.math.BigDecimal;
/**
* 商品 添加表单
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
public class GoodsAddForm {
@Schema(description = "商品分类")
@NotNull(message = "商品分类不能为空")
private Long categoryId;
@Schema(description = "商品名称")
@NotBlank(message = "商品名称不能为空")
private String goodsName;
@SchemaEnum(GoodsStatusEnum.class)
@CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = true)
private Integer goodsStatus;
@Schema(description = "产地")
@NotBlank(message = "产地 不能为空 ")
@JsonDeserialize(using = DictDataDeserializer.class)
private String place;
@Schema(description = "商品价格")
@NotNull(message = "商品价格不能为空")
@DecimalMin(value = "0", message = "商品价格最低0")
private BigDecimal price;
@Schema(description = "上架状态")
@NotNull(message = "上架状态不能为空")
private Boolean shelvesFlag;
@Schema(description = "备注|可选")
private String remark;
}

34
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsImportForm.java

@ -0,0 +1,34 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
* 商品 导入表单
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
public class GoodsImportForm {
@ExcelProperty("商品分类")
private String categoryName;
@ExcelProperty("商品名称")
private String goodsName;
@ExcelProperty("商品状态错误")
private String goodsStatus;
@ExcelProperty("产地")
private String place;
@ExcelProperty("商品价格")
private BigDecimal price;
@ExcelProperty("备注")
private String remark;
}

42
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java

@ -0,0 +1,42 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.domain.PageParam;
import net.lab1024.sa.base.common.json.deserializer.DictDataDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
* 商品 分页查询
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
public class GoodsQueryForm extends PageParam {
@Schema(description = "商品分类")
private Integer categoryId;
@Schema(description = "搜索词")
@Length(max = 30, message = "搜索词最多30字符")
private String searchWord;
@SchemaEnum(GoodsStatusEnum.class)
@CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = false)
private Integer goodsStatus;
@Schema(description = "产地")
@JsonDeserialize(using = DictDataDeserializer.class)
private String place;
@Schema(description = "上架状态")
private Boolean shelvesFlag;
@Schema(hidden = true)
private Boolean deletedFlag;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 商品 更新表单
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
public class GoodsUpdateForm extends GoodsAddForm {
@Schema(description = "商品id")
@NotNull(message = "商品id不能为空")
private Long goodsId;
}

41
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsExcelVO.java

@ -0,0 +1,41 @@
package net.lab1024.sa.admin.module.business.goods.domain.vo;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
/**
* excel商品
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class GoodsExcelVO {
@ExcelProperty("商品分类")
private String categoryName;
@ExcelProperty("商品名称")
private String goodsName;
@ExcelProperty("商品状态错误")
private String goodsStatus;
@ExcelProperty("产地")
private String place;
@ExcelProperty("商品价格")
private BigDecimal price;
@ExcelProperty("备注")
private String remark;
}

51
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java

@ -0,0 +1,51 @@
package net.lab1024.sa.admin.module.business.goods.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 商品
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Data
public class GoodsVO {
@Schema(description = "商品分类")
private Long categoryId;
@Schema(description = "商品名称")
private String goodsName;
@SchemaEnum(GoodsStatusEnum.class)
private Integer goodsStatus;
@Schema(description = "产地")
private String place;
@Schema(description = "商品价格")
private BigDecimal price;
@Schema(description = "上架状态")
private Boolean shelvesFlag;
@Schema(description = "备注|可选")
private String remark;
@Schema(description = "商品id")
private Long goodsId;
@Schema(description = "商品分类")
private String categoryName;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

208
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java

@ -0,0 +1,208 @@
package net.lab1024.sa.admin.module.business.goods.service;
import cn.idev.excel.FastExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
import net.lab1024.sa.admin.module.business.category.domain.entity.CategoryEntity;
import net.lab1024.sa.admin.module.business.category.service.CategoryQueryService;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.admin.module.business.goods.dao.GoodsDao;
import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsAddForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsImportForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsQueryForm;
import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsExcelVO;
import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.exception.BusinessException;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartEnumUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import net.lab1024.sa.base.module.support.dict.service.DictService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 商品
*
* @Date 2021-10-25 20:26:54
* @Author wzh
*/
@Service
@Slf4j
public class GoodsService {
@Resource
private GoodsDao goodsDao;
@Resource
private CategoryQueryService categoryQueryService;
@Resource
private DataTracerService dataTracerService;
@Resource
private DictService dictService;
/**
* 添加商品
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> add(GoodsAddForm addForm) {
// 商品校验
ResponseDTO<String> res = this.checkGoods(addForm);
if (!res.getOk()) {
return res;
}
GoodsEntity goodsEntity = SmartBeanUtil.copy(addForm, GoodsEntity.class);
goodsEntity.setDeletedFlag(Boolean.FALSE);
goodsDao.insert(goodsEntity);
dataTracerService.insert(goodsEntity.getGoodsId(), DataTracerTypeEnum.GOODS);
return ResponseDTO.ok();
}
/**
* 更新商品
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> update(GoodsUpdateForm updateForm) {
// 商品校验
ResponseDTO<String> res = this.checkGoods(updateForm);
if (!res.getOk()) {
return res;
}
GoodsEntity originEntity = goodsDao.selectById(updateForm.getGoodsId());
GoodsEntity goodsEntity = SmartBeanUtil.copy(updateForm, GoodsEntity.class);
goodsDao.updateById(goodsEntity);
dataTracerService.update(updateForm.getGoodsId(), DataTracerTypeEnum.GOODS, originEntity, goodsEntity);
return ResponseDTO.ok();
}
/**
* 添加/更新 商品校验
*/
private ResponseDTO<String> checkGoods(GoodsAddForm addForm) {
// 校验类目id
Long categoryId = addForm.getCategoryId();
Optional<CategoryEntity> optional = categoryQueryService.queryCategory(categoryId);
if (!optional.isPresent() || !CategoryTypeEnum.GOODS.equalsValue(optional.get().getCategoryType())) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST, "商品类目不存在~");
}
return ResponseDTO.ok();
}
/**
* 删除
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> delete(Long goodsId) {
GoodsEntity goodsEntity = goodsDao.selectById(goodsId);
if (goodsEntity == null) {
return ResponseDTO.userErrorParam("商品不存在");
}
if (!goodsEntity.getGoodsStatus().equals(GoodsStatusEnum.SELL_OUT.getValue())) {
return ResponseDTO.userErrorParam("只有售罄的商品才可以删除");
}
batchDelete(Collections.singletonList(goodsId));
dataTracerService.batchDelete(Collections.singletonList(goodsId), DataTracerTypeEnum.GOODS);
return ResponseDTO.ok();
}
/**
* 批量删除
*/
public ResponseDTO<String> batchDelete(List<Long> goodsIdList) {
if (CollectionUtils.isEmpty(goodsIdList)) {
return ResponseDTO.ok();
}
goodsDao.batchUpdateDeleted(goodsIdList, Boolean.TRUE);
return ResponseDTO.ok();
}
/**
* 分页查询
*/
public ResponseDTO<PageResult<GoodsVO>> query(GoodsQueryForm queryForm) {
queryForm.setDeletedFlag(false);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<GoodsVO> list = goodsDao.query(page, queryForm);
PageResult<GoodsVO> pageResult = SmartPageUtil.convert2PageResult(page, list);
if (pageResult.getEmptyFlag()) {
return ResponseDTO.ok(pageResult);
}
// 查询分类名称
List<Long> categoryIdList = list.stream().map(GoodsVO::getCategoryId).distinct().collect(Collectors.toList());
Map<Long, CategoryEntity> categoryMap = categoryQueryService.queryCategoryList(categoryIdList);
list.forEach(e -> {
CategoryEntity categoryEntity = categoryMap.get(e.getCategoryId());
if (categoryEntity != null) {
e.setCategoryName(categoryEntity.getCategoryName());
}
});
return ResponseDTO.ok(pageResult);
}
/**
* 商品导入
*
* @param file 上传文件
* @return 结果
*/
public ResponseDTO<String> importGoods(MultipartFile file) {
List<GoodsImportForm> dataList;
try {
dataList = FastExcel.read(file.getInputStream()).head(GoodsImportForm.class)
.sheet()
.doReadSync();
} catch (IOException e) {
log.error(e.getMessage(), e);
throw new BusinessException("数据格式存在问题,无法读取");
}
if (CollectionUtils.isEmpty(dataList)) {
return ResponseDTO.userErrorParam("数据为空");
}
return ResponseDTO.okMsg("成功导入" + dataList.size() + "条,具体数据为:" + JSON.toJSONString(dataList));
}
/**
* 商品导出
*/
public List<GoodsExcelVO> getAllGoods() {
List<GoodsEntity> goodsEntityList = goodsDao.selectList(null);
String dictCode = "GOODS_PLACE";
return goodsEntityList.stream()
.map(e ->
GoodsExcelVO.builder()
.goodsStatus(SmartEnumUtil.getEnumDescByValue(e.getGoodsStatus(), GoodsStatusEnum.class))
.categoryName(categoryQueryService.queryCategoryName(e.getCategoryId()))
.place(Arrays.stream(e.getPlace().split(",")).map(code -> dictService.getDictDataLabel(dictCode, code)).collect(Collectors.joining(",")))
.price(e.getPrice())
.goodsName(e.getGoodsName())
.remark(e.getRemark())
.build()
)
.collect(Collectors.toList());
}
}

78
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java

@ -0,0 +1,78 @@
package net.lab1024.sa.admin.module.business.oa.bank;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankCreateForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankUpdateForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* OA办公-OA银行信息
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@RestController
@Tag(name = AdminSwaggerTagConst.Business.OA_BANK)
public class BankController {
@Resource
private BankService bankService;
@Operation(summary = "分页查询银行信息 @author 善逸")
@PostMapping("/oa/bank/page/query")
@SaCheckPermission("oa:bank:query")
public ResponseDTO<PageResult<BankVO>> queryByPage(@RequestBody @Valid BankQueryForm queryForm) {
return bankService.queryByPage(queryForm);
}
@Operation(summary = "根据企业ID查询银行信息列表 @author 善逸")
@GetMapping("/oa/bank/query/list/{enterpriseId}")
@SaCheckPermission("oa:bank:query")
public ResponseDTO<List<BankVO>> queryList(@PathVariable Long enterpriseId) {
return bankService.queryList(enterpriseId);
}
@Operation(summary = "查询银行信息详情 @author 善逸")
@GetMapping("/oa/bank/get/{bankId}")
@SaCheckPermission("oa:bank:query")
public ResponseDTO<BankVO> getDetail(@PathVariable Long bankId) {
return bankService.getDetail(bankId);
}
@Operation(summary = "新建银行信息 @author 善逸")
@PostMapping("/oa/bank/create")
@SaCheckPermission("oa:bank:add")
public ResponseDTO<String> createBank(@RequestBody @Valid BankCreateForm createVO) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
createVO.setCreateUserId(requestUser.getUserId());
createVO.setCreateUserName(requestUser.getUserName());
return bankService.createBank(createVO);
}
@Operation(summary = "编辑银行信息 @author 善逸")
@PostMapping("/oa/bank/update")
@SaCheckPermission("oa:bank:update")
public ResponseDTO<String> updateBank(@RequestBody @Valid BankUpdateForm updateVO) {
return bankService.updateBank(updateVO);
}
@Operation(summary = "删除银行信息 @author 善逸")
@GetMapping("/oa/bank/delete/{bankId}")
@SaCheckPermission("oa:bank:delete")
public ResponseDTO<String> deleteBank(@PathVariable Long bankId) {
return bankService.deleteBank(bankId);
}
}

44
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java

@ -0,0 +1,44 @@
package net.lab1024.sa.admin.module.business.oa.bank;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankEntity;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* OA办公-OA银行信息
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Mapper
public interface BankDao extends BaseMapper<BankEntity> {
/**
* 根据账号查询
*/
BankEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeBankId") Long excludeBankId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 删除银行信息
*
*/
void deleteBank(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 银行信息分页查询
*
*/
List<BankVO> queryPage(Page page, @Param("queryForm") BankQueryForm queryForm);
/**
* 查询银行信息详情
*/
BankVO getDetail(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag);
}

142
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java

@ -0,0 +1,142 @@
package net.lab1024.sa.admin.module.business.oa.bank;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.bank.domain.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
/**
* OA办公-OA银行信息
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Service
@Slf4j
public class BankService {
@Resource
private BankDao bankDao;
@Resource
private EnterpriseDao enterpriseDao;
@Resource
private DataTracerService dataTracerService;
/**
* 分页查询银行信息
*/
public ResponseDTO<PageResult<BankVO>> queryByPage(BankQueryForm queryForm) {
queryForm.setDeletedFlag(Boolean.FALSE);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<BankVO> bankList = bankDao.queryPage(page, queryForm);
PageResult<BankVO> pageResult = SmartPageUtil.convert2PageResult(page, bankList);
return ResponseDTO.ok(pageResult);
}
/**
* 根据企业ID查询不分页的银行列表
*/
public ResponseDTO<List<BankVO>> queryList(Long enterpriseId) {
BankQueryForm queryForm = new BankQueryForm();
queryForm.setEnterpriseId(enterpriseId);
queryForm.setDeletedFlag(Boolean.FALSE);
List<BankVO> bankList = bankDao.queryPage(null, queryForm);
return ResponseDTO.ok(bankList);
}
/**
* 查询银行信息详情
*/
public ResponseDTO<BankVO> getDetail(Long bankId) {
// 校验银行信息是否存在
BankVO bankVO = bankDao.getDetail(bankId, Boolean.FALSE);
if (Objects.isNull(bankVO)) {
return ResponseDTO.userErrorParam("银行信息不存在");
}
return ResponseDTO.ok(bankVO);
}
/**
* 新建银行信息
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> createBank(BankCreateForm createVO) {
Long enterpriseId = createVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
// 验证银行信息账号是否重复
BankEntity validateBank = bankDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE);
if (Objects.nonNull(validateBank)) {
return ResponseDTO.userErrorParam("银行信息账号重复");
}
// 数据插入
BankEntity insertBank = SmartBeanUtil.copy(createVO, BankEntity.class);
bankDao.insert(insertBank);
dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertBank));
return ResponseDTO.ok();
}
/**
* 编辑银行信息
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> updateBank(BankUpdateForm updateVO) {
Long enterpriseId = updateVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
Long bankId = updateVO.getBankId();
// 校验银行信息是否存在
BankEntity bankDetail = bankDao.selectById(bankId);
if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("银行信息不存在");
}
// 验证银行信息账号是否重复
BankEntity validateBank = bankDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), bankId, Boolean.FALSE);
if (Objects.nonNull(validateBank)) {
return ResponseDTO.userErrorParam("银行信息账号重复");
}
// 数据编辑
BankEntity updateBank = SmartBeanUtil.copy(updateVO, BankEntity.class);
bankDao.updateById(updateBank);
dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail, updateBank));
return ResponseDTO.ok();
}
/**
* 删除银行信息
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> deleteBank(Long bankId) {
// 校验银行信息是否存在
BankEntity bankDetail = bankDao.selectById(bankId);
if (Objects.isNull(bankDetail) || bankDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("银行信息不存在");
}
bankDao.deleteBank(bankId, Boolean.TRUE);
dataTracerService.addTrace(bankDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除银行:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(bankDetail));
return ResponseDTO.ok();
}
}

54
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java

@ -0,0 +1,54 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
/**
* OA办公-银行信息新建
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Data
public class BankCreateForm {
@Schema(description = "开户银行")
@NotBlank(message = "开户银行不能为空")
@Length(max = 200, message = "开户银行最多200字符")
private String bankName;
@Schema(description = "账户名称")
@NotBlank(message = "账户名称不能为空")
@Length(max = 200, message = "账户名称最多200字符")
private String accountName;
@Schema(description = "账号")
@NotBlank(message = "账号不能为空")
@Length(max = 200, message = "账号最多200字符")
private String accountNumber;
@Schema(description = "备注")
@Length(max = 500, message = "备注最多500字符")
private String remark;
@Schema(description = "是否对公")
@NotNull(message = "是否对公不能为空")
private Boolean businessFlag;
@Schema(description = "企业")
@NotNull(message = "企业不能为空")
private Long enterpriseId;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
@Schema(hidden = true)
private Long createUserId;
@Schema(hidden = true)
private String createUserName;
}

92
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java

@ -0,0 +1,92 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel;
import java.time.LocalDateTime;
/**
* OA办公-OA银行信息
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Data
@TableName("t_oa_bank")
public class BankEntity {
/**
* 银行信息ID
*/
@TableId(type = IdType.AUTO)
@DataTracerFieldLabel("银行信息ID")
private Long bankId;
/**
* 开户银行
*/
@DataTracerFieldLabel("开户银行")
private String bankName;
/**
* 账户名称
*/
@DataTracerFieldLabel("账户名称")
private String accountName;
/**
* 账号
*/
@DataTracerFieldLabel("账号")
private String accountNumber;
/**
* 备注
*/
@DataTracerFieldLabel("备注")
private String remark;
/**
* 是否对公
*/
@DataTracerFieldLabel("是否对公")
private Boolean businessFlag;
/**
* 企业ID
*/
private Long enterpriseId;
/**
* 禁用状态
*/
@DataTracerFieldLabel("禁用状态")
private Boolean disabledFlag;
/**
* 删除状态
*/
private Boolean deletedFlag;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人ID
*/
private String createUserName;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

37
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java

@ -0,0 +1,37 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
import java.time.LocalDate;
/**
* OA办公-OA银行信息查询
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Data
public class BankQueryForm extends PageParam {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "关键字")
@Length(max = 200, message = "关键字最多200字符")
private String keywords;
@Schema(description = "开始时间")
private LocalDate startTime;
@Schema(description = "结束时间")
private LocalDate endTime;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "删除状态", hidden = true)
private Boolean deletedFlag;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* OA办公-银行信息更新
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Data
public class BankUpdateForm extends BankCreateForm {
@Schema(description = "银行信息ID")
@NotNull(message = "银行信息ID不能为空")
private Long bankId;
}

55
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java

@ -0,0 +1,55 @@
package net.lab1024.sa.admin.module.business.oa.bank.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* OA办公-OA银行信息
*
* @Date 2022/6/23 21:59:22
* @Author wzh
*/
@Data
public class BankVO {
@Schema(description = "银行信息ID")
private Long bankId;
@Schema(description = "开户银行")
private String bankName;
@Schema(description = "账户名称")
private String accountName;
@Schema(description = "账号")
private String accountNumber;
@Schema(description = "备注")
private String remark;
@Schema(description = "是否对公")
private Boolean businessFlag;
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "创建人ID")
private Long createUserId;
@Schema(description = "创建人名称")
private String createUserName;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

134
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java

@ -0,0 +1,134 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.util.AdminRequestUtil;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.*;
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
/**
* 企业
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Slf4j
@RestController
@Tag(name = AdminSwaggerTagConst.Business.OA_ENTERPRISE)
@OperateLog
public class EnterpriseController {
@Resource
private EnterpriseService enterpriseService;
@Operation(summary = "分页查询企业模块 @author 开云")
@PostMapping("/oa/enterprise/page/query")
@SaCheckPermission("oa:enterprise:query")
public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryForm) {
return enterpriseService.queryByPage(queryForm);
}
@Operation(summary = "导出企业信息 @author 卓大")
@PostMapping("/oa/enterprise/exportExcel")
public void exportExcel(@RequestBody @Valid EnterpriseQueryForm queryForm, HttpServletResponse response) throws IOException {
List<EnterpriseExcelVO> data = enterpriseService.getExcelExportData(queryForm);
if (CollectionUtils.isEmpty(data)) {
SmartResponseUtil.write(response, ResponseDTO.userErrorParam("暂无数据"));
return;
}
String watermark = AdminRequestUtil.getRequestUser().getActualName();
watermark += SmartLocalDateUtil.format(LocalDateTime.now(), SmartDateFormatterEnum.YMD_HMS);
SmartExcelUtil.exportExcelWithWatermark(response,"企业基本信息.xlsx","企业信息",EnterpriseExcelVO.class,data,watermark);
}
@Operation(summary = "查询企业详情 @author 开云")
@GetMapping("/oa/enterprise/get/{enterpriseId}")
@SaCheckPermission("oa:enterprise:detail")
public ResponseDTO<EnterpriseVO> getDetail(@PathVariable Long enterpriseId) {
return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId));
}
@Operation(summary = "新建企业 @author 开云")
@PostMapping("/oa/enterprise/create")
@SaCheckPermission("oa:enterprise:add")
public ResponseDTO<String> createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
createVO.setCreateUserId(requestUser.getUserId());
createVO.setCreateUserName(requestUser.getUserName());
return enterpriseService.createEnterprise(createVO);
}
@Operation(summary = "编辑企业 @author 开云")
@PostMapping("/oa/enterprise/update")
@SaCheckPermission("oa:enterprise:update")
public ResponseDTO<String> updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) {
return enterpriseService.updateEnterprise(updateVO);
}
@Operation(summary = "删除企业 @author 开云")
@GetMapping("/oa/enterprise/delete/{enterpriseId}")
@SaCheckPermission("oa:enterprise:delete")
public ResponseDTO<String> deleteEnterprise(@PathVariable Long enterpriseId) {
return enterpriseService.deleteEnterprise(enterpriseId);
}
@Operation(summary = "按照类型查询企业 @author 开云")
@GetMapping("/oa/enterprise/query/list")
@SaCheckPermission("oa:enterprise:query")
public ResponseDTO<List<EnterpriseListVO>> queryList(@RequestParam(value = "type", required = false) Integer type) {
return enterpriseService.queryList(type);
}
@Operation(summary = "企业添加员工 @author 罗伊")
@PostMapping("/oa/enterprise/employee/add")
@SaCheckPermission("oa:enterprise:addEmployee")
public ResponseDTO<String> addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
return enterpriseService.addEmployee(enterpriseEmployeeForm);
}
@Operation(summary = "查询企业全部员工 @author 罗伊")
@PostMapping("/oa/enterprise/employee/list")
@SaCheckPermission("oa:enterprise:queryEmployee")
public ResponseDTO<List<EnterpriseEmployeeVO>> employeeList(@RequestBody @Valid List<Long> enterpriseIdList) {
return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList));
}
@Operation(summary = "分页查询企业员工 @author 卓大")
@PostMapping("/oa/enterprise/employee/queryPage")
@SaCheckPermission("oa:enterprise:queryEmployee")
public ResponseDTO<PageResult<EnterpriseEmployeeVO>> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) {
return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm));
}
@Operation(summary = "企业删除员工 @author 罗伊")
@PostMapping("/oa/enterprise/employee/delete")
@SaCheckPermission("oa:enterprise:deleteEmployee")
public ResponseDTO<String> deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
return enterpriseService.deleteEmployee(enterpriseEmployeeForm);
}
}

16
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java

@ -0,0 +1,16 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity;
import org.springframework.stereotype.Service;
/**
* 企业员工关系 manager
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Service
public class EnterpriseEmployeeManager extends ServiceImpl<EnterpriseEmployeeDao, EnterpriseEmployeeEntity> {
}

235
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java

@ -0,0 +1,235 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.domain.form.DataTracerForm;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 企业
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Service
@Slf4j
public class EnterpriseService {
@Resource
private EnterpriseDao enterpriseDao;
@Resource
private EnterpriseEmployeeDao enterpriseEmployeeDao;
@Resource
private EnterpriseEmployeeManager enterpriseEmployeeManager;
@Resource
private DataTracerService dataTracerService;
@Resource
private DepartmentService departmentService;
/**
* 分页查询企业模块
*
*/
public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(EnterpriseQueryForm queryForm) {
queryForm.setDeletedFlag(Boolean.FALSE);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<EnterpriseVO> enterpriseList = enterpriseDao.queryPage(page, queryForm);
PageResult<EnterpriseVO> pageResult = SmartPageUtil.convert2PageResult(page, enterpriseList);
return ResponseDTO.ok(pageResult);
}
/**
* 获取导出数据
*/
public List<EnterpriseExcelVO> getExcelExportData(EnterpriseQueryForm queryForm) {
queryForm.setDeletedFlag(false);
return enterpriseDao.selectExcelExportData(queryForm);
}
/**
* 查询企业详情
*
*/
public EnterpriseVO getDetail(Long enterpriseId) {
return enterpriseDao.getDetail(enterpriseId, Boolean.FALSE);
}
/**
* 新建企业
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> createEnterprise(EnterpriseCreateForm createVO) {
// 验证企业名称是否重复
EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(createVO.getEnterpriseName(), null, Boolean.FALSE);
if (Objects.nonNull(validateEnterprise)) {
return ResponseDTO.userErrorParam("企业名称重复");
}
// 数据插入
EnterpriseEntity insertEnterprise = SmartBeanUtil.copy(createVO, EnterpriseEntity.class);
enterpriseDao.insert(insertEnterprise);
dataTracerService.insert(insertEnterprise.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE);
return ResponseDTO.ok();
}
/**
* 编辑企业
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> updateEnterprise(EnterpriseUpdateForm updateVO) {
Long enterpriseId = updateVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
// 验证企业名称是否重复
EnterpriseEntity validateEnterprise = enterpriseDao.queryByEnterpriseName(updateVO.getEnterpriseName(), enterpriseId, Boolean.FALSE);
if (Objects.nonNull(validateEnterprise)) {
return ResponseDTO.userErrorParam("企业名称重复");
}
// 数据编辑
EnterpriseEntity updateEntity = SmartBeanUtil.copy(enterpriseDetail, EnterpriseEntity.class);
SmartBeanUtil.copyProperties(updateVO, updateEntity);
enterpriseDao.updateById(updateEntity);
//变更记录
DataTracerForm dataTracerForm = DataTracerForm.builder()
.dataId(updateVO.getEnterpriseId())
.type(DataTracerTypeEnum.OA_ENTERPRISE)
.content("修改企业信息")
.diffOld(dataTracerService.getChangeContent(enterpriseDetail))
.diffNew(dataTracerService.getChangeContent(updateEntity))
.build();
dataTracerService.addTrace(dataTracerForm);
return ResponseDTO.ok();
}
/**
* 删除企业
*
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> deleteEnterprise(Long enterpriseId) {
// 校验企业是否存在
EnterpriseEntity enterpriseDetail = enterpriseDao.selectById(enterpriseId);
if (Objects.isNull(enterpriseDetail) || enterpriseDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("企业不存在");
}
enterpriseDao.deleteEnterprise(enterpriseId, Boolean.TRUE);
dataTracerService.delete(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE);
return ResponseDTO.ok();
}
/**
* 企业列表查询
*/
public ResponseDTO<List<EnterpriseListVO>> queryList(Integer type) {
List<EnterpriseListVO> enterpriseList = enterpriseDao.queryList(type, Boolean.FALSE, Boolean.FALSE);
return ResponseDTO.ok(enterpriseList);
}
//----------------------------------------- 以下为员工相关--------------------------------------------
/**
* 企业添加员工
*
*/
public synchronized ResponseDTO<String> addEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) {
Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId();
EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId);
if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
//过滤掉已存在的员工
List<Long> waitAddEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList();
List<EnterpriseEmployeeEntity> enterpriseEmployeeEntityList = enterpriseEmployeeDao.selectByEnterpriseAndEmployeeIdList(enterpriseId, waitAddEmployeeIdList);
if (CollectionUtils.isNotEmpty(enterpriseEmployeeEntityList)) {
List<Long> existEmployeeIdList = enterpriseEmployeeEntityList.stream().map(EnterpriseEmployeeEntity::getEmployeeId).collect(Collectors.toList());
waitAddEmployeeIdList = waitAddEmployeeIdList.stream().filter(e -> !existEmployeeIdList.contains(e)).collect(Collectors.toList());
}
if (CollectionUtils.isEmpty(waitAddEmployeeIdList)) {
return ResponseDTO.ok();
}
List<EnterpriseEmployeeEntity> batchAddList = Lists.newArrayList();
for (Long employeeId : waitAddEmployeeIdList) {
EnterpriseEmployeeEntity enterpriseEmployeeEntity = new EnterpriseEmployeeEntity();
enterpriseEmployeeEntity.setEnterpriseId(enterpriseId);
enterpriseEmployeeEntity.setEmployeeId(employeeId);
batchAddList.add(enterpriseEmployeeEntity);
}
enterpriseEmployeeManager.saveBatch(batchAddList);
return ResponseDTO.ok();
}
/**
* 企业删除员工
*
*/
public synchronized ResponseDTO<String> deleteEmployee(EnterpriseEmployeeForm enterpriseEmployeeForm) {
Long enterpriseId = enterpriseEmployeeForm.getEnterpriseId();
EnterpriseEntity enterpriseEntity = enterpriseDao.selectById(enterpriseId);
if (enterpriseEntity == null || enterpriseEntity.getDeletedFlag()) {
return ResponseDTO.error(UserErrorCode.DATA_NOT_EXIST);
}
List<Long> waitDeleteEmployeeIdList = enterpriseEmployeeForm.getEmployeeIdList();
enterpriseEmployeeDao.deleteByEnterpriseAndEmployeeIdList(enterpriseId, waitDeleteEmployeeIdList);
return ResponseDTO.ok();
}
/**
* 企业下员工列表
*
*/
public List<EnterpriseEmployeeVO> employeeList(List<Long> enterpriseIdList) {
if (CollectionUtils.isEmpty(enterpriseIdList)) {
return Lists.newArrayList();
}
return enterpriseEmployeeDao.selectByEnterpriseIdList(enterpriseIdList);
}
/**
* 分页查询企业员工
*
*/
public PageResult<EnterpriseEmployeeVO> queryPageEmployeeList(EnterpriseEmployeeQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<EnterpriseEmployeeVO> enterpriseEmployeeVOList = enterpriseEmployeeDao.queryPageEmployeeList(page, queryForm);
for (EnterpriseEmployeeVO enterpriseEmployeeVO : enterpriseEmployeeVOList) {
enterpriseEmployeeVO.setDepartmentName(departmentService.getDepartmentPath(enterpriseEmployeeVO.getDepartmentId()));
}
return SmartPageUtil.convert2PageResult(page, enterpriseEmployeeVOList);
}
}

43
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java

@ -0,0 +1,43 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.constant;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
* 企业类型
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
public enum EnterpriseTypeEnum implements BaseEnum {
/**
* 有限企业
*/
NORMAL(1, "有限企业"),
/**
* 外资企业
*/
FOREIGN(2, "外资企业"),
;
private Integer value;
private String desc;
EnterpriseTypeEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
@Override
public Integer getValue() {
return value;
}
@Override
public String getDesc() {
return desc;
}
}

61
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java

@ -0,0 +1,61 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseQueryForm;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 企业
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Mapper
public interface EnterpriseDao extends BaseMapper<EnterpriseEntity> {
/**
* 根据企业名称查询
*
*/
EnterpriseEntity queryByEnterpriseName(@Param("enterpriseName") String enterpriseName, @Param("excludeEnterpriseId") Long excludeEnterpriseId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 删除企业
*/
void deleteEnterprise(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 企业分页查询
*
*/
List<EnterpriseVO> queryPage(Page page, @Param("queryForm") EnterpriseQueryForm queryForm);
/**
* 查询导出的数据
*
*/
List<EnterpriseExcelVO> selectExcelExportData(@Param("queryForm") EnterpriseQueryForm queryForm);
/**
* 查询企业详情
*
*/
EnterpriseVO getDetail(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 查询列表
*
*/
List<EnterpriseListVO> queryList(@Param("type") Integer type, @Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag);
}

66
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java

@ -0,0 +1,66 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEmployeeEntity;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.EnterpriseEmployeeQueryForm;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.List;
/**
* 企业员工
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Mapper
public interface EnterpriseEmployeeDao extends BaseMapper<EnterpriseEmployeeEntity> {
/**
* 根据员工查询
*/
List<EnterpriseEmployeeVO> selectByEmployeeIdList(@Param("employeeIdList")Collection<Long> employeeIdList);
/**
* 查询员工关联的企业
*/
List<Long> selectEnterpriseIdByEmployeeId(@Param("employeeId")Long employeeId);
/**
* 根据企业查询
*/
List<EnterpriseEmployeeVO> selectByEnterpriseIdList(@Param("enterpriseIdList")Collection<Long> enterpriseIdList);
/**
* 根据企业查询
*/
List<EnterpriseEmployeeEntity> selectByEnterpriseId(@Param("enterpriseId")Long enterpriseId);
/**
* 查询企业下的所有员工id
*/
List<Long> selectEmployeeIdByEnterpriseIdList(@Param("enterpriseIdList")Collection<Long> enterpriseIdList);
/**
* 根据员工删除
*/
void deleteByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection<Long> employeeIdList);
/**
* 根据员工查询
*/
List<EnterpriseEmployeeEntity> selectByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection<Long> employeeIdList);
/**
* 删除某员工关联的所有企业
*/
void deleteByEmployeeId(@Param("employeeId")Long employeeId);
/**
* 分页查询企业员工
*/
List<EnterpriseEmployeeVO> queryPageEmployeeList(Page<?> page,@Param("queryForm") EnterpriseEmployeeQueryForm queryForm);
}

48
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java

@ -0,0 +1,48 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 企业员工
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
@TableName("t_oa_enterprise_employee")
@NoArgsConstructor
public class EnterpriseEmployeeEntity {
@TableId(type = IdType.AUTO)
private Long enterpriseEmployeeId;
/**
* 企业ID
*/
private Long enterpriseId;
/**
* 员工
*/
private Long employeeId;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
public EnterpriseEmployeeEntity(Long enterpriseId, Long employeeId) {
this.enterpriseId = enterpriseId;
this.employeeId = employeeId;
}
}

150
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java

@ -0,0 +1,150 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldEnum;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel;
import java.time.LocalDateTime;
/**
* 企业
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
@TableName("t_oa_enterprise")
public class EnterpriseEntity {
/**
* 企业ID
*/
@TableId(type = IdType.AUTO)
private Long enterpriseId;
/**
* 企业名称
*/
@DataTracerFieldLabel("企业名称")
private String enterpriseName;
/**
* 企业logo
*/
@DataTracerFieldLabel("企业logo")
private String enterpriseLogo;
/**
* 统一社会信用代码
*/
@DataTracerFieldLabel("统一社会信用代码")
private String unifiedSocialCreditCode;
/**
* 类型
*
* @see EnterpriseTypeEnum
*/
@DataTracerFieldLabel("类型")
@DataTracerFieldEnum(enumClass = EnterpriseTypeEnum.class)
private Integer type;
/**
* 联系人
*/
@DataTracerFieldLabel("联系人")
private String contact;
/**
* 联系人电话
*/
@DataTracerFieldLabel("联系人电话")
private String contactPhone;
/**
* 邮箱
*/
@DataTracerFieldLabel("邮箱")
private String email;
/**
* 省份
*/
private Integer province;
/**
* 省份名称
*/
@DataTracerFieldLabel("省份名称")
private String provinceName;
/**
* 城市
*/
private Integer city;
/**
* 城市名称
*/
@DataTracerFieldLabel("城市名称")
private String cityName;
/**
* 区县
*/
private Integer district;
/**
* 区县名称
*/
@DataTracerFieldLabel("区县名称")
private String districtName;
/**
* 详细地址
*/
@DataTracerFieldLabel("详细地址")
private String address;
/**
* 营业执照
*/
@DataTracerFieldLabel("营业执照")
private String businessLicense;
/**
* 禁用状态
*/
@DataTracerFieldLabel("禁用状态")
private Boolean disabledFlag;
/**
* 删除状态
*/
@DataTracerFieldLabel("删除状态")
private Boolean deletedFlag;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人ID
*/
private String createUserName;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

97
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java

@ -0,0 +1,97 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer;
import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.util.SmartVerificationUtil;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
/**
* OA企业模块创建
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseCreateForm {
@Schema(description = "企业名称")
@NotBlank(message = "企业名称不能为空")
@Length(max = 200, message = "企业名称最多200字符")
private String enterpriseName;
@Schema(description = "企业logo")
@JsonSerialize(using = FileKeyVoSerializer.class)
@JsonDeserialize(using = FileKeyVoDeserializer.class)
private String enterpriseLogo;
@Schema(description = "统一社会信用代码")
@NotBlank(message = "统一社会信用代码不能为空")
@Length(max = 200, message = "统一社会信用代码最多200字符")
private String unifiedSocialCreditCode;
@Schema(description = "联系人")
@NotBlank(message = "联系人不能为空")
@Length(max = 100, message = "联系人最多100字符")
private String contact;
@Schema(description = "联系人电话")
@NotBlank(message = "联系人电话不能为空")
@Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确")
private String contactPhone;
@SchemaEnum(desc = "类型", value = EnterpriseTypeEnum.class)
@CheckEnum(message = "类型不正确", value = EnterpriseTypeEnum.class)
private Integer type;
@Schema(description = "邮箱")
@Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱格式不正确")
private String email;
@Schema(description = "省份")
private Integer province;
@Schema(description = "省份名称")
private String provinceName;
@Schema(description = "城市")
private Integer city;
@Schema(description = "城市名称")
private String cityName;
@Schema(description = "区县")
private Integer district;
@Schema(description = "区县名称")
private String districtName;
@Schema(description = "详细地址")
@Length(max = 500, message = "详细地址最多500字符")
private String address;
@Schema(description = "营业执照")
@JsonSerialize(using = FileKeyVoSerializer.class)
@JsonDeserialize(using = FileKeyVoDeserializer.class)
private String businessLicense;
@Schema(description = "禁用状态")
@NotNull(message = "禁用状态不能为空")
private Boolean disabledFlag;
@Schema(description = "创建人", hidden = true)
private Long createUserId;
@Schema(description = "创建人", hidden = true)
private String createUserName;
}

26
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java

@ -0,0 +1,26 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
/**
* 企业员工
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseEmployeeForm {
@Schema(description = "企业id")
@NotNull(message = "企业id不能为空")
private Long enterpriseId;
@Schema(description = "员工信息id")
@NotEmpty(message = "员工信息id不能为空")
private List<Long> employeeIdList;
}

29
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java

@ -0,0 +1,29 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
/**
* 查询企业员工
*
* @Date 2021-12-20 21:06:49
* @Author wzh
*/
@Data
public class EnterpriseEmployeeQueryForm extends PageParam {
@Schema(description = "搜索词")
@Length(max = 20, message = "搜索词最多20字符")
private String keyword;
@Schema(description = "公司Id")
@NotNull(message = "公司id 不能为空")
private Long enterpriseId;
@Schema(description = "删除标识", hidden = true)
private Boolean deletedFlag;
}

35
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java

@ -0,0 +1,35 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
import java.time.LocalDate;
/**
* OA企业模块分页查询
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseQueryForm extends PageParam {
@Schema(description = "关键字")
@Length(max = 200, message = "关键字最多200字符")
private String keywords;
@Schema(description = "开始时间")
private LocalDate startTime;
@Schema(description = "结束时间")
private LocalDate endTime;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "删除状态", hidden = true)
private Boolean deletedFlag;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* OA企业模块编辑
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseUpdateForm extends EnterpriseCreateForm {
@Schema(description = "企业ID")
@NotNull(message = "企业ID不能为空")
private Long enterpriseId;
}

44
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java

@ -0,0 +1,44 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 企业员工信息
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseEmployeeVO {
private Long enterpriseEmployeeId;
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "员工")
private Long employeeId;
@Schema(description = "登录账号")
private String loginName;
@Schema(description = "员工名称")
private String actualName;
@Schema(description = "手机号码")
private String phone;
@Schema(description = "部门id")
private Long departmentId;
@Schema(description = "是否被禁用")
private Boolean disabledFlag;
@Schema(description = "部门名称")
private String departmentName;
}

45
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseExcelVO.java

@ -0,0 +1,45 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import cn.idev.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* 企业信息
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseExcelVO {
@ExcelProperty("企业名称")
private String enterpriseName;
@ExcelProperty("统一社会信用代码")
private String unifiedSocialCreditCode;
@ExcelProperty("企业类型")
private String typeName;
@ExcelProperty("联系人")
private String contact;
@ExcelProperty("联系人电话")
private String contactPhone;
@ExcelProperty("邮箱")
private String email;
@ExcelProperty("省份名称")
private String provinceName;
@ExcelProperty("城市名称")
private String cityName;
@ExcelProperty("区县名称")
private String districtName;
@ExcelProperty("详细地址")
private String address;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* OA企业模块列表
*
* @date 2022/6/23 14:31
*/
@Data
public class EnterpriseListVO {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
}

86
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java

@ -0,0 +1,86 @@
package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
import net.lab1024.sa.base.common.json.serializer.FileKeyVoSerializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.time.LocalDateTime;
/**
* 企业信息
*
* @Date 2022/7/28 20:37:15
* @Author wzh
*/
@Data
public class EnterpriseVO {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "企业logo")
@JsonSerialize(using = FileKeyVoSerializer.class)
private String enterpriseLogo;
@Schema(description = "统一社会信用代码")
private String unifiedSocialCreditCode;
@SchemaEnum(desc = "类型", value = EnterpriseTypeEnum.class)
private Integer type;
@Schema(description = "联系人")
private String contact;
@Schema(description = "联系人电话")
private String contactPhone;
@Schema(description = "邮箱")
private String email;
@Schema(description = "省份")
private Integer province;
@Schema(description = "省份名称")
private String provinceName;
@Schema(description = "城市")
private Integer city;
@Schema(description = "城市名称")
private String cityName;
@Schema(description = "区县")
private Integer district;
@Schema(description = "区县名称")
private String districtName;
@Schema(description = "详细地址")
private String address;
@Schema(description = "营业执照")
@JsonSerialize(using = FileKeyVoSerializer.class)
private String businessLicense;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "创建人ID")
private Long createUserId;
@Schema(description = "创建人名称")
private String createUserName;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

84
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java

@ -0,0 +1,84 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceAddForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceUpdateForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.RequestUser;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* OA发票信息
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Slf4j
@RestController
@Tag(name = AdminSwaggerTagConst.Business.OA_INVOICE)
public class InvoiceController {
@Resource
private InvoiceService invoiceService;
@Operation(summary = "分页查询发票信息 @author 善逸")
@PostMapping("/oa/invoice/page/query")
@SaCheckPermission("oa:invoice:query")
public ResponseDTO<PageResult<InvoiceVO>> queryByPage(@RequestBody @Valid InvoiceQueryForm queryForm) {
return invoiceService.queryByPage(queryForm);
}
@Operation(summary = "查询发票信息详情 @author 善逸")
@GetMapping("/oa/invoice/get/{invoiceId}")
@SaCheckPermission("oa:invoice:query")
public ResponseDTO<InvoiceVO> getDetail(@PathVariable Long invoiceId) {
return invoiceService.getDetail(invoiceId);
}
@Operation(summary = "新建发票信息 @author 善逸")
@PostMapping("/oa/invoice/create")
@SaCheckPermission("oa:invoice:add")
public ResponseDTO<String> createInvoice(@RequestBody @Valid InvoiceAddForm createVO) {
RequestUser requestUser = SmartRequestUtil.getRequestUser();
createVO.setCreateUserId(requestUser.getUserId());
createVO.setCreateUserName(requestUser.getUserName());
return invoiceService.createInvoice(createVO);
}
@OperateLog
@Operation(summary = "编辑发票信息 @author 善逸")
@PostMapping("/oa/invoice/update")
@SaCheckPermission("oa:invoice:update")
public ResponseDTO<String> updateInvoice(@RequestBody @Valid InvoiceUpdateForm updateVO) {
return invoiceService.updateInvoice(updateVO);
}
@Operation(summary = "删除发票信息 @author 善逸")
@GetMapping("/invoice/delete/{invoiceId}")
@SaCheckPermission("oa:invoice:delete")
public ResponseDTO<String> deleteInvoice(@PathVariable Long invoiceId) {
return invoiceService.deleteInvoice(invoiceId);
}
@Operation(summary = "查询列表")
@GetMapping("/oa/invoice/query/list/{enterpriseId}")
@SaCheckPermission("oa:invoice:query")
public ResponseDTO<List<InvoiceVO>> queryList(@PathVariable Long enterpriseId) {
return invoiceService.queryList(enterpriseId);
}
}

57
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java

@ -0,0 +1,57 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceEntity;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* OA发票信息
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Mapper
public interface InvoiceDao extends BaseMapper<InvoiceEntity> {
/**
* 根据账号查询
* @param enterpriseId
* @param accountNumber
* @param excludeInvoiceId
* @param deletedFlag
* @return
*/
InvoiceEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeInvoiceId") Long excludeInvoiceId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 删除发票信息
*
* @param invoiceId
* @param deletedFlag
*/
void deleteInvoice(@Param("invoiceId") Long invoiceId, @Param("deletedFlag") Boolean deletedFlag);
/**
* 发票信息分页查询
*
* @param page
* @param queryForm
* @return
*/
List<InvoiceVO> queryPage(Page page, @Param("queryForm") InvoiceQueryForm queryForm);
/**
* 查询发票信息详情
* @param invoiceId
* @param deletedFlag
* @return
*/
InvoiceVO getDetail(@Param("invoiceId") Long invoiceId, @Param("deletedFlag") Boolean deletedFlag);
}

140
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java

@ -0,0 +1,140 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.enterprise.EnterpriseService;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.*;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerConst;
import net.lab1024.sa.base.module.support.datatracer.constant.DataTracerTypeEnum;
import net.lab1024.sa.base.module.support.datatracer.service.DataTracerService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
/**
* OA发票信息
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Service
@Slf4j
public class InvoiceService {
@Resource
private InvoiceDao invoiceDao;
@Resource
private EnterpriseService enterpriseService;
@Resource
private DataTracerService dataTracerService;
/**
* 分页查询发票信息
*/
public ResponseDTO<PageResult<InvoiceVO>> queryByPage(InvoiceQueryForm queryForm) {
queryForm.setDeletedFlag(Boolean.FALSE);
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<InvoiceVO> invoiceList = invoiceDao.queryPage(page, queryForm);
PageResult<InvoiceVO> pageResult = SmartPageUtil.convert2PageResult(page, invoiceList);
return ResponseDTO.ok(pageResult);
}
public ResponseDTO<List<InvoiceVO>> queryList(Long enterpriseId) {
InvoiceQueryForm queryForm = new InvoiceQueryForm();
queryForm.setDeletedFlag(Boolean.FALSE);
queryForm.setDisabledFlag(Boolean.FALSE);
queryForm.setEnterpriseId(enterpriseId);
List<InvoiceVO> invoiceList = invoiceDao.queryPage(null, queryForm);
return ResponseDTO.ok(invoiceList);
}
/**
* 查询发票信息详情
*/
public ResponseDTO<InvoiceVO> getDetail(Long invoiceId) {
// 校验发票信息是否存在
InvoiceVO invoiceVO = invoiceDao.getDetail(invoiceId, Boolean.FALSE);
if (Objects.isNull(invoiceVO)) {
return ResponseDTO.userErrorParam("发票信息不存在");
}
return ResponseDTO.ok(invoiceVO);
}
/**
* 新建发票信息
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> createInvoice(InvoiceAddForm createVO) {
Long enterpriseId = createVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseVO enterpriseVO = enterpriseService.getDetail(enterpriseId);
if (Objects.isNull(enterpriseVO)) {
return ResponseDTO.userErrorParam("企业不存在");
}
// 验证发票信息账号是否重复
InvoiceEntity validateInvoice = invoiceDao.queryByAccountNumber(enterpriseId, createVO.getAccountNumber(), null, Boolean.FALSE);
if (Objects.nonNull(validateInvoice)) {
return ResponseDTO.userErrorParam("发票信息账号重复");
}
// 数据插入
InvoiceEntity insertInvoice = SmartBeanUtil.copy(createVO, InvoiceEntity.class);
invoiceDao.insert(insertInvoice);
dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "新增发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(insertInvoice));
return ResponseDTO.ok();
}
/**
* 编辑发票信息
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> updateInvoice(InvoiceUpdateForm updateVO) {
Long enterpriseId = updateVO.getEnterpriseId();
// 校验企业是否存在
EnterpriseVO enterpriseVO = enterpriseService.getDetail(enterpriseId);
if (Objects.isNull(enterpriseVO)) {
return ResponseDTO.userErrorParam("企业不存在");
}
Long invoiceId = updateVO.getInvoiceId();
// 校验发票信息是否存在
InvoiceEntity invoiceDetail = invoiceDao.selectById(invoiceId);
if (Objects.isNull(invoiceDetail) || invoiceDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("发票信息不存在");
}
// 验证发票信息账号是否重复
InvoiceEntity validateInvoice = invoiceDao.queryByAccountNumber(updateVO.getEnterpriseId(), updateVO.getAccountNumber(), invoiceId, Boolean.FALSE);
if (Objects.nonNull(validateInvoice)) {
return ResponseDTO.userErrorParam("发票信息账号重复");
}
// 数据编辑
InvoiceEntity updateInvoice = SmartBeanUtil.copy(updateVO, InvoiceEntity.class);
invoiceDao.updateById(updateInvoice);
dataTracerService.addTrace(enterpriseId, DataTracerTypeEnum.OA_ENTERPRISE, "更新发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(invoiceDetail, updateInvoice));
return ResponseDTO.ok();
}
/**
* 删除发票信息
*/
@Transactional(rollbackFor = Exception.class)
public ResponseDTO<String> deleteInvoice(Long invoiceId) {
// 校验发票信息是否存在
InvoiceEntity invoiceDetail = invoiceDao.selectById(invoiceId);
if (Objects.isNull(invoiceDetail) || invoiceDetail.getDeletedFlag()) {
return ResponseDTO.userErrorParam("发票信息不存在");
}
invoiceDao.deleteInvoice(invoiceId, Boolean.TRUE);
dataTracerService.addTrace(invoiceDetail.getEnterpriseId(), DataTracerTypeEnum.OA_ENTERPRISE, "删除发票:" + DataTracerConst.HTML_BR + dataTracerService.getChangeContent(invoiceDetail));
return ResponseDTO.ok();
}
}

55
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java

@ -0,0 +1,55 @@
package net.lab1024.sa.admin.module.business.oa.invoice.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
/**
* OA发票信息新建
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Data
public class InvoiceAddForm {
@Schema(description = "开票抬头")
@NotBlank(message = "开票抬头不能为空")
@Length(max = 200, message = "开票抬头最多200字符")
private String invoiceHeads;
@Schema(description = "纳税人识别号")
@NotBlank(message = "纳税人识别号不能为空")
@Length(max = 200, message = "纳税人识别号最多200字符")
private String taxpayerIdentificationNumber;
@Schema(description = "银行账户")
@NotBlank(message = "银行账户不能为空")
@Length(max = 200, message = "银行账户最多200字符")
private String accountNumber;
@Schema(description = "开户行")
@NotBlank(message = "开户行不能为空")
@Length(max = 200, message = "开户行最多200字符")
private String bankName;
@Schema(description = "启用状态")
@NotNull(message = "启用状态不能为空")
private Boolean disabledFlag;
@Schema(description = "备注")
@Length(max = 500, message = "备注最多500字符")
private String remark;
@Schema(description = "企业")
@NotNull(message = "企业不能为空")
private Long enterpriseId;
@Schema(description = "创建人", hidden = true)
private Long createUserId;
@Schema(description = "创建人名称", hidden = true)
private String createUserName;
}

95
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java

@ -0,0 +1,95 @@
package net.lab1024.sa.admin.module.business.oa.invoice.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import net.lab1024.sa.base.module.support.datatracer.annoation.DataTracerFieldLabel;
import java.time.LocalDateTime;
/**
* OA发票信息
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Data
@TableName("t_oa_invoice")
public class InvoiceEntity {
/**
* 发票信息ID
*/
@TableId(type = IdType.AUTO)
private Long invoiceId;
/**
* 开票抬头
*/
@DataTracerFieldLabel("开票抬头")
private String invoiceHeads;
/**
* 纳税人识别号
*/
@DataTracerFieldLabel("纳税人识别号")
private String taxpayerIdentificationNumber;
/**
* 银行账户
*/
@DataTracerFieldLabel("银行账户")
private String accountNumber;
/**
* 开户行
*/
@DataTracerFieldLabel("开户行")
private String bankName;
/**
* 备注
*/
@DataTracerFieldLabel("备注")
private String remark;
/**
* 企业ID
*/
private Long enterpriseId;
/**
* 禁用状态
*/
@DataTracerFieldLabel("禁用状态")
private Boolean disabledFlag;
/**
* 删除状态
*/
@DataTracerFieldLabel("删除状态")
private Boolean deletedFlag;
/**
* 创建人ID
*/
private Long createUserId;
/**
* 创建人ID
*/
private String createUserName;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}

37
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java

@ -0,0 +1,37 @@
package net.lab1024.sa.admin.module.business.oa.invoice.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import org.hibernate.validator.constraints.Length;
import java.time.LocalDate;
/**
* OA发票信息查询
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Data
public class InvoiceQueryForm extends PageParam {
@Schema(description = "企业ID")
private Long enterpriseId;
@Schema(description = "关键字")
@Length(max = 200, message = "关键字最多200字符")
private String keywords;
@Schema(description = "开始时间")
private LocalDate startTime;
@Schema(description = "结束时间")
private LocalDate endTime;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "删除状态", hidden = true)
private Boolean deletedFlag;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.oa.invoice.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* OA发票信息编辑
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Data
public class InvoiceUpdateForm extends InvoiceAddForm {
@Schema(description = "发票信息ID")
@NotNull(message = "发票信息ID不能为空")
private Long invoiceId;
}

55
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java

@ -0,0 +1,55 @@
package net.lab1024.sa.admin.module.business.oa.invoice.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* OA发票信息
*
* @Date 2022-06-23 19:32:59
* @Author wzh
*/
@Data
public class InvoiceVO {
@Schema(description = "发票信息ID")
private Long invoiceId;
@Schema(description = "开票抬头")
private String invoiceHeads;
@Schema(description = "纳税人识别号")
private String taxpayerIdentificationNumber;
@Schema(description = "银行账户")
private String accountNumber;
@Schema(description = "开户行")
private String bankName;
@Schema(description = "备注")
private String remark;
@Schema(description = "企业")
private Long enterpriseId;
@Schema(description = "企业名称")
private String enterpriseName;
@Schema(description = "禁用状态")
private Boolean disabledFlag;
@Schema(description = "创建人ID")
private Long createUserId;
@Schema(description = "创建人名称")
private String createUserName;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

77
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/controller/LeaveController.java

@ -0,0 +1,77 @@
package net.lab1024.sa.admin.module.business.oa.leave.controller;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveAddForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveQueryForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveUpdateForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.vo.LeaveVO;
import net.lab1024.sa.admin.module.business.oa.leave.service.LeaveService;
import net.lab1024.sa.base.common.domain.ValidateList;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
/**
* OA 请假申请表 Controller
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@RestController
@Tag(name = "OA 请假申请表")
public class LeaveController {
@Resource
private LeaveService leaveService;
@Operation(summary = "分页查询")
@PostMapping("/leave/queryPage")
@SaCheckPermission("leave:query")
public ResponseDTO<PageResult<LeaveVO>> queryPage(@RequestBody @Valid LeaveQueryForm queryForm) {
return ResponseDTO.ok(leaveService.queryPage(queryForm));
}
@Operation(summary = "添加")
@PostMapping("/leave/add")
@SaCheckPermission("leave:add")
public ResponseDTO<String> add(@RequestBody @Valid LeaveAddForm addForm) {
addForm.setCreateUserId(Long.valueOf(SmartRequestUtil.getRequestUserId()));
return leaveService.add(addForm);
}
@Operation(summary = "更新")
@PostMapping("/leave/update")
@SaCheckPermission("leave:update")
public ResponseDTO<String> update(@RequestBody @Valid LeaveUpdateForm updateForm) {
return leaveService.update(updateForm);
}
@Operation(summary = "批量删除")
@PostMapping("/leave/batchDelete")
@SaCheckPermission("leave:delete")
public ResponseDTO<String> batchDelete(@RequestBody ValidateList<Long> idList) {
return leaveService.batchDelete(idList);
}
@Operation(summary = "单个删除")
@GetMapping("/leave/delete/{id}")
@SaCheckPermission("leave:delete")
public ResponseDTO<String> batchDelete(@PathVariable Long id) {
return leaveService.delete(id);
}
@GetMapping("/leave/{id}")
public ResponseDTO<LeaveVO> getDetail(@PathVariable Long id) {
return ResponseDTO.ok(leaveService.getDetail(id));
}
}

32
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/dao/LeaveDao.java

@ -0,0 +1,32 @@
package net.lab1024.sa.admin.module.business.oa.leave.dao;
import java.util.List;
import net.lab1024.sa.admin.module.business.oa.leave.domain.entity.LeaveEntity;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveQueryForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.vo.LeaveVO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
/**
* OA 请假申请表 Dao
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Mapper
public interface LeaveDao extends BaseMapper<LeaveEntity> {
/**
* 分页 查询
*
* @param page
* @param queryForm
* @return
*/
List<LeaveVO> queryPage(Page page, @Param("queryForm") LeaveQueryForm queryForm);
}

97
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/entity/LeaveEntity.java

@ -0,0 +1,97 @@
package net.lab1024.sa.admin.module.business.oa.leave.domain.entity;
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.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Data;
/**
* OA 请假申请表 实体类
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Data
@TableName("t_leave")
public class LeaveEntity {
/**
* 主键
*/
@TableId(type = IdType.AUTO)
private Long leaveId;
/**
* 请假类型
*/
private String type;
/**
* 请假原因
*/
private String reason;
/**
* 开始时间
*/
private LocalDate startTime;
/**
* 结束时间
*/
private LocalDate endTime;
/**
* 请假天数
*/
private Integer day;
/**
* 流程实例的id
*/
private Long instanceId;
/**
* 节点编码
*/
private String nodeCode;
/**
* 流程节点名称
*/
private String nodeName;
/**
* 节点类型0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关
*/
private Integer nodeType;
/**
* 流程状态0待提交 1审批中 2 审批通过 3自动通过 4终止 5作废 6撤销 7取回 8已完成 9已退回 10失效
*/
private String flowStatus;
private Boolean deletedFlag;
private Long createUserId;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
}

46
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/form/LeaveAddForm.java

@ -0,0 +1,46 @@
package net.lab1024.sa.admin.module.business.oa.leave.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Data;
/**
* OA 请假申请表 新建表单
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Data
public class LeaveAddForm {
@Schema(description = "请假类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "请假类型 不能为空")
private String type;
@Schema(description = "请假原因", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "请假原因 不能为空")
private String reason;
/**
* 开始时间
*/
private LocalDate startTime;
/**
* 结束时间
*/
private LocalDate endTime;
/**
* 请假天数
*/
private Integer day;
@Schema(description = "创建者")
private Long createUserId;
}

36
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/form/LeaveQueryForm.java

@ -0,0 +1,36 @@
package net.lab1024.sa.admin.module.business.oa.leave.domain.form;
import net.lab1024.sa.base.common.domain.PageParam;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* OA 请假申请表 分页查询表单
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class LeaveQueryForm extends PageParam {
@Schema(description = "请假类型")
private String type;
@Schema(description = "开始时间")
private LocalDate startTimeBegin;
@Schema(description = "开始时间")
private LocalDate startTimeEnd;
@Schema(description = "请假原因")
private String reason;
@Schema(description = "流程状态")
private String flowStatus;
}

47
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/form/LeaveUpdateForm.java

@ -0,0 +1,47 @@
package net.lab1024.sa.admin.module.business.oa.leave.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Data;
/**
* OA 请假申请表 更新表单
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Data
public class LeaveUpdateForm {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "主键 不能为空")
private Long leaveId;
@Schema(description = "请假类型", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "请假类型 不能为空")
private String type;
@Schema(description = "请假原因", requiredMode = Schema.RequiredMode.REQUIRED)
@NotBlank(message = "请假原因 不能为空")
private String reason;
/**
* 开始时间
*/
private LocalDate startTime;
/**
* 结束时间
*/
private LocalDate endTime;
/**
* 请假天数
*/
private Integer day;
}

59
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/domain/vo/LeaveVO.java

@ -0,0 +1,59 @@
package net.lab1024.sa.admin.module.business.oa.leave.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import java.time.LocalDateTime;
import lombok.Data;
/**
* OA 请假申请表 列表VO
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Data
public class LeaveVO {
@Schema(description = "主键")
private Long leaveId;
@Schema(description = "请假类型")
private String type;
@Schema(description = "请假原因")
private String reason;
/**
* 开始时间
*/
private LocalDate startTime;
/**
* 结束时间
*/
private LocalDate endTime;
@Schema(description = "请假天数")
private Integer day;
@Schema(description = "流程节点名称")
private String nodeName;
@Schema(description = "流程状态(0待提交 1审批中 2 审批通过 3自动通过 4终止 5作废 6撤销 7取回 8已完成 9已退回 10失效)")
private String flowStatus;
@Schema(description = "创建者")
private String createUserName;
@Schema(description = "创建时间")
private LocalDateTime createTime;
/**
* 流程实例的id
*/
@Schema(description = "流程实例的id")
private Long instanceId;
}

19
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/manager/LeaveManager.java

@ -0,0 +1,19 @@
package net.lab1024.sa.admin.module.business.oa.leave.manager;
import net.lab1024.sa.admin.module.business.oa.leave.domain.entity.LeaveEntity;
import net.lab1024.sa.admin.module.business.oa.leave.dao.LeaveDao;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* OA 请假申请表 Manager
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Service
public class LeaveManager extends ServiceImpl<LeaveDao, LeaveEntity> {
}

89
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/leave/service/LeaveService.java

@ -0,0 +1,89 @@
package net.lab1024.sa.admin.module.business.oa.leave.service;
import java.util.List;
import net.lab1024.sa.admin.module.business.oa.leave.dao.LeaveDao;
import net.lab1024.sa.admin.module.business.oa.leave.domain.entity.LeaveEntity;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveAddForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveQueryForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.form.LeaveUpdateForm;
import net.lab1024.sa.admin.module.business.oa.leave.domain.vo.LeaveVO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartPageUtil;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.PageResult;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
/**
* OA 请假申请表 Service
*
* @Author wzh
* @Date 2025-05-31 20:00:10
*/
@Service
public class LeaveService {
@Resource
private LeaveDao leaveDao;
/**
* 分页查询
*/
public PageResult<LeaveVO> queryPage(LeaveQueryForm queryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
List<LeaveVO> list = leaveDao.queryPage(page, queryForm);
return SmartPageUtil.convert2PageResult(page, list);
}
/**
* 添加
*/
public ResponseDTO<String> add(LeaveAddForm addForm) {
LeaveEntity leaveEntity = SmartBeanUtil.copy(addForm, LeaveEntity.class);
leaveDao.insert(leaveEntity);
return ResponseDTO.ok();
}
/**
* 更新
*
*/
public ResponseDTO<String> update(LeaveUpdateForm updateForm) {
LeaveEntity leaveEntity = SmartBeanUtil.copy(updateForm, LeaveEntity.class);
leaveDao.updateById(leaveEntity);
return ResponseDTO.ok();
}
/**
* 批量删除
*/
public ResponseDTO<String> batchDelete(List<Long> idList) {
if (CollectionUtils.isEmpty(idList)){
return ResponseDTO.ok();
}
leaveDao.deleteBatchIds(idList);
return ResponseDTO.ok();
}
/**
* 单个删除
*/
public ResponseDTO<String> delete(Long id) {
if (null == id){
return ResponseDTO.ok();
}
leaveDao.deleteById(id);
return ResponseDTO.ok();
}
public LeaveVO getDetail(Long id) {
LeaveEntity leaveEntity = leaveDao.selectById(id);
return SmartBeanUtil.copy(leaveEntity, LeaveVO.class);
}
}

33
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java

@ -0,0 +1,33 @@
package net.lab1024.sa.admin.module.business.oa.notice.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.lab1024.sa.base.common.enumeration.BaseEnum;
/**
* 公告通知 可见范围类型
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Getter
@AllArgsConstructor
public enum NoticeVisibleRangeDataTypeEnum implements BaseEnum {
/**
* 员工
*/
EMPLOYEE(1, "员工"),
/**
* 部门
*/
DEPARTMENT(2, "部门"),
;
private final Integer value;
private final String desc;
}

138
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java

@ -0,0 +1,138 @@
package net.lab1024.sa.admin.module.business.oa.notice.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.extra.servlet.JakartaServletUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.notice.domain.form.*;
import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*;
import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeEmployeeService;
import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeService;
import net.lab1024.sa.admin.module.business.oa.notice.service.NoticeTypeService;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.operatelog.annotation.OperateLog;
import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 公告通知新闻等等
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Tag(name = AdminSwaggerTagConst.Business.OA_NOTICE)
@RestController
@OperateLog
public class NoticeController {
@Resource
private NoticeService noticeService;
@Resource
private NoticeTypeService noticeTypeService;
@Resource
private NoticeEmployeeService noticeEmployeeService;
// --------------------- 通知公告类型 -------------------------
@Operation(summary = "通知公告类型-获取全部 @author 卓大")
@GetMapping("/oa/noticeType/getAll")
public ResponseDTO<List<NoticeTypeVO>> getAll() {
return ResponseDTO.ok(noticeTypeService.getAll());
}
@Operation(summary = "通知公告类型-添加 @author 卓大")
@GetMapping("/oa/noticeType/add/{name}")
public ResponseDTO<String> add(@PathVariable String name) {
return noticeTypeService.add(name);
}
@Operation(summary = "通知公告类型-修改 @author 卓大")
@GetMapping("/oa/noticeType/update/{noticeTypeId}/{name}")
public ResponseDTO<String> update(@PathVariable Long noticeTypeId, @PathVariable String name) {
return noticeTypeService.update(noticeTypeId, name);
}
@Operation(summary = "通知公告类型-删除 @author 卓大")
@GetMapping("/oa/noticeType/delete/{noticeTypeId}")
public ResponseDTO<String> deleteNoticeType(@PathVariable Long noticeTypeId) {
return noticeTypeService.delete(noticeTypeId);
}
// --------------------- 【管理】通知公告-------------------------
@Operation(summary = "【管理】通知公告-分页查询 @author 卓大")
@PostMapping("/oa/notice/query")
@SaCheckPermission("oa:notice:query")
public ResponseDTO<PageResult<NoticeVO>> query(@RequestBody @Valid NoticeQueryForm queryForm) {
return ResponseDTO.ok(noticeService.query(queryForm));
}
@Operation(summary = "【管理】通知公告-添加 @author 卓大")
@PostMapping("/oa/notice/add")
@RepeatSubmit
@SaCheckPermission("oa:notice:add")
public ResponseDTO<String> add(@RequestBody @Valid NoticeAddForm addForm) {
addForm.setCreateUserId(SmartRequestUtil.getRequestUserId());
return noticeService.add(addForm);
}
@Operation(summary = "【管理】通知公告-更新 @author 卓大")
@PostMapping("/oa/notice/update")
@RepeatSubmit
@SaCheckPermission("oa:notice:update")
public ResponseDTO<String> update(@RequestBody @Valid NoticeUpdateForm updateForm) {
return noticeService.update(updateForm);
}
@Operation(summary = "【管理】通知公告-更新详情 @author 卓大")
@GetMapping("/oa/notice/getUpdateVO/{noticeId}")
@SaCheckPermission("oa:notice:update")
public ResponseDTO<NoticeUpdateFormVO> getUpdateFormVO(@PathVariable Long noticeId) {
return ResponseDTO.ok(noticeService.getUpdateFormVO(noticeId));
}
@Operation(summary = "【管理】通知公告-删除 @author 卓大")
@GetMapping("/oa/notice/delete/{noticeId}")
@SaCheckPermission("oa:notice:delete")
public ResponseDTO<String> delete(@PathVariable Long noticeId) {
return noticeService.delete(noticeId);
}
// --------------------- 【员工】查看 通知公告 -------------------------
@Operation(summary = "【员工】通知公告-查看详情 @author 卓大")
@GetMapping("/oa/notice/employee/view/{noticeId}")
public ResponseDTO<NoticeDetailVO> view(@PathVariable Long noticeId, HttpServletRequest request) {
return noticeEmployeeService.view(
SmartRequestUtil.getRequestUserId(),
noticeId,
JakartaServletUtil.getClientIP(request),
request.getHeader("User-Agent")
);
}
@Operation(summary = "【员工】通知公告-查询全部 @author 卓大")
@PostMapping("/oa/notice/employee/query")
public ResponseDTO<PageResult<NoticeEmployeeVO>> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) {
return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm);
}
@Operation(summary = "【员工】通知公告-查询 查看记录 @author 卓大")
@PostMapping("/oa/notice/employee/queryViewRecord")
public ResponseDTO<PageResult<NoticeViewRecordVO>> queryViewRecord(@RequestBody @Valid NoticeViewRecordQueryForm noticeViewRecordQueryForm) {
return ResponseDTO.ok(noticeEmployeeService.queryViewRecord(noticeViewRecordQueryForm));
}
}

123
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java

@ -0,0 +1,123 @@
package net.lab1024.sa.admin.module.business.oa.notice.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity;
import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeEmployeeQueryForm;
import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeQueryForm;
import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeViewRecordQueryForm;
import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm;
import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeEmployeeVO;
import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVO;
import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeViewRecordVO;
import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVisibleRangeVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 公告通知新闻等等
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Mapper
public interface NoticeDao extends BaseMapper<NoticeEntity> {
// ================================= 数据范围相关 【子表】 =================================
/**
* 保存可见范围
*
*/
void insertVisibleRange(@Param("noticeId") Long noticeId, @Param("visibleRangeFormList") List<NoticeVisibleRangeForm> visibleRangeFormList);
/**
* 删除可见范围
*
*/
void deleteVisibleRange(@Param("noticeId") Long noticeId);
/**
* 相关可见范围
*
*/
List<NoticeVisibleRangeVO> queryVisibleRange(@Param("noticeId") Long noticeId);
// ================================= 通知公告【主表】 相关 =================================
/**
* 后管分页查询资讯
*
*/
List<NoticeVO> query(Page<?> page, @Param("query") NoticeQueryForm queryForm);
/**
* 更新删除状态
*
*/
void updateDeletedFlag(@Param("noticeId") Long noticeId);
// ================================= 通知公告【员工查看】 相关 =================================
/**
* 查询 员工 查看到的通知公告
*
*/
List<NoticeEmployeeVO> queryEmployeeNotice(Page<?> page,
@Param("requestEmployeeId") Long requestEmployeeId,
@Param("query") NoticeEmployeeQueryForm noticeEmployeeQueryForm,
@Param("requestEmployeeDepartmentIdList") List<Long> requestEmployeeDepartmentIdList,
@Param("deletedFlag") boolean deletedFlag,
@Param("administratorFlag") boolean administratorFlag,
@Param("departmentDataType") Integer departmentDataType,
@Param("employeeDataType") Integer employeeDataType
);
/**
* 查询 员工 未读的通知公告
*
*/
List<NoticeEmployeeVO> queryEmployeeNotViewNotice(Page<?> page,
@Param("requestEmployeeId") Long requestEmployeeId,
@Param("query") NoticeEmployeeQueryForm noticeEmployeeQueryForm,
@Param("requestEmployeeDepartmentIdList") List<Long> requestEmployeeDepartmentIdList,
@Param("deletedFlag") boolean deletedFlag,
@Param("administratorFlag") boolean administratorFlag,
@Param("departmentDataType") Integer departmentDataType,
@Param("employeeDataType") Integer employeeDataType
);
long viewRecordCount(@Param("noticeId")Long noticeId, @Param("employeeId")Long employeeId);
/**
* 查询通知公告的 查看记录
*/
List<NoticeViewRecordVO> queryNoticeViewRecordList(Page page,@Param("queryForm") NoticeViewRecordQueryForm noticeViewRecordQueryForm);
/**
* 保存查看记录
*/
void insertViewRecord(@Param("noticeId") Long noticeId, @Param("employeeId") Long employeeId, @Param("ip") String ip, @Param("userAgent") String userAgent,@Param("pageViewCount") Integer pageViewCount);
/**
* 更新查看记录
*/
void updateViewRecord(@Param("noticeId")Long noticeId, @Param("employeeId")Long requestEmployeeId,@Param("ip") String ip, @Param("userAgent")String userAgent);
/**
* 更新 浏览量
*
* @param noticeId 通知 id
* @param pageViewCountIncrement 页面浏览量的增量
* @param userViewCountIncrement 用户浏览量的增量
*/
void updateViewCount(@Param("noticeId")Long noticeId,@Param("pageViewCountIncrement") Integer pageViewCountIncrement, @Param("userViewCountIncrement")Integer userViewCountIncrement);
}

17
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java

@ -0,0 +1,17 @@
package net.lab1024.sa.admin.module.business.oa.notice.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeTypeEntity;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
/**
* 通知公告类型
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Mapper
public interface NoticeTypeDao extends BaseMapper<NoticeTypeEntity> {
}

111
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java

@ -0,0 +1,111 @@
package net.lab1024.sa.admin.module.business.oa.notice.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 通知公告
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Data
@TableName("t_notice")
public class NoticeEntity {
@TableId(type = IdType.AUTO)
private Long noticeId;
/**
* 类型
*/
private Long noticeTypeId;
/**
* 标题
*/
private String title;
/**
* 是否全部可见
*/
private Boolean allVisibleFlag;
/**
* 是否定时发布
*/
private Boolean scheduledPublishFlag;
/**
* 发布时间
*/
private LocalDateTime publishTime;
/**
* 内容 纯文本
*/
private String contentText;
/**
* 内容 html
*/
private String contentHtml;
/**
* 附件
* 多个英文逗号分隔
*/
private String attachment;
/**
* 页面浏览量
*/
private Integer pageViewCount;
/**
* 用户浏览量
*/
private Integer userViewCount;
/**
* 来源
*/
private String source;
/**
* 作者
*/
private String author;
/**
* 文号
*/
private String documentNumber;
/**
* 流程实例的id
*/
private Long instanceId;
/**
* 流程节点名称
*/
private String nodeName;
/**
* 流程状态
*/
private String flowStatus;
private Boolean deletedFlag;
private Long createUserId;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

38
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java

@ -0,0 +1,38 @@
package net.lab1024.sa.admin.module.business.oa.notice.domain.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
* 通知公告类型
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Data
@TableName("t_notice_type")
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class NoticeTypeEntity {
@TableId(type = IdType.AUTO)
private Long noticeTypeId;
/**
* 名称
*/
private String noticeTypeName;
private LocalDateTime updateTime;
private LocalDateTime createTime;
}

75
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java

@ -0,0 +1,75 @@
package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.base.common.json.deserializer.FileKeyVoDeserializer;
import org.hibernate.validator.constraints.Length;
import java.time.LocalDateTime;
import java.util.List;
/**
* 通知公告 添加表单
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Data
public class NoticeAddForm {
@Schema(description = "标题")
@NotBlank(message = "标题不能为空")
@Length(max = 200, message = "标题最多200字符")
private String title;
@Schema(description = "分类")
@NotNull(message = "分类不能为空")
private Long noticeTypeId;
@Schema(description = "是否全部可见")
@NotNull(message = "是否全部可见不能为空")
private Boolean allVisibleFlag;
@Schema(description = "是否定时发布")
@NotNull(message = "是否定时发布不能为空")
private Boolean scheduledPublishFlag;
@Schema(description = "发布时间")
@NotNull(message = "发布时间不能为空")
private LocalDateTime publishTime;
@Schema(description = "纯文本内容")
@NotNull(message = "文本内容不能为空")
private String contentText;
@Schema(description = "html内容")
@NotNull(message = "html内容不能为空")
private String contentHtml;
@Schema(description = "附件,多个英文逗号分隔|可选")
@Length(max = 1000, message = "最多1000字符")
@JsonDeserialize(using = FileKeyVoDeserializer.class)
private String attachment;
@Schema(description = "作者")
@NotBlank(message = "作者不能为空")
private String author;
@Schema(description = "来源")
@NotBlank(message = "标题不能为空")
private String source;
@Schema(description = "文号")
private String documentNumber;
@Schema(hidden = true)
private Long createUserId;
@Schema(description = "可见范围设置|可选")
@Valid
private List<NoticeVisibleRangeForm> visibleRangeList;
}

32
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java

@ -0,0 +1,32 @@
package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import java.time.LocalDate;
/**
* 通知公告 员工查询表单
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Data
public class NoticeEmployeeQueryForm extends PageParam {
@Schema(description = "标题、作者、来源、文号")
private String keywords;
@Schema(description = "分类")
private Long noticeTypeId;
@Schema(description = "发布-开始时间")
private LocalDate publishTimeBegin;
@Schema(description = "未读标识")
private Boolean notViewFlag;
@Schema(description = "发布-截止时间")
private LocalDate publishTimeEnd;
}

57
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java

@ -0,0 +1,57 @@
package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.base.common.domain.PageParam;
import java.time.LocalDate;
/**
* 通知公告 管理查询表单
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Data
public class NoticeQueryForm extends PageParam {
@Schema(description = "分类")
private Long noticeTypeId;
@Schema(description = "标题、作者、来源")
private String keywords;
@Schema(description = "文号")
private String documentNumber;
@Schema(description = "创建人")
private String createUserName;
/**
* 流程节点名称
*/
@Schema(description = "流程节点")
private String nodeName;
/**
* 流程状态
*/
@Schema(description = "流程状态")
private String flowStatus;
@Schema(description = "删除标识")
private Boolean deletedFlag;
@Schema(description = "创建-开始时间")
private LocalDate createTimeBegin;
@Schema(description = "创建-截止时间")
private LocalDate createTimeEnd;
@Schema(description = "发布-开始时间")
private LocalDate publishTimeBegin;
@Schema(description = "发布-截止时间")
private LocalDate publishTimeEnd;
}

36
smart-flow-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java

@ -0,0 +1,36 @@
package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
* 通知公告 更新表单
*
* @Date 2022-08-12 21:40:39
* @Author wzh
*/
@Data
public class NoticeUpdateForm extends NoticeAddForm {
@Schema(description = "id")
@NotNull(message = "通知id不能为空")
private Long noticeId;
/**
* 流程实例的id
*/
@Schema(description = "流程实例的id")
private Long instanceId;
/**
* 流程节点名称
*/
@Schema(description = "流程节点")
private String nodeName;
/**
* 流程状态
*/
@Schema(description = "流程状态")
private String flowStatus;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save