Browse Source

first commit

baishaojie 1 year ago
commit
5f572dc19b
100 changed files with 7166 additions and 0 deletions
  1. 26 0
      .gitignore
  2. 21 0
      LICENSE
  3. 101 0
      README.md
  4. 35 0
      smart-admin-api/.gitignore
  5. 363 0
      smart-admin-api/pom.xml
  6. 52 0
      smart-admin-api/sa-admin/pom.xml
  7. 33 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/SmartAdminApplication.java
  8. 13 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/common/AdminBaseController.java
  9. 177 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/common/PostRequestUtil.java
  10. 17 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/HttpConverterConfig.java
  11. 38 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java
  12. 34 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java
  13. 40 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java
  14. 50 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java
  15. 57 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java
  16. 17 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java
  17. 55 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java
  18. 40 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/listener/AdminStartupRunner.java
  19. 36 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java
  20. 67 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java
  21. 72 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java
  22. 44 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java
  23. 26 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategorySimpleDTO.java
  24. 67 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/entity/CategoryEntity.java
  25. 49 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java
  26. 25 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java
  27. 24 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java
  28. 40 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java
  29. 51 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java
  30. 120 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java
  31. 214 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java
  32. 220 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java
  33. 42 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java
  34. 75 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java
  35. 41 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java
  36. 75 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java
  37. 57 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java
  38. 46 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java
  39. 23 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java
  40. 56 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java
  41. 20 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/manager/GoodsManager.java
  42. 168 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java
  43. 74 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java
  44. 61 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java
  45. 162 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java
  46. 58 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java
  47. 95 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java
  48. 40 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java
  49. 23 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java
  50. 58 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java
  51. 115 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java
  52. 19 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java
  53. 252 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java
  54. 40 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java
  55. 72 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java
  56. 88 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java
  57. 51 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java
  58. 153 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java
  59. 101 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java
  60. 29 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java
  61. 35 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java
  62. 38 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java
  63. 23 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java
  64. 47 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java
  65. 20 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java
  66. 89 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java
  67. 80 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java
  68. 61 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java
  69. 158 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java
  70. 59 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java
  71. 98 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java
  72. 40 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java
  73. 23 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java
  74. 58 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java
  75. 30 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java
  76. 135 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java
  77. 144 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java
  78. 21 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java
  79. 99 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java
  80. 41 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java
  81. 78 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java
  82. 35 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java
  83. 48 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java
  84. 24 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java
  85. 32 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java
  86. 34 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java
  87. 84 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java
  88. 26 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java
  89. 24 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java
  90. 35 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java
  91. 75 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java
  92. 49 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java
  93. 29 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java
  94. 67 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java
  95. 159 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java
  96. 250 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java
  97. 87 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java
  98. 313 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/gm/audit/controller/AuditController.java
  99. 68 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/gm/audit/dao/AuditDao.java
  100. 32 0
      smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/gm/audit/domain/from/AddAuditFrom.java

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**
+!**/src/test/**
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### front ###
+**/dist
+**/node_modules
+**/.vscode
+

+ 21 - 0
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.

+ 101 - 0
README.md

@@ -0,0 +1,101 @@
+### SmartAdmin
+**SmartAdmin** 由 **河南·洛阳** [1024 创新实验室](https://www.1024lab.net/) 使用SpringBoot2 和 Vue3 Setup语法糖、 Composition Api (同时支持JavaScript和TypeScript双版本) ,开发出的一套简洁、易用的低代码中后台解决方案!  
+
+**我们开源一套漂亮的代码和一套整洁的代码规范**,让大家在这浮躁的代码世界里感受到一股把代码写好的清流!同时又让开发者节省大量的时间,减少加班,快乐工作,保持谦逊,保持学习,**热爱代码,更热爱生活!**
+
+
+在线预览:[https://preview.smartadmin.vip](https://preview.smartadmin.vip)  
+官方文档:[https://smartadmin.vip](https://smartadmin.vip)  
+
+### 理念与思想
+
+- 我们分享的不是徒劳无功的各种功能,而是必须有的功能,如:数据变动记录、系统说明文档、版本更新记录、意见反馈、日志、心跳、单号生成器等等。
+- 我们分享的还有经过上百家公司验证过的前端、后端、vue3等代码规范,好的规范能让我们敲下的每行代码更铿锵有力!
+- **我们推崇高质量的代码,身为开发,代码即利剑,键盘上一套行云流水,宛如侠客,事了拂衣去,深藏身与名。**
+- **我们推崇团队的高度配合默契、互相帮助,从不加班,而不是一看到别人的代码就头皮发麻,留其 [996.ICU](https://baike.baidu.com/item/996.ICU),我们热爱代码,更热爱生活**
+
+### 演示图
+<table>
+<tr>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/1-1.png"/></td>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/2-1.png"/></td>
+</tr>
+<tr>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/4-2.png"/></td>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/3-1.png"/></td>
+</tr>
+<tr>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/5-1.png"/></td>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/6-1.png"/></td>
+</tr>
+<tr>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/code1.png"/></td>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/code2.png"/></td>
+</tr>
+
+</table>
+
+### 技术体系
+
+- 前端:Vue3.2 + Vue-Router + Pinia + Ant Design Vue 3.X + Vite
+- 后端:Java8 + SpringBoot2.X + Mybatis-plus + jwt + druid + mysql
+
+### 功能特点
+
+- 表格:持久化表格自定义列、国际化、水印 等
+- OA办公:公司信息(发票、银行、员工等)、通知公告(阅读记录、次数等)
+- 文档:系统手册、意见反馈、更新记录 等
+- 监控:心跳监控、数据库监控
+- 日志:登录日志、操作日志(IP、浏览器、操作系统等设备信息)
+- 系统:员工、部门、角色、权限、菜单 等
+- 工具:文件管理、系统参数、数据字典、单号生成 等
+- 代码生成: 基于每个表的配置、在线预览代码、下载 等
+- 更多请查看:[SmartAdmin 业内独有功能亮点](https://smartadmin.vip/views/v2/base/FunctionFeature.html)
+
+### 前端特点
+
+- 提供 js 和 ts 双版本,目录结构及其清晰
+- setup语法糖下Composition Api 代码规范可能只有我们写对了
+- 前端常量维护: vue-enum,拒绝出现魔法数字,常量枚举不可维护的现象
+- 非常漂亮的首页、业内独有的帮助文档、数据变动记录、水印等
+- 业内独有的用户表格自定义列,且保存到数据库
+- 业内最好的api、常量、等写法
+- 独有的本地、开发、测试、预发布、生产 5个env环境配置文件
+- 业内代码最清晰的layout布局写法
+- 业内可能只有我们把main.js中的router加载方式写对了
+- 以上只是一些举例,更多灿若繁星的惊喜和细节,等待着你的发现![去查看](https://smartadmin.vip/views/v2/base/CodeFeature.html)
+
+
+### 后端特点
+
+- 高质量的 Java 代码、分包结构、和代码注释
+- 业内独创的请求返回码维护,非常值得一看
+- 四层架构(controller, service, manager, dao),为什么要有四层
+- vo, bo, form, entity ,各种 javabean 怎么区分和使用
+- 基于git diff的数据变更留痕功能,忘掉鸡肋的操作记录吧
+- 心跳服务,让你发现有哪些机器再跑,哪些人在偷偷的跑你的 Job
+- 支持接口加密解密注解、接口重复提交
+- maven多环境:开发、测试、预发布、生产 环境配置
+- smart-reload,为系统预留钩子,动态加载,在不重启程序前提下执行一些代码
+- 以上只是沧海一粟,更多的细节等待你的发现![去查看](https://smartadmin.vip/views/v2/base/CodeFeature.html)
+
+### 联系我们
+
+<table>
+<tr>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/zhuoda-wechat.jpg"/></td>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/xiaozhen-gzh.jpg"/></td>
+  <td><img src="https://gitee.com/lab1024/smart-admin/raw/master/%E6%88%AA%E5%9B%BE/zhuoda-wechat-money-v1.jpg"/></td>
+</tr>
+<tr>
+  <td style="text-align:center">骚扰“卓大”,拉你入群</td>
+  <td style="text-align:center">关注“小镇程序员”,代码与生活、技术与钱途</td>
+  <td style="text-align:center">请我们喝杯咖啡</td>
+</tr>
+</table>
+
+### 作者
+
+[1024创新实验室-主任:卓大](https://zhuoda.vip),混迹于各个技术圈,研究过计算机,熟悉点 java,略懂点前端。  
+[1024创新实验室(河南·洛阳)](https://1024lab.net) 致力于成为中原领先、国内一流的技术团队,以技术创新为驱动,合作各类项目(软件外包、技术顾问、培训等等)。
+

+ 35 - 0
smart-admin-api/.gitignore

@@ -0,0 +1,35 @@
+HELP.md
+target/
+
+velocity.log
+
+!.mvn/wrapper/maven-wrapper.jar
+
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+.DS_Store
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+
+### VS Code ###
+.vscode/

+ 363 - 0
smart-admin-api/pom.xml

@@ -0,0 +1,363 @@
+<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.1024lab</groupId>
+    <artifactId>sa-parent</artifactId>
+    <version>1.0.0</version>
+    <packaging>pom</packaging>
+
+    <name>sa-parent</name>
+    <description>SmartAdmin project</description>
+
+	<modules>
+        <module>sa-common</module>
+		<module>sa-admin</module>
+    </modules>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <springboot.version>2.7.5</springboot.version>
+        <spring-mock.version>2.0.8</spring-mock.version>
+        <mybatis-plus.version>3.5.2</mybatis-plus.version>
+        <p6spy.version>3.8.6</p6spy.version>
+        <swagger.version>2.7.0</swagger.version>
+        <fastjson.version>2.0.16</fastjson.version>
+        <druid.version>1.2.14</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>
+        <kaptcha.version>2.3.2</kaptcha.version>
+        <reflections.version>0.9.11</reflections.version>
+        <commons-io.version>2.6</commons-io.version>
+        <commons-lang3.version>3.12.0</commons-lang3.version>
+        <commons-collections4.version>4.4</commons-collections4.version>
+        <commons-codec.version>1.13</commons-codec.version>
+        <easypoi.version>4.2.0</easypoi.version>
+        <xerces.version>2.12.0</xerces.version>
+        <poi-scratchpad.version>4.1.1</poi-scratchpad.version>
+        <poi-ooxml-schemas.version>1.3</poi-ooxml-schemas.version>
+        <aws-java-sdk.version>1.11.842</aws-java-sdk.version>
+        <log4j-spring-boot.version>2.17.2</log4j-spring-boot.version>
+        <hutool.version>5.7.22</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>
+    </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>org.springframework</groupId>
+                <artifactId>spring-mock</artifactId>
+                <version>${spring-mock.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>commons-logging</artifactId>
+                        <groupId>commons-logging</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-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>p6spy</groupId>
+                <artifactId>p6spy</artifactId>
+                <version>${p6spy.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-swagger2</artifactId>
+                <version>${swagger.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>guava</artifactId>
+                        <groupId>com.google.guava</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-swagger-ui</artifactId>
+                <version>${swagger.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>${fastjson.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>druid</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>com.github.penggle</groupId>
+                <artifactId>kaptcha</artifactId>
+                <version>${kaptcha.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>
+                <artifactId>commons-codec</artifactId>
+                <groupId>commons-codec</groupId>
+                <version>${commons-codec.version}</version>
+            </dependency>
+
+            <!-- poi start -->
+            <dependency>
+                <groupId>cn.afterturn</groupId>
+                <artifactId>easypoi-spring-boot-starter</artifactId>
+                <version>${easypoi.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>cn.afterturn</groupId>
+                <artifactId>easypoi-web</artifactId>
+                <version>${easypoi.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>javassist</artifactId>
+                        <groupId>org.javassist</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>guava</artifactId>
+                        <groupId>com.google.guava</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <!-- sax 读取时候用到的 -->
+<!--            <dependency>-->
+<!--                <groupId>xerces</groupId>-->
+<!--                <artifactId>xercesImpl</artifactId>-->
+<!--                <version>${xerces.version}</version>-->
+<!--            </dependency>-->
+            <dependency>
+                <groupId>org.apache.poi</groupId>
+                <artifactId>poi-scratchpad</artifactId>
+                <version>${poi-scratchpad.version}</version>
+            </dependency>
+
+            <!-- Word 需要使用 -->
+
+
+            <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.logging.log4j</groupId>
+                <artifactId>log4j-spring-boot</artifactId>
+                <version>${log4j-spring-boot.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-->
+        </dependencies>
+
+    </dependencyManagement>
+
+    <build>
+        <finalName>${profiles.active}-${project.name}</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.2</version>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                    <encoding>UTF-8</encoding>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.16</version>
+                <configuration>
+                    <testFailureIgnore>true</testFailureIgnore>
+                    <skipTests>true</skipTests>
+                </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>

+ 52 - 0
smart-admin-api/sa-admin/pom.xml

@@ -0,0 +1,52 @@
+<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.1024lab</groupId>
+        <artifactId>sa-parent</artifactId>
+        <version>1.0.0</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>sa-admin</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
+
+    <name>sa-admin</name>
+    <description>sa-admin project</description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>net.1024lab</groupId>
+            <artifactId>sa-common</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.jsqlparser</groupId>
+            <artifactId>jsqlparser</artifactId>
+            <version>4.4</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>net.lab1024.sa.admin.SmartAdminApplication</mainClass>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 33 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/SmartAdminApplication.java

@@ -0,0 +1,33 @@
+package net.lab1024.sa.admin;
+
+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 项目启动类
+ *
+ * @Author 1024创新实验室-主任:卓大
+ * @Date 2022-08-29 21:00:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@EnableCaching
+@EnableScheduling
+@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
+@ComponentScan(basePackages = {"net.lab1024.sa"})
+@MapperScan(value = "net.lab1024.sa", annotationClass = Mapper.class)
+@SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class })
+public class SmartAdminApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(SmartAdminApplication.class, args);
+    }
+}

+ 13 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/common/AdminBaseController.java

@@ -0,0 +1,13 @@
+package net.lab1024.sa.admin.common;
+
+/**
+ * admin 相关的父类
+ *
+ * @Author 1024创新实验室-主任:卓大
+ * @Date 2022-06-10 21:00:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+public class AdminBaseController {
+}

+ 177 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/common/PostRequestUtil.java

@@ -0,0 +1,177 @@
+package net.lab1024.sa.admin.common;
+
+import lombok.extern.slf4j.Slf4j;
+
+import net.lab1024.sa.admin.module.gm.eq.domain.from.EquipmentTplnrFrom;
+import net.lab1024.sa.admin.module.gm.maintain.domain.vo.MaintainDetailsVo;
+import net.lab1024.sa.admin.module.gm.repair.service.RepairService;
+import org.json.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.xml.bind.DatatypeConverter;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+
+@RestController
+@Slf4j
+@Service
+public class PostRequestUtil {
+    /**
+     * 发送 POST 请求
+     *
+     * @param urlStr      请求 URL
+     * @param contentType 请求体类型
+     * @param body        请求体内容
+     * @return 响应内容
+     * @throws Exception 发送请求出错抛出异常
+     */
+    public static String SendPost(String urlStr, String contentType, String body) throws Exception {
+        // 创建连接
+        URL url = new URL(urlStr);
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setRequestMethod("POST");
+        connection.setRequestProperty("Content-Type", contentType);
+
+        String encoding = DatatypeConverter.printBase64Binary("gmmy_pmapp:1234qwer".getBytes("UTF-8"));  //username  password 自行修改  中间":"不可少
+        connection.setRequestProperty("Authorization", "Basic " + encoding);
+//        connection.
+
+        // 设置请求体
+        byte[] requestBodyBytes = body.getBytes(StandardCharsets.UTF_8);
+        connection.setDoOutput(true);
+        connection.setRequestProperty("Content-Length", Integer.toString(requestBodyBytes.length));
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(requestBodyBytes);
+        outputStream.close();
+
+        // 发送请求并获取响应
+        int responseCode = connection.getResponseCode();
+
+
+        if (responseCode == HttpURLConnection.HTTP_OK) {
+//            String response = connection.getInputStream().toString();
+
+
+//            String response = new String(connection.getInputStream()., StandardCharsets.UTF_8);
+            BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            String inputLine;
+            StringBuffer response = new StringBuffer();
+            while ((inputLine = in.readLine()) != null) {
+                response.append(inputLine);
+            }
+            in.close();
+            String responseBody = response.toString();
+            return response.toString();
+        } else {
+            throw new RuntimeException("POST request failed with code " + responseCode);
+        }
+    }
+
+    public static <T> List<T> Paginate(List<T> items, int pageSize, int pageNumber) {
+        if (pageNumber <= 0) { // Check if pageNumber is valid
+            throw new IllegalArgumentException("Invalid page number: " + pageNumber);
+        }
+        int fromIndex = (pageNumber - 1) * pageSize;
+        if (fromIndex >= items.size()) {
+            return Collections.emptyList();
+        }
+        int toIndex = Math.min(fromIndex + pageSize, items.size());
+        return items.subList(fromIndex, toIndex);
+    }
+
+
+    //    public List<Map<String,Object>> parseStringToListMap(String res) throws Exception{
+//        List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
+//        JSONObject jsonResult = new JSONObject(res);
+//        Iterator<String> nameItr = jsonResult.keys();
+//        while (nameItr.hasNext()) {
+//            String name = nameItr.next();
+//            if(name.equals("data")){
+//                String data=jsonResult.getString(name);
+//                JSONArray jsonArr = JSONArray.fromObject(data);
+//                for(int s=0;s<jsonArr.size();s++){//便利取到每个map
+//                    Map<String,Object> map = new HashMap<String,Object>();
+//                    String vas= jsonArr.get(s)==null?"":jsonArr.get(s).toString();
+//                    JSONObject jr=new JSONObject(vas);
+//                    Iterator<String> nir = jr.keys();
+//                    while (nir.hasNext()) {//取到map里的每个值
+//                        String json2 = nir.next();
+//                        String value= jr.getString(json2);
+//                        map.put(json2, value);
+//                    }
+//                    list.add(map);
+//                }
+//            }
+//        }
+//        return list;
+//    }
+
+
+
+
+//    @Autowired
+//    private RepairService repairService;
+//    public boolean MaintainSapSync(String res) throws Exception {
+//        Map<String, Object> req = new HashMap<>();
+//        List<Map<String, Object>> itemList = new ArrayList<>();
+//        Map<String, Object> sapReq = new HashMap<>();
+//        MaintainDetailsVo maintain =  repairService.GetRepairDetails(from.getWxCode());
+//
+//        sapReq.put("AUFPL",maintain.getSapCode());
+////        sapReq.put("AUART",from.getQmart());
+//        sapReq.put("ERDAT",maintain.getQMDAT());
+//        sapReq.put("KTEXT",maintain.getQMTXT());
+//        sapReq.put("BUKRS",maintain.getCompanyCode());
+//        sapReq.put("IWERK",maintain.getIwerk());
+//        sapReq.put("EQUNR",maintain.getEQUNR());
+//        sapReq.put("KOSTV",maintain.getCostCenter());
+////        sapReq.put("PRCTR",maintain.getPriok());
+//        sapReq.put("PRVAL",maintain.getPRIOK());
+////        sapReq.put("ILART",maintain.getRevnr());
+//        sapReq.put("REVNR",from.getRevnr());
+//        sapReq.put("VAPLZ",maintain.getLgwid1());
+//
+//
+//        List<Map<String, Object>> itemList1 = new ArrayList<>();
+//        Map<String, Object> sapReq1 = new HashMap<>();
+//        sapReq1.put("AUFPL",maintain.getSapCode());
+//        sapReq1.put("PREIS",from.getOutsource());
+//        sapReq1.put("PEINH",from.getPrice_unit());
+//        itemList1.add(sapReq1);
+//        sapReq.put("Item1",itemList1);
+//
+//        EquipmentTplnrFrom query = new EquipmentTplnrFrom();
+//        query.setPageNum(0);
+//        query.setPageSize(0);
+//        Page pageParam = SmartPageUtil.convert2PageQuery(query);
+//        List<PartapplyVo> partapplyList = partapplyService.getPartapplyList(pageParam, "",from.getWxCode(),"1");
+//
+//        List<Map<String, Object>> itemList2 = new ArrayList<>();
+//        for (PartapplyVo partapplyVo : partapplyList) {
+//            Map<String, Object> sapReq2= new HashMap<>();
+//
+//            sapReq2.put("AUFPL",maintain.getSapCode());
+//            sapReq2.put("MATNR",partapplyVo.getPartCode());
+//            sapReq2.put("MAKTX",partapplyVo.getPartName());
+//            sapReq2.put("BDMNG",partapplyVo.getAmount());
+//            sapReq2.put("BDTER",partapplyVo.getApplyDate());
+//            sapReq2.put("MEINS",partapplyVo.getUnit());
+//            itemList2.add(sapReq1);
+//        }
+//        sapReq.put("Item2",itemList2);
+//        return true;
+//    }
+}

+ 17 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/HttpConverterConfig.java

@@ -0,0 +1,17 @@
+package net.lab1024.sa.admin.config;
+
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class HttpConverterConfig implements WebMvcConfigurer {
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        //其中image表示访问的前缀。"file:F:/img/"是文件真实的存储路径
+        registry.addResourceHandler("/image/**").addResourceLocations("file:D:/img/");
+    }
+
+}

+ 38 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/JweAspectConfig.java

@@ -0,0 +1,38 @@
+package net.lab1024.sa.admin.config;
+
+import net.lab1024.sa.common.common.domain.RequestUser;
+import net.lab1024.sa.common.common.util.SmartRequestUtil;
+import net.lab1024.sa.common.module.support.jwe.JweAspect;
+import net.lab1024.sa.common.module.support.jwe.JweUserKey;
+import net.lab1024.sa.common.module.support.operatelog.core.OperateLogAspect;
+import net.lab1024.sa.common.module.support.operatelog.core.OperateLogConfig;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 操作日志切面 配置
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022-05-30 21:22:12
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net )
+ */
+@Configuration
+public class JweAspectConfig {
+
+    /**
+     * 配置信息
+     */
+    @Bean
+    public JweAspect jweConfig() {
+        return new JweAspect((request -> {
+            RequestUser requestUser = SmartRequestUtil.getRequestUser();
+            JweUserKey userKey = new JweUserKey();
+            userKey.setUserId(requestUser.getUserId());
+            userKey.setUserName(requestUser.getUserName());
+            userKey.setExtData(requestUser.getUserType().getValue().toString());
+            return userKey;
+        }));
+    }
+}

+ 34 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/OperateLogAspectConfig.java

@@ -0,0 +1,34 @@
+package net.lab1024.sa.admin.config;
+
+import net.lab1024.sa.common.common.domain.RequestUser;
+import net.lab1024.sa.common.common.util.SmartRequestUtil;
+import net.lab1024.sa.common.module.support.operatelog.core.OperateLogAspect;
+import net.lab1024.sa.common.module.support.operatelog.core.OperateLogConfig;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 操作日志切面 配置
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022-05-30 21:22:12
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net )
+ */
+@Configuration
+public class OperateLogAspectConfig extends OperateLogAspect{
+
+    /**
+     * 配置信息
+     * @return
+     */
+    @Override
+    public OperateLogConfig getOperateLogConfig() {
+        OperateLogConfig config = OperateLogConfig.builder().corePoolSize(4).queueCapacity(1000).build();
+        return config;
+    }
+
+
+}

+ 40 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityConfig.java

@@ -0,0 +1,40 @@
+package net.lab1024.sa.admin.config;
+
+import net.lab1024.sa.admin.module.system.login.service.LoginService;
+import net.lab1024.sa.common.common.security.AbstractSecurityConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.core.userdetails.UserDetails;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.function.BiFunction;
+
+/**
+ * 权限配置
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022-05-30 21:22:12
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net )
+ */
+@Configuration
+public class SecurityConfig extends AbstractSecurityConfig {
+    /**
+     * 获取TOKEN 解析类
+     */
+    @Autowired
+    private LoginService loginService;
+
+    @Override
+    protected BiFunction<String, HttpServletRequest, UserDetails> userFunction() {
+        return (token, request) -> loginService.getLoginUserDetail(token, request);
+    }
+
+    @Override
+    protected String[] getAuthenticatedUrlPatterns() {
+        return new String[]{"/**"};
+    }
+
+
+}

+ 50 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/config/SecurityMethodConfig.java

@@ -0,0 +1,50 @@
+package net.lab1024.sa.admin.config;
+
+import net.lab1024.sa.admin.module.system.login.domain.LoginEmployeeDetail;
+import net.lab1024.sa.common.common.annoation.SaAuth;
+import net.lab1024.sa.common.common.security.SecurityMethodSource;
+import net.lab1024.sa.common.common.security.SecurityPermissionCheckService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.access.expression.method.ExpressionBasedAnnotationAttributeFactory;
+import org.springframework.security.access.method.MethodSecurityMetadataSource;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
+import org.springframework.security.core.Authentication;
+
+/**
+ * 1、以类名加方法名为权限字符串的校验模式 <br>
+ * 2、重写MethodSecurityMetadataSource将优化security配置,只需在方法上加上@saAuth注解,方法上就会存在权限(权限字符串为类名加方法名),而无需另外手动设置,减轻后端开发成本<br>
+ * 3、security将不再依据权限字符串进行权限控制,<br>
+ * 4、security将依据对应权限字符串下的接口权限进行控制 <br>
+ * 5、采用此配置原@PreAuthorize依然有效 <br>
+ * 6、如若无需此配置,需将@EnableGlobalMethodSecurity注解添加至SecurityConfig类上
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2021-08-31 0:01
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net )
+ */
+@EnableGlobalMethodSecurity(prePostEnabled = true)
+public class SecurityMethodConfig extends GlobalMethodSecurityConfiguration {
+
+    @Bean(SaAuth.saAuth)
+    public SecurityPermissionCheckService securityPermissionCheckService() {
+        return new SecurityPermissionCheckService() {
+            @Override
+            public boolean checkPermission(Authentication authentication, String permission) {
+                LoginEmployeeDetail loginEmployeeDetail = (LoginEmployeeDetail) authentication.getPrincipal();
+                if (loginEmployeeDetail.getAdministratorFlag()) {
+                    return true;
+                }
+                return super.permissionJudge(loginEmployeeDetail, permission);
+            }
+        };
+    }
+
+    @Override
+    public MethodSecurityMetadataSource customMethodSecurityMetadataSource() {
+        ExpressionBasedAnnotationAttributeFactory attributeFactory = new ExpressionBasedAnnotationAttributeFactory(this.getExpressionHandler());
+        return new SecurityMethodSource(attributeFactory, SaAuth.saAuth);
+    }
+}

+ 57 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminCacheConst.java

@@ -0,0 +1,57 @@
+package net.lab1024.sa.admin.constant;
+
+import net.lab1024.sa.common.constant.CacheKeyConst;
+
+/**
+ * 缓存 key
+ *
+ * @Author 1024创新实验室-主任:卓大
+ * @Date 2022-01-07 18:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+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";
+    }
+
+}

+ 17 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminRedisKeyConst.java

@@ -0,0 +1,17 @@
+package net.lab1024.sa.admin.constant;
+
+import net.lab1024.sa.common.constant.RedisKeyConst;
+
+/**
+ * redis key 常量类
+ *
+ * @Author 1024创新实验室-主任:卓大
+ * @Date 2022-01-07 18:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+public class AdminRedisKeyConst extends RedisKeyConst {
+
+
+}

+ 55 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/constant/AdminSwaggerTagConst.java

@@ -0,0 +1,55 @@
+package net.lab1024.sa.admin.constant;
+
+import net.lab1024.sa.common.constant.SwaggerTagConst;
+
+/**
+ * swagger
+ *
+ * @Author 1024创新实验室:罗伊
+ * @Date 2022-01-07 18:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+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_DATA_TRACER = "系统-";
+    }
+
+
+}

+ 40 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/listener/AdminStartupRunner.java

@@ -0,0 +1,40 @@
+package net.lab1024.sa.admin.listener;
+
+import lombok.extern.slf4j.Slf4j;
+import net.lab1024.sa.common.common.code.ErrorCodeRegister;
+import net.lab1024.sa.common.config.ScheduleConfig;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * admin 应用启动加载
+ *
+ * @Author 1024创新实验室-主任:卓大
+ * @Date 2021-08-26 18:46:32
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Slf4j
+@Component
+public class AdminStartupRunner implements CommandLineRunner {
+
+    @Autowired
+    private ScheduleConfig scheduleConfig;
+
+    @Override
+    public void run(String... args) {
+
+        // 初始化状态码
+        int codeCount = ErrorCodeRegister.initialize();
+
+        //TODO <卓大> :根据实际情况来决定是否开启定时任务
+        String destroySchedules = "Spring 定时任务 @Schedule 已启动";
+//        destroySchedules = scheduleConfig.destroy();
+
+        log.info("\n ---------------【1024创新实验室 温馨提示:】 ErrorCode 共计完成初始化: {}个!---------------" +
+                 "\n ---------------【1024创新实验室 温馨提示:】 {}---------------\n", codeCount, destroySchedules);
+
+    }
+}

+ 36 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/constant/CategoryTypeEnum.java

@@ -0,0 +1,36 @@
+package net.lab1024.sa.admin.module.business.category.constant;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import net.lab1024.sa.common.common.enumeration.BaseEnum;
+
+/**
+ * 分类类型 枚举
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@AllArgsConstructor
+@Getter
+public enum CategoryTypeEnum implements BaseEnum {
+
+    /**
+     * 1 商品
+     */
+    GOODS(1, "商品"),
+
+    /**
+     * 2 自定义
+     */
+    CUSTOM(2, "自定义"),
+
+    ;
+
+    private final Integer value;
+
+    private final String desc;
+}

+ 67 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/controller/CategoryController.java

@@ -0,0 +1,67 @@
+package net.lab1024.sa.admin.module.business.category.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.lab1024.sa.admin.common.AdminBaseController;
+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.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 类目
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@OperateLog
+@RestController
+@Api(tags = AdminSwaggerTagConst.Business.MANAGER_CATEGORY)
+public class CategoryController extends AdminBaseController {
+
+    @Autowired
+    private CategoryService categoryService;
+
+    @ApiOperation("添加类目 @author 胡克")
+    @PostMapping("/category/add")
+    public ResponseDTO<String> add(@RequestBody @Valid CategoryAddForm addForm) {
+        return categoryService.add(addForm);
+    }
+
+    @ApiOperation("更新类目 @author 胡克")
+    @PostMapping("/category/update")
+    public ResponseDTO<String> update(@RequestBody @Valid CategoryUpdateForm updateForm) {
+        return categoryService.update(updateForm);
+    }
+
+    @ApiOperation("查询类目详情 @author 胡克")
+    @GetMapping("/category/{categoryId}")
+    public ResponseDTO<CategoryVO> queryDetail(@PathVariable Long categoryId) {
+        return categoryService.queryDetail(categoryId);
+    }
+
+    @ApiOperation("查询类目层级树 @author 胡克")
+    @PostMapping("/category/tree")
+    public ResponseDTO<List<CategoryTreeVO>> queryTree(@RequestBody @Valid CategoryTreeQueryForm queryForm) {
+        return categoryService.queryTree(queryForm);
+    }
+
+    @ApiOperation("删除类目 @author 胡克")
+    @GetMapping("/category/delete/{categoryId}")
+    public ResponseDTO<String> delete(@PathVariable Long categoryId) {
+        return categoryService.delete(categoryId);
+    }
+}

+ 72 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/dao/CategoryDao.java

@@ -0,0 +1,72 @@
+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
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Component
+@Mapper
+public interface CategoryDao extends BaseMapper<CategoryEntity> {
+
+    /**
+     * 根据父级id 类型 查询子类
+     *
+     * @param parentIdList
+     * @param deletedFlag
+     * @return
+     */
+    List<CategoryEntity> queryByParentId(@Param("parentIdList") List<Long> parentIdList,
+                                         @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 根据父级id 类型 查询子类
+     *
+     * @param parentIdList
+     * @param categoryType {@link CategoryTypeEnum}
+     * @param deletedFlag
+     * @return
+     */
+    List<CategoryEntity> queryByParentIdAndType(@Param("parentIdList") List<Long> parentIdList,
+                                         @Param("categoryType") Integer categoryType,
+                                         @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 某个类型的所有
+     * @param categoryType
+     * @param deletedFlag
+     * @return
+     */
+    List<CategoryEntity> queryByType(@Param("categoryType") Integer categoryType,
+                                                @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 根据类型和id查询
+     * @param categoryType
+     * @param categoryId
+     * @return
+     */
+    CategoryEntity selectByTypeAndId(@Param("categoryType") Integer categoryType, @Param("categoryId") Long categoryId);
+
+    /**
+     * 查看类目 具体条件 看sql
+     *
+     * @param entity
+     * @return
+     */
+    CategoryEntity selectOne(CategoryEntity entity);
+
+}

+ 44 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/dto/CategoryBaseDTO.java

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

+ 26 - 0
smart-admin-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.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 类目 基础属性 DTO 类
+ *
+ * @author 胡克
+ * @date 2021/1/20 16:17
+ */
+@Data
+public class CategorySimpleDTO {
+
+    @ApiModelProperty("类目id")
+    private Long categoryId;
+
+    @ApiModelProperty("类目名称")
+    private String categoryName;
+
+    @ApiModelProperty("类目层级全称")
+    private String categoryFullName;
+
+    @ApiModelProperty("父级id")
+    private Long parentId;
+}

+ 67 - 0
smart-admin-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.time.LocalDateTime;
+
+/**
+ * 类目 实体类
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+@TableName("t_category")
+public class CategoryEntity {
+
+    @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;
+}

+ 49 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryAddForm.java

@@ -0,0 +1,49 @@
+package net.lab1024.sa.admin.module.business.category.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
+import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 类目 添加
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class CategoryAddForm {
+
+    @ApiModelProperty(value = "类目名称", required = true)
+    @NotBlank(message = "类目名称不能为空")
+    @Length(max = 20, message = "类目名称最多20字符")
+    private String categoryName;
+
+    @ApiModelPropertyEnum(desc = "分类类型", value = CategoryTypeEnum.class)
+    @CheckEnum(value = CategoryTypeEnum.class, required = true, message = "分类错误")
+    private Integer categoryType;
+
+    @ApiModelProperty("父级类目id|可选")
+    private Long parentId;
+
+    @ApiModelProperty("排序|可选")
+    private Integer sort;
+
+    @ApiModelProperty("备注|可选")
+    @Length(max = 200, message = "备注最多200字符")
+    private String remark;
+
+    @ApiModelProperty("禁用状态")
+    @NotNull(message = "禁用状态不能为空")
+    private Boolean disabledFlag;
+
+}

+ 25 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryTreeQueryForm.java

@@ -0,0 +1,25 @@
+package net.lab1024.sa.admin.module.business.category.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+
+/**
+ * 类目 层级树查询
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class CategoryTreeQueryForm {
+
+    @ApiModelPropertyEnum(desc = "分类类型|可选", value = CategoryTypeEnum.class)
+    private Integer categoryType;
+
+    @ApiModelProperty("父级类目id|可选")
+    private Long parentId;
+}

+ 24 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/form/CategoryUpdateForm.java

@@ -0,0 +1,24 @@
+package net.lab1024.sa.admin.module.business.category.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 类目 更新
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class CategoryUpdateForm extends CategoryAddForm {
+
+    @ApiModelProperty("类目id")
+    @NotNull(message = "类目id不能为空")
+    private Long categoryId;
+}

+ 40 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryTreeVO.java

@@ -0,0 +1,40 @@
+package net.lab1024.sa.admin.module.business.category.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 类目 层级树 vo
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class CategoryTreeVO {
+
+    @ApiModelProperty("类目id")
+    private Long categoryId;
+
+    @ApiModelProperty("类目名称")
+    private String categoryName;
+
+    @ApiModelProperty("类目层级全称")
+    private String categoryFullName;
+
+    @ApiModelProperty("父级id")
+    private Long parentId;
+
+    @ApiModelProperty("类目id")
+    private Long value;
+
+    @ApiModelProperty("类目名称")
+    private String label;
+
+    @ApiModelProperty("子类")
+    private List<CategoryTreeVO> children;
+}

+ 51 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/domain/vo/CategoryVO.java

@@ -0,0 +1,51 @@
+package net.lab1024.sa.admin.module.business.category.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.category.constant.CategoryTypeEnum;
+import net.lab1024.sa.admin.module.business.category.domain.dto.CategoryBaseDTO;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+/**
+ * 类目
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class CategoryVO {
+
+    @ApiModelProperty(value = "类目名称", required = true)
+    private String categoryName;
+
+    @ApiModelPropertyEnum(desc = "分类类型", value = CategoryTypeEnum.class)
+    private Integer categoryType;
+
+    @ApiModelProperty("父级类目id|可选")
+    private Long parentId;
+
+    @ApiModelProperty("排序|可选")
+    private Integer sort;
+
+    @ApiModelProperty("备注|可选")
+    private String remark;
+
+    @ApiModelProperty("禁用状态")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty("类目id")
+    private Long categoryId;
+
+    private LocalDateTime updateTime;
+
+    private LocalDateTime createTime;
+}

+ 120 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/manager/CategoryCacheManager.java

@@ -0,0 +1,120 @@
+package net.lab1024.sa.admin.module.business.category.manager;
+
+import com.google.common.collect.Lists;
+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.common.common.constant.StringConst;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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;
+
+/**
+ * 类目 查询 缓存
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+@Slf4j
+public class CategoryCacheManager {
+
+
+    @Autowired
+    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");
+    }
+
+    /**
+     * 查詢类目
+     *
+     * @param categoryId
+     * @return
+     */
+    @Cacheable(AdminCacheConst.CATEGORY.CATEGORY_ENTITY)
+    public CategoryEntity queryCategory(Long categoryId) {
+        return categoryDao.selectById(categoryId);
+    }
+
+    /**
+     * 查询类目 子级
+     *
+     * @param categoryId
+     * @return
+     */
+    @Cacheable(AdminCacheConst.CATEGORY.CATEGORY_SUB)
+    public List<CategoryEntity> querySubCategory(Long categoryId) {
+        return categoryDao.queryByParentId(Lists.newArrayList(categoryId), false);
+    }
+
+
+    /**
+     * 查询类目 层级树
+     * 优先查询缓存
+     *
+     * @return
+     */
+    @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;
+    }
+
+    /**
+     * 递归查询设置类目子类
+     * 从缓存查询子类
+     *
+     * @param 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);
+        });
+    }
+
+
+}

+ 214 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryQueryService.java

@@ -0,0 +1,214 @@
+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 lombok.extern.slf4j.Slf4j;
+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.dto.CategorySimpleDTO;
+import net.lab1024.sa.admin.module.business.category.manager.CategoryCacheManager;
+import net.lab1024.sa.common.common.constant.StringConst;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 类目 查询 业务类
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+@Slf4j
+public class CategoryQueryService {
+
+    private static final Long DEFAULT_CATEGORY_PARENT_ID = 0L;
+
+    @Autowired
+    private CategoryDao categoryDao;
+
+    @Autowired
+    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集合 查询未删除的类目集合
+     *
+     * @param categoryIdList
+     * @return
+     */
+    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 递归查询
+     * 同时存入缓存
+     * 注意:查询出来的集合 不包含传递的父类参数
+     *
+     * @param categoryIdList
+     */
+    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;
+    }
+
+
+    /**
+     * 处理类目名称
+     *
+     * @param 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 查询类目名称
+     *
+     * @param categoryId
+     * @return
+     */
+    public String queryCategoryName(Long categoryId) {
+        CategoryEntity categoryEntity = categoryCacheManager.queryCategory(categoryId);
+        if (null == categoryEntity || categoryEntity.getDeletedFlag()) {
+            return null;
+        }
+        return categoryEntity.getCategoryName();
+    }
+
+    /**
+     * 根据类目id 查询类目详情 包含类目全称 如:医考/医师资格/临床执业
+     *
+     * @param categoryId
+     * @return
+     */
+    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:特别注意返回的集合中 包含自己
+     *
+     * @param categoryId
+     * @return
+     */
+    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;
+    }
+
+    /**
+     * 查询 分类全称 如:医考/医师资格/临床执业
+     *
+     * @param categoryId
+     * @return
+     */
+    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);
+    }
+
+    /**
+     * 查询 分类全称 如:医考/医师资格/临床执业
+     *
+     * @param categoryIdList
+     * @return
+     */
+    public Map<Long, String> queryFullName(List<Long> categoryIdList) {
+        if (CollectionUtils.isEmpty(categoryIdList)) {
+            return Collections.EMPTY_MAP;
+        }
+        // 循环内查询的缓存 还ok
+        return categoryIdList.stream().collect(Collectors.toMap(Function.identity(), this::queryFullName));
+    }
+
+}

+ 220 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/category/service/CategoryService.java

@@ -0,0 +1,220 @@
+package net.lab1024.sa.admin.module.business.category.service;
+
+import com.google.common.collect.Lists;
+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.common.common.code.UserErrorCode;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.math.NumberUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 类目
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021/08/05 21:26:58
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class CategoryService {
+
+    @Autowired
+    private CategoryDao categoryDao;
+
+    @Autowired
+    private CategoryQueryService categoryQueryService;
+
+    @Autowired
+    private CategoryCacheManager categoryCacheManager;
+
+    /**
+     * 添加类目
+     *
+     * @author 胡克
+     * @date 2021/1/20 17:17
+     */
+    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();
+    }
+
+    /**
+     * 更新类目
+     * 不能更新父级类目
+     *
+     * @author 胡克
+     * @date 2021/1/20 17:17
+     */
+    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();
+    }
+
+    /**
+     * 新增/更新 类目时的 校验
+     *
+     * @param categoryEntity
+     * @param isUpdate
+     * @return
+     */
+    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();
+    }
+
+    /**
+     * 查询 类目详情
+     *
+     * @param categoryId
+     * @return
+     */
+    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 为空 返回所有类目层级
+     *
+     * @param queryForm
+     * @return
+     */
+    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);
+    }
+
+    /**
+     * 删除类目
+     * 如果有未删除的子类 则无法删除
+     *
+     * @param categoryId
+     * @return
+     */
+    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();
+    }
+
+}

+ 42 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/constant/GoodsStatusEnum.java

@@ -0,0 +1,42 @@
+package net.lab1024.sa.admin.module.business.goods.constant;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import net.lab1024.sa.common.common.enumeration.BaseEnum;
+
+/**
+ * 商品状态
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+}

+ 75 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/controller/GoodsController.java

@@ -0,0 +1,75 @@
+package net.lab1024.sa.admin.module.business.goods.controller;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import net.lab1024.sa.admin.common.AdminBaseController;
+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.GoodsVO;
+import net.lab1024.sa.admin.module.business.goods.service.GoodsService;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.domain.ValidateList;
+import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+
+/**
+ * 商品业务
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@OperateLog
+@RestController
+@Api(tags = AdminSwaggerTagConst.Business.MANAGER_GOODS)
+public class GoodsController extends AdminBaseController {
+
+    @Autowired
+    private GoodsService goodsService;
+
+    @ApiOperation("分页查询 @author 胡克")
+    @PostMapping("/goods/query")
+    @PreAuthorize("@saAuth.checkPermission('goods:query ')")
+    public ResponseDTO<PageResult<GoodsVO>> query(@RequestBody @Valid GoodsQueryForm queryForm) {
+        return goodsService.query(queryForm);
+    }
+
+    @ApiOperation("添加商品 @author 胡克")
+    @PostMapping("/goods/add")
+    @PreAuthorize("@saAuth.checkPermission('goods:add')")
+    public ResponseDTO<String> add(@RequestBody @Valid GoodsAddForm addForm) {
+        return goodsService.add(addForm);
+    }
+
+    @ApiOperation("更新商品 @author 胡克")
+    @PostMapping("/goods/update")
+    @PreAuthorize("@saAuth.checkPermission('goods:update')")
+    public ResponseDTO<String> update(@RequestBody @Valid GoodsUpdateForm updateForm) {
+        return goodsService.update(updateForm);
+    }
+
+    @ApiOperation("删除 @author 卓大")
+    @GetMapping("/goods/delete/{goodsId}")
+    @PreAuthorize("@saAuth.checkPermission('goods:delete')")
+    public ResponseDTO<String> delete(@PathVariable Long goodsId) {
+        return goodsService.delete(goodsId);
+    }
+
+    @ApiOperation("批量 @author 卓大")
+    @PostMapping("/goods/batchDelete")
+    @PreAuthorize("@saAuth.checkPermission('goods:batchDelete')")
+    public ResponseDTO<String> batchDelete(@RequestBody @Valid ValidateList<Long> idList) {
+        return goodsService.batchDelete(idList);
+    }
+
+
+}

+ 41 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/dao/GoodsDao.java

@@ -0,0 +1,41 @@
+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;
+
+/**
+ * 商品
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+public interface GoodsDao extends BaseMapper<GoodsEntity> {
+
+    /**
+     * 分页 查询商品
+     *
+     * @param page
+     * @param query
+     * @return
+     */
+    List<GoodsVO> query(Page page, @Param("query") GoodsQueryForm query);
+
+    /**
+     * 批量更新删除状态
+     */
+
+    void batchUpdateDeleted(@Param("goodsIdList")List<Long> goodsIdList,@Param("deletedFlag")Boolean deletedFlag);
+}

+ 75 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/entity/GoodsEntity.java

@@ -0,0 +1,75 @@
+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 net.lab1024.sa.admin.module.business.category.dao.CategoryDao;
+import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldBigDecimal;
+import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldLabel;
+import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldSql;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 商品 实体类
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+}

+ 57 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsAddForm.java

@@ -0,0 +1,57 @@
+package net.lab1024.sa.admin.module.business.goods.domain.form;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
+import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.DecimalMin;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * 商品 添加表单
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class GoodsAddForm {
+
+    @ApiModelProperty("商品分类")
+    @NotNull(message = "商品分类不能为空")
+    private Long categoryId;
+
+    @ApiModelProperty("商品名称")
+    @NotBlank(message = "商品名称不能为空")
+    private String goodsName;
+
+    @ApiModelPropertyEnum(GoodsStatusEnum.class)
+    @CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = true)
+    private Integer goodsStatus;
+
+    @ApiModelProperty("产地")
+    @NotBlank(message = "产地 不能为空 ")
+    @JsonDeserialize(using = DictValueVoDeserializer.class)
+    private String place;
+
+    @ApiModelProperty("商品价格")
+    @NotNull(message = "商品价格不能为空")
+    @DecimalMin(value = "0", message = "商品价格最低0")
+    private BigDecimal price;
+
+    @ApiModelProperty("上架状态")
+    @NotNull(message = "上架状态不能为空")
+    private Boolean shelvesFlag;
+
+    @ApiModelProperty("备注|可选")
+    private String remark;
+}

+ 46 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsQueryForm.java

@@ -0,0 +1,46 @@
+package net.lab1024.sa.admin.module.business.goods.domain.form;
+
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
+import net.lab1024.sa.common.common.domain.PageParam;
+import net.lab1024.sa.common.common.json.deserializer.DictValueVoDeserializer;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 商品 分页查询
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class GoodsQueryForm extends PageParam {
+
+    @ApiModelProperty("商品分类")
+    private Integer categoryId;
+
+    @ApiModelProperty("搜索词")
+    @Length(max = 30, message = "搜索词最多30字符")
+    private String searchWord;
+
+    @ApiModelPropertyEnum(GoodsStatusEnum.class)
+    @CheckEnum(message = "商品状态错误", value = GoodsStatusEnum.class, required = false)
+    private Integer goodsStatus;
+
+    @ApiModelProperty("产地")
+    private String place;
+
+    @ApiModelProperty("上架状态")
+    private Boolean shelvesFlag;
+
+    @ApiModelProperty(hidden = true)
+    private Boolean deletedFlag;
+}

+ 23 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/form/GoodsUpdateForm.java

@@ -0,0 +1,23 @@
+package net.lab1024.sa.admin.module.business.goods.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 商品 更新表单
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class GoodsUpdateForm extends GoodsAddForm {
+
+    @ApiModelProperty("商品id")
+    @NotNull(message = "商品id不能为空")
+    private Long goodsId;
+}

+ 56 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/domain/vo/GoodsVO.java

@@ -0,0 +1,56 @@
+package net.lab1024.sa.admin.module.business.goods.domain.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
+import net.lab1024.sa.common.common.json.serializer.DictValueVoSerializer;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+
+/**
+ * 商品
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class GoodsVO  {
+
+    @ApiModelProperty("商品分类")
+    private Long categoryId;
+
+    @ApiModelProperty("商品名称")
+    private String goodsName;
+
+    @ApiModelPropertyEnum(GoodsStatusEnum.class)
+    private Integer goodsStatus;
+
+    @ApiModelProperty("产地")
+    @JsonSerialize(using = DictValueVoSerializer.class)
+    private String place;
+
+    @ApiModelProperty("商品价格")
+    private BigDecimal price;
+
+    @ApiModelProperty("上架状态")
+    private Boolean shelvesFlag;
+
+    @ApiModelProperty("备注|可选")
+    private String remark;
+
+    @ApiModelProperty("商品id")
+    private Long goodsId;
+
+    @ApiModelProperty("商品分类")
+    private String categoryName;
+
+    private LocalDateTime updateTime;
+
+    private LocalDateTime createTime;
+}

+ 20 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/manager/GoodsManager.java

@@ -0,0 +1,20 @@
+package net.lab1024.sa.admin.module.business.goods.manager;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import net.lab1024.sa.admin.module.business.goods.dao.GoodsDao;
+import net.lab1024.sa.admin.module.business.goods.domain.entity.GoodsEntity;
+import org.springframework.stereotype.Service;
+
+/**
+ * 商品 manager
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class GoodsManager extends ServiceImpl<GoodsDao, GoodsEntity> {
+
+}

+ 168 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/goods/service/GoodsService.java

@@ -0,0 +1,168 @@
+package net.lab1024.sa.admin.module.business.goods.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.GoodsQueryForm;
+import net.lab1024.sa.admin.module.business.goods.domain.form.GoodsUpdateForm;
+import net.lab1024.sa.admin.module.business.goods.domain.vo.GoodsVO;
+import net.lab1024.sa.admin.module.business.goods.manager.GoodsManager;
+import net.lab1024.sa.common.common.code.UserErrorCode;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum;
+import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 商品
+ *
+ * @Author 1024创新实验室: 胡克
+ * @Date 2021-10-25 20:26:54
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class GoodsService {
+    @Autowired
+    private GoodsDao goodsDao;
+
+    @Autowired
+    private CategoryQueryService categoryQueryService;
+
+    @Autowired
+    private DataTracerService dataTracerService;
+
+    /**
+     * 添加商品
+     *
+     * @param addForm
+     * @return
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public ResponseDTO<String> add(GoodsAddForm addForm) {
+        // 商品校验
+        ResponseDTO<String> res = this.checkGoods(addForm, null);
+        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();
+    }
+
+    /**
+     * 更新商品
+     *
+     * @param updateForm
+     * @return
+     */
+    @Transactional(rollbackFor = Exception.class)
+    public ResponseDTO<String> update(GoodsUpdateForm updateForm) {
+        // 商品校验
+        ResponseDTO<String> res = this.checkGoods(updateForm, updateForm.getGoodsId());
+        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();
+    }
+
+    /**
+     * 添加/更新 商品校验
+     *
+     * @param addForm
+     * @param goodsId 不为空 代表更新商品
+     * @return
+     */
+    private ResponseDTO<String> checkGoods(GoodsAddForm addForm, Long goodsId) {
+        // 校验类目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(Arrays.asList(goodsId));
+        dataTracerService.batchDelete(Arrays.asList(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();
+    }
+
+
+    /**
+     * 分页查询
+     *
+     * @param queryForm
+     * @return
+     */
+    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);
+    }
+}

+ 74 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankController.java

@@ -0,0 +1,74 @@
+package net.lab1024.sa.admin.module.business.oa.bank;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.RequestUser;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartRequestUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * OA办公-OA银行信息
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@RestController
+@Api(tags = {AdminSwaggerTagConst.Business.OA_BANK})
+public class BankController {
+
+    @Autowired
+    private BankService bankService;
+
+    @ApiOperation(value = "分页查询银行信息 @author 善逸")
+    @PostMapping("/oa/bank/page/query")
+    public ResponseDTO<PageResult<BankVO>> queryByPage(@RequestBody @Valid BankQueryForm queryDTO) {
+        return bankService.queryByPage(queryDTO);
+    }
+
+    @ApiOperation(value = "根据企业ID查询银行信息列表 @author 善逸")
+    @GetMapping("/oa/bank/query/list/{enterpriseId}")
+    public ResponseDTO<List<BankVO>> queryList(@PathVariable Long enterpriseId) {
+        return bankService.queryList(enterpriseId);
+    }
+
+    @ApiOperation(value = "查询银行信息详情 @author 善逸")
+    @GetMapping("/oa/bank/get/{bankId}")
+    public ResponseDTO<BankVO> getDetail(@PathVariable Long bankId) {
+        return bankService.getDetail(bankId);
+    }
+
+    @ApiOperation(value = "新建银行信息 @author 善逸")
+    @PostMapping("/oa/bank/create")
+    public ResponseDTO<String> createBank(@RequestBody @Valid BankCreateForm createVO) {
+        RequestUser requestUser = SmartRequestUtil.getRequestUser();
+        createVO.setCreateUserId(requestUser.getUserId());
+        createVO.setCreateUserName(requestUser.getUserName());
+        return bankService.createBank(createVO);
+    }
+
+    @ApiOperation(value = "编辑银行信息 @author 善逸")
+    @PostMapping("/oa/bank/update")
+    public ResponseDTO<String> updateBank(@RequestBody @Valid BankUpdateForm updateVO) {
+        return bankService.updateBank(updateVO);
+    }
+
+    @ApiOperation(value = "删除银行信息 @author 善逸")
+    @GetMapping("/oa/bank/delete/{bankId}")
+    public ResponseDTO<String> deleteBank(@PathVariable Long bankId) {
+        return bankService.deleteBank(bankId);
+    }
+}

+ 61 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankDao.java

@@ -0,0 +1,61 @@
+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银行信息
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+public interface BankDao extends BaseMapper<BankEntity> {
+
+    /**
+     * 根据账号查询
+     * @param enterpriseId
+     * @param accountNumber
+     * @param excludeBankId
+     * @param deletedFlag
+     * @return
+     */
+    BankEntity queryByAccountNumber(@Param("enterpriseId") Long enterpriseId, @Param("accountNumber") String accountNumber, @Param("excludeBankId") Long excludeBankId, @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 删除银行信息
+     *
+     * @param bankId
+     * @param deletedFlag
+     */
+    void deleteBank(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 银行信息分页查询
+     *
+     * @param page
+     * @param queryForm
+     * @return
+     */
+    List<BankVO> queryPage(Page page, @Param("queryForm") BankQueryForm queryForm);
+
+    /**
+     * 查询银行信息详情
+     * @param bankId
+     * @param deletedFlag
+     * @return
+     */
+    BankVO getDetail(@Param("bankId") Long bankId, @Param("deletedFlag") Boolean deletedFlag);
+}

+ 162 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/BankService.java

@@ -0,0 +1,162 @@
+package net.lab1024.sa.admin.module.business.oa.bank;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerConst;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum;
+import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * OA办公-OA银行信息
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+@Slf4j
+public class BankService {
+
+    @Autowired
+    private BankDao bankDao;
+    @Autowired
+    private EnterpriseDao enterpriseDao;
+
+    @Autowired
+    private DataTracerService dataTracerService;
+
+    /**
+     * 分页查询银行信息
+     *
+     * @param queryDTO
+     * @return
+     */
+    public ResponseDTO<PageResult<BankVO>> queryByPage(BankQueryForm queryDTO) {
+        queryDTO.setDeletedFlag(Boolean.FALSE);
+        Page<?> page = SmartPageUtil.convert2PageQuery(queryDTO);
+        List<BankVO> bankVOS = bankDao.queryPage(page, queryDTO);
+        PageResult<BankVO> pageResult = SmartPageUtil.convert2PageResult(page, bankVOS);
+        return ResponseDTO.ok(pageResult);
+    }
+
+    /**
+     * 根据企业ID查询不分页的银行列表
+     *
+     * @param enterpriseId
+     * @return
+     */
+    public ResponseDTO<List<BankVO>> queryList(Long enterpriseId) {
+        BankQueryForm queryDTO = new BankQueryForm();
+        queryDTO.setEnterpriseId(enterpriseId);
+        queryDTO.setDeletedFlag(Boolean.FALSE);
+        List<BankVO> bankVOS = bankDao.queryPage(null, queryDTO);
+        return ResponseDTO.ok(bankVOS);
+    }
+
+    /**
+     * 查询银行信息详情
+     *
+     * @param bankId
+     * @return
+     */
+    public ResponseDTO<BankVO> getDetail(Long bankId) {
+        // 校验银行信息是否存在
+        BankVO bankVO = bankDao.getDetail(bankId, Boolean.FALSE);
+        if (Objects.isNull(bankVO)) {
+            return ResponseDTO.userErrorParam("银行信息不存在");
+        }
+        return ResponseDTO.ok(bankVO);
+    }
+
+    /**
+     * 新建银行信息
+     *
+     * @param createVO
+     * @return
+     */
+    @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();
+    }
+
+    /**
+     * 编辑银行信息
+     *
+     * @param updateVO
+     * @return
+     */
+    @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();
+    }
+
+
+    /**
+     * 删除银行信息
+     *
+     * @param bankId
+     * @return
+     */
+    @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();
+    }
+}

+ 58 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankCreateForm.java

@@ -0,0 +1,58 @@
+package net.lab1024.sa.admin.module.business.oa.bank.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * OA办公-银行信息新建
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class BankCreateForm {
+
+    @ApiModelProperty("开户银行")
+    @NotBlank(message = "开户银行不能为空")
+    @Length(max = 200, message = "开户银行最多200字符")
+    private String bankName;
+
+    @ApiModelProperty("账户名称")
+    @NotBlank(message = "账户名称不能为空")
+    @Length(max = 200, message = "账户名称最多200字符")
+    private String accountName;
+
+    @ApiModelProperty("账号")
+    @NotBlank(message = "账号不能为空")
+    @Length(max = 200, message = "账号最多200字符")
+    private String accountNumber;
+
+    @ApiModelProperty("备注")
+    @Length(max = 500, message = "备注最多500字符")
+    private String remark;
+
+    @ApiModelProperty("是否对公")
+    @NotNull(message = "是否对公不能为空")
+    private Boolean businessFlag;
+
+    @ApiModelProperty("企业")
+    @NotNull(message = "企业不能为空")
+    private Long enterpriseId;
+
+    @ApiModelProperty("禁用状态")
+    @NotNull(message = "禁用状态不能为空")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private Long createUserId;
+
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private String createUserName;
+}

+ 95 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankEntity.java

@@ -0,0 +1,95 @@
+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.common.module.support.datatracer.annoation.DataTracerFieldLabel;
+
+import java.time.LocalDateTime;
+
+/**
+ * OA办公-OA银行信息
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+}

+ 40 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankQueryForm.java

@@ -0,0 +1,40 @@
+package net.lab1024.sa.admin.module.business.oa.bank.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+import org.hibernate.validator.constraints.Length;
+
+import java.time.LocalDate;
+
+/**
+ * OA办公-OA银行信息查询
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class BankQueryForm extends PageParam {
+
+    @ApiModelProperty("企业ID")
+    private Long enterpriseId;
+
+    @ApiModelProperty("关键字")
+    @Length(max = 200, message = "关键字最多200字符")
+    private String keywords;
+
+    @ApiModelProperty("开始时间")
+    private LocalDate startTime;
+
+    @ApiModelProperty("结束时间")
+    private LocalDate endTime;
+
+    @ApiModelProperty("禁用状态")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty(value = "删除状态", hidden = true)
+    private Boolean deletedFlag;
+}

+ 23 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankUpdateForm.java

@@ -0,0 +1,23 @@
+package net.lab1024.sa.admin.module.business.oa.bank.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * OA办公-银行信息更新
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class BankUpdateForm extends BankCreateForm {
+
+    @ApiModelProperty("银行信息ID")
+    @NotNull(message = "银行信息ID不能为空")
+    private Long bankId;
+}

+ 58 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/bank/domain/BankVO.java

@@ -0,0 +1,58 @@
+package net.lab1024.sa.admin.module.business.oa.bank.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * OA办公-OA银行信息
+ *
+ * @Author 1024创新实验室:善逸
+ * @Date 2022/6/23 21:59:22
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class BankVO {
+
+    @ApiModelProperty("银行信息ID")
+    private Long bankId;
+
+    @ApiModelProperty("开户银行")
+    private String bankName;
+
+    @ApiModelProperty("账户名称")
+    private String accountName;
+
+    @ApiModelProperty("账号")
+    private String accountNumber;
+
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @ApiModelProperty("是否对公")
+    private Boolean businessFlag;
+
+    @ApiModelProperty("企业ID")
+    private Long enterpriseId;
+
+    @ApiModelProperty("企业名称")
+    private String enterpriseName;
+
+    @ApiModelProperty("禁用状态")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty("创建人ID")
+    private Long createUserId;
+
+    @ApiModelProperty("创建人名称")
+    private String createUserName;
+
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新时间")
+    private LocalDateTime updateTime;
+}

+ 115 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseController.java

@@ -0,0 +1,115 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.EnterpriseListVO;
+import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
+import net.lab1024.sa.common.common.annoation.SaAuth;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.RequestUser;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartRequestUtil;
+import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 企业
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Slf4j
+@RestController
+@OperateLog
+@Api(tags = {AdminSwaggerTagConst.Business.OA_ENTERPRISE})
+public class EnterpriseController {
+
+    @Autowired
+    private EnterpriseService enterpriseService;
+
+    @ApiOperation(value = "分页查询企业模块 @author 开云")
+    @PostMapping("/oa/enterprise/page/query")
+    @SaAuth
+    public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(@RequestBody @Valid EnterpriseQueryForm queryDTO) {
+        return enterpriseService.queryByPage(queryDTO);
+    }
+
+    @ApiOperation(value = "查询企业详情 @author 开云")
+    @GetMapping("/oa/enterprise/get/{enterpriseId}")
+    @SaAuth
+    public ResponseDTO<EnterpriseVO> getDetail(@PathVariable Long enterpriseId) {
+        return ResponseDTO.ok(enterpriseService.getDetail(enterpriseId));
+    }
+
+    @ApiOperation(value = "新建企业 @author 开云")
+    @PostMapping("/oa/enterprise/create")
+    @SaAuth
+    public ResponseDTO<String> createEnterprise(@RequestBody @Valid EnterpriseCreateForm createVO) {
+        RequestUser requestUser = SmartRequestUtil.getRequestUser();
+        createVO.setCreateUserId(requestUser.getUserId());
+        createVO.setCreateUserName(requestUser.getUserName());
+        return enterpriseService.createEnterprise(createVO);
+    }
+
+    @ApiOperation(value = "编辑企业 @author 开云")
+    @PostMapping("/oa/enterprise/update")
+    @SaAuth
+    public ResponseDTO<String> updateEnterprise(@RequestBody @Valid EnterpriseUpdateForm updateVO) {
+        return enterpriseService.updateEnterprise(updateVO);
+    }
+
+    @ApiOperation(value = "删除企业 @author 开云")
+    @GetMapping("/oa/enterprise/delete/{enterpriseId}")
+    @SaAuth
+    public ResponseDTO<String> deleteEnterprise(@PathVariable Long enterpriseId) {
+        return enterpriseService.deleteEnterprise(enterpriseId);
+    }
+
+    @ApiOperation(value = "企业列表查询 @author 开云")
+    @GetMapping("/oa/enterprise/query/list")
+    @SaAuth
+    public ResponseDTO<List<EnterpriseListVO>> queryList(@RequestParam(value = "type", required = false) Integer type) {
+        return enterpriseService.queryList(type);
+    }
+
+
+    @ApiOperation(value = "企业添加员工 @author 罗伊")
+    @PostMapping("/oa/enterprise/employee/add")
+    @SaAuth
+    public ResponseDTO<String> addEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
+        return enterpriseService.addEmployee(enterpriseEmployeeForm);
+    }
+
+    @ApiOperation(value = "查询企业全部员工 @author 罗伊")
+    @PostMapping("/oa/enterprise/employee/list")
+    @SaAuth
+    public ResponseDTO<List<EnterpriseEmployeeVO>> employeeList(@RequestBody @Valid List<Long> enterpriseIdList) {
+        return ResponseDTO.ok(enterpriseService.employeeList(enterpriseIdList));
+    }
+
+    @ApiOperation(value = "分页查询企业员工 @author 卓大")
+    @PostMapping("/oa/enterprise/employee/queryPage")
+    @SaAuth
+    public ResponseDTO<PageResult<EnterpriseEmployeeVO>> queryPageEmployeeList(@RequestBody @Valid EnterpriseEmployeeQueryForm queryForm) {
+        return ResponseDTO.ok(enterpriseService.queryPageEmployeeList(queryForm));
+    }
+
+
+    @ApiOperation(value = "企业删除员工 @author 罗伊")
+    @PostMapping("/oa/enterprise/employee/delete")
+    @SaAuth
+    public ResponseDTO<String> deleteEmployee(@RequestBody @Valid EnterpriseEmployeeForm enterpriseEmployeeForm) {
+        return enterpriseService.deleteEmployee(enterpriseEmployeeForm);
+    }
+}

+ 19 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseEmployeeManager.java

@@ -0,0 +1,19 @@
+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
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class EnterpriseEmployeeManager extends ServiceImpl<EnterpriseEmployeeDao, EnterpriseEmployeeEntity> {
+}

+ 252 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/EnterpriseService.java

@@ -0,0 +1,252 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
+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.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.common.common.code.UserErrorCode;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum;
+import net.lab1024.sa.common.module.support.datatracer.domain.form.DataTracerForm;
+import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 企业
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+@Slf4j
+public class EnterpriseService {
+
+    @Autowired
+    private EnterpriseDao enterpriseDao;
+
+    @Autowired
+    private EnterpriseEmployeeDao enterpriseEmployeeDao;
+
+    @Autowired
+    private EnterpriseEmployeeManager enterpriseEmployeeManager;
+
+    @Autowired
+    private DataTracerService dataTracerService;
+
+    @Autowired
+    private DepartmentService departmentService;
+
+    /**
+     * 分页查询企业模块
+     *
+     * @param queryDTO
+     * @return
+     */
+    public ResponseDTO<PageResult<EnterpriseVO>> queryByPage(EnterpriseQueryForm queryDTO) {
+        queryDTO.setDeletedFlag(Boolean.FALSE);
+        Page<?> page = SmartPageUtil.convert2PageQuery(queryDTO);
+        List<EnterpriseVO> enterpriseVOS = enterpriseDao.queryPage(page, queryDTO);
+        PageResult<EnterpriseVO> pageResult = SmartPageUtil.convert2PageResult(page, enterpriseVOS);
+        return ResponseDTO.ok(pageResult);
+    }
+
+    /**
+     * 查询企业详情
+     *
+     * @param enterpriseId
+     * @return
+     */
+    public EnterpriseVO getDetail(Long enterpriseId) {
+        EnterpriseVO enterpriseDetail = enterpriseDao.getDetail(enterpriseId, Boolean.FALSE);
+        return enterpriseDetail;
+    }
+
+    /**
+     * 新建企业
+     *
+     * @param createVO
+     * @return
+     */
+    @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();
+    }
+
+    /**
+     * 编辑企业
+     *
+     * @param updateVO
+     * @return
+     */
+    @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();
+    }
+
+
+    /**
+     * 删除企业
+     *
+     * @param enterpriseId
+     * @return
+     */
+    @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();
+    }
+
+    /**
+     * 企业列表查询
+     *
+     * @return
+     */
+    public ResponseDTO<List<EnterpriseListVO>> queryList(Integer type) {
+        List<EnterpriseListVO> enterpriseListVOS = enterpriseDao.queryList(type, Boolean.FALSE, Boolean.FALSE);
+        return ResponseDTO.ok(enterpriseListVOS);
+    }
+
+    //----------------------------------------- 以下为员工相关--------------------------------------------
+
+    /**
+     * 企业添加员工
+     *
+     * @param enterpriseEmployeeForm
+     * @return
+     */
+    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();
+    }
+
+    /**
+     * 企业删除员工
+     *
+     * @param enterpriseEmployeeForm
+     * @return
+     */
+    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();
+    }
+
+    /**
+     * 企业下员工列表
+     *
+     * @param enterpriseIdList
+     * @return
+     */
+    public List<EnterpriseEmployeeVO> employeeList(List<Long> enterpriseIdList) {
+        if (CollectionUtils.isEmpty(enterpriseIdList)) {
+            return Lists.newArrayList();
+        }
+        List<EnterpriseEmployeeVO> enterpriseEmployeeVOList = enterpriseEmployeeDao.selectByEnterpriseIdList(enterpriseIdList);
+        return enterpriseEmployeeVOList;
+    }
+
+    /**
+     * 分页查询企业员工
+     *
+     * @param queryForm
+     * @return
+     */
+    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);
+    }
+}

+ 40 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/constant/EnterpriseTypeEnum.java

@@ -0,0 +1,40 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise.constant;
+
+
+import net.lab1024.sa.common.common.enumeration.BaseEnum;
+
+/**
+ * 企业类型
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+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;
+    }
+}

+ 72 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseDao.java

@@ -0,0 +1,72 @@
+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.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;
+
+/**
+ * 企业
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+public interface EnterpriseDao extends BaseMapper<EnterpriseEntity> {
+
+    /**
+     * 根据企业名称查询
+     *
+     * @param enterpriseName
+     * @param excludeEnterpriseId
+     * @param deletedFlag
+     * @return
+     */
+    EnterpriseEntity queryByEnterpriseName(@Param("enterpriseName") String enterpriseName, @Param("excludeEnterpriseId") Long excludeEnterpriseId, @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 删除企业
+     *
+     * @param enterpriseId
+     * @param deletedFlag
+     */
+    void deleteEnterprise(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 企业分页查询
+     *
+     * @param page
+     * @param queryForm
+     * @return
+     */
+    List<EnterpriseVO> queryPage(Page page, @Param("queryForm") EnterpriseQueryForm queryForm);
+
+    /**
+     * 查询企业详情
+     *
+     * @param enterpriseId
+     * @return
+     */
+    EnterpriseVO getDetail(@Param("enterpriseId") Long enterpriseId, @Param("deletedFlag") Boolean deletedFlag);
+
+    /**
+     * 查询列表
+     *
+     * @param type
+     * @param disabledFlag
+     * @param deletedFlag
+     * @return
+     */
+    List<EnterpriseListVO> queryList(@Param("type") Integer type, @Param("disabledFlag") Boolean disabledFlag, @Param("deletedFlag") Boolean deletedFlag);
+}

+ 88 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/dao/EnterpriseEmployeeDao.java

@@ -0,0 +1,88 @@
+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;
+
+/**
+ * 企业员工
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+public interface EnterpriseEmployeeDao extends BaseMapper<EnterpriseEmployeeEntity> {
+
+
+    /**
+     * 根据员工查询
+     * @param employeeIdList
+     * @return
+     */
+    List<EnterpriseEmployeeVO> selectByEmployeeIdList(@Param("employeeIdList")Collection<Long> employeeIdList);
+
+    /**
+     * 查询员工关联的企业
+     * @param employeeId
+     * @return
+     */
+    List<Long> selectEnterpriseIdByEmployeeId(@Param("employeeId")Long employeeId);
+    /**
+     * 根据企业查询
+     * @param enterpriseIdList
+     * @return
+     */
+    List<EnterpriseEmployeeVO> selectByEnterpriseIdList(@Param("enterpriseIdList")Collection<Long> enterpriseIdList);
+    /**
+     * 根据企业查询
+     * @param enterpriseId
+     * @return
+     */
+    List<EnterpriseEmployeeEntity> selectByEnterpriseId(@Param("enterpriseId")Long enterpriseId);
+
+    /**
+     * 查询企业下的所有员工id
+     * @param enterpriseIdList
+     * @return
+     */
+    List<Long> selectEmployeeIdByEnterpriseIdList(@Param("enterpriseIdList")Collection<Long> enterpriseIdList);
+    /**
+     * 根据员工删除
+     * @param enterpriseId
+     * @param employeeIdList
+     */
+    void deleteByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection<Long> employeeIdList);
+
+    /**
+     * 根据员工查询
+     * @param enterpriseId
+     * @param employeeIdList
+     */
+    List<EnterpriseEmployeeEntity> selectByEnterpriseAndEmployeeIdList(@Param("enterpriseId")Long enterpriseId, @Param("employeeIdList")Collection<Long> employeeIdList);
+
+    /**
+     * 删除某员工关联的所有企业
+     * @param employeeId
+     */
+    void deleteByEmployeeId(@Param("employeeId")Long employeeId);
+
+    /**
+     * 分页查询企业员工
+     * @param page
+     * @param queryForm
+     * @return
+     */
+    List<EnterpriseEmployeeVO> queryPageEmployeeList(Page<?> page,@Param("queryForm") EnterpriseEmployeeQueryForm queryForm);
+}

+ 51 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEmployeeEntity.java

@@ -0,0 +1,51 @@
+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;
+
+/**
+ * 企业员工
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+    }
+}

+ 153 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/entity/EnterpriseEntity.java

@@ -0,0 +1,153 @@
+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.common.module.support.datatracer.annoation.DataTracerFieldEnum;
+import net.lab1024.sa.common.module.support.datatracer.annoation.DataTracerFieldLabel;
+
+import java.time.LocalDateTime;
+
+/**
+ * 企业
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+}

+ 101 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseCreateForm.java

@@ -0,0 +1,101 @@
+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.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.oa.enterprise.constant.EnterpriseTypeEnum;
+import net.lab1024.sa.common.common.json.deserializer.FileKeyVoDeserializer;
+import net.lab1024.sa.common.common.json.serializer.FileKeyVoSerializer;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+import net.lab1024.sa.common.common.util.SmartVerificationUtil;
+import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+
+/**
+ * OA企业模块创建
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class EnterpriseCreateForm {
+
+    @ApiModelProperty("企业名称")
+    @NotBlank(message = "企业名称不能为空")
+    @Length(max = 200, message = "企业名称最多200字符")
+    private String enterpriseName;
+
+    @ApiModelProperty("企业logo")
+    @JsonSerialize(using = FileKeyVoSerializer.class)
+    @JsonDeserialize(using = FileKeyVoDeserializer.class)
+    private String enterpriseLogo;
+
+    @ApiModelProperty("统一社会信用代码")
+    @NotBlank(message = "统一社会信用代码不能为空")
+    @Length(max = 200, message = "统一社会信用代码最多200字符")
+    private String unifiedSocialCreditCode;
+
+    @ApiModelProperty("联系人")
+    @NotBlank(message = "联系人不能为空")
+    @Length(max = 100, message = "联系人最多100字符")
+    private String contact;
+
+    @ApiModelProperty("联系人电话")
+    @NotBlank(message = "联系人电话不能为空")
+    @Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确")
+    private String contactPhone;
+
+    @ApiModelPropertyEnum(desc = "类型", value = EnterpriseTypeEnum.class)
+    @CheckEnum(message = "类型不正确", value = EnterpriseTypeEnum.class)
+    private Integer type;
+
+    @ApiModelProperty("邮箱")
+    @Pattern(regexp = SmartVerificationUtil.EMAIL, message = "邮箱格式不正确")
+    private String email;
+
+    @ApiModelProperty("省份")
+    private Integer province;
+
+    @ApiModelProperty("省份名称")
+    private String provinceName;
+
+    @ApiModelProperty("城市")
+    private Integer city;
+
+    @ApiModelProperty("城市名称")
+    private String cityName;
+
+    @ApiModelProperty("区县")
+    private Integer district;
+
+    @ApiModelProperty("区县名称")
+    private String districtName;
+
+    @ApiModelProperty("详细地址")
+    @Length(max = 500, message = "详细地址最多500字符")
+    private String address;
+
+    @ApiModelProperty("营业执照")
+    @JsonSerialize(using = FileKeyVoSerializer.class)
+    @JsonDeserialize(using = FileKeyVoDeserializer.class)
+    private String businessLicense;
+
+    @ApiModelProperty("禁用状态")
+    @NotNull(message = "禁用状态不能为空")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private Long createUserId;
+
+    @ApiModelProperty(value = "创建人", hidden = true)
+    private String createUserName;
+
+}

+ 29 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeForm.java

@@ -0,0 +1,29 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 企业员工
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class EnterpriseEmployeeForm {
+
+    @ApiModelProperty("企业id")
+    @NotNull(message = "企业id不能为空")
+    private Long enterpriseId;
+
+    @ApiModelProperty("员工信息id")
+    @NotEmpty(message = "员工信息id不能为空")
+    private List<Long> employeeIdList;
+}

+ 35 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseEmployeeQueryForm.java

@@ -0,0 +1,35 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * 查询企业员工
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2021-12-20 21:06:49
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net )
+ */
+@Data
+public class EnterpriseEmployeeQueryForm extends PageParam {
+
+    @ApiModelProperty("搜索词")
+    @Length(max = 20, message = "搜索词最多20字符")
+    private String keyword;
+
+    @ApiModelProperty("公司Id")
+    @NotNull(message = "公司id 不能为空")
+    private Long enterpriseId;
+
+    @ApiModelProperty(value = "删除标识", hidden = true)
+    private Boolean deletedFlag;
+
+}

+ 38 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseQueryForm.java

@@ -0,0 +1,38 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+import org.hibernate.validator.constraints.Length;
+
+import java.time.LocalDate;
+
+/**
+ * OA企业模块分页查询
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class EnterpriseQueryForm extends PageParam {
+
+    @ApiModelProperty("关键字")
+    @Length(max = 200, message = "关键字最多200字符")
+    private String keywords;
+
+    @ApiModelProperty("开始时间")
+    private LocalDate startTime;
+
+    @ApiModelProperty("结束时间")
+    private LocalDate endTime;
+
+    @ApiModelProperty("禁用状态")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty(value = "删除状态", hidden = true)
+    private Boolean deletedFlag;
+
+}

+ 23 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/form/EnterpriseUpdateForm.java

@@ -0,0 +1,23 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * OA企业模块编辑
+ *
+ * @Author 1024创新实验室: 开云
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class EnterpriseUpdateForm extends EnterpriseCreateForm {
+
+    @ApiModelProperty("企业ID")
+    @NotNull(message = "企业ID不能为空")
+    private Long enterpriseId;
+}

+ 47 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseEmployeeVO.java

@@ -0,0 +1,47 @@
+package net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 企业员工信息
+ *
+ * @Author 1024创新实验室: 罗伊
+ * @Date 2022/7/28 20:37:15
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class EnterpriseEmployeeVO {
+
+    private Long enterpriseEmployeeId;
+
+    @ApiModelProperty("企业ID")
+    private Long enterpriseId;
+
+    @ApiModelProperty("企业名称")
+    private String enterpriseName;
+
+    @ApiModelProperty("员工")
+    private Long employeeId;
+
+    @ApiModelProperty("登录账号")
+    private String loginName;
+
+    @ApiModelProperty("员工名称")
+    private String actualName;
+
+    @ApiModelProperty("手机号码")
+    private String phone;
+
+    @ApiModelProperty("部门id")
+    private Long departmentId;
+
+    @ApiModelProperty("是否被禁用")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty("部门名称")
+    private String departmentName;
+
+}

+ 20 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseListVO.java

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

+ 89 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/enterprise/domain/vo/EnterpriseVO.java

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

+ 80 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceController.java

@@ -0,0 +1,80 @@
+package net.lab1024.sa.admin.module.business.oa.invoice;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.RequestUser;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartRequestUtil;
+import net.lab1024.sa.common.module.support.operatelog.annoation.OperateLog;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * OA发票信息
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Slf4j
+@RestController
+@OperateLog
+@Api(tags = {AdminSwaggerTagConst.Business.OA_INVOICE})
+public class InvoiceController {
+
+    @Autowired
+    private InvoiceService invoiceService;
+
+    @ApiOperation(value = "分页查询发票信息 @author 善逸")
+    @PostMapping("/oa/invoice/page/query")
+    public ResponseDTO<PageResult<InvoiceVO>> queryByPage(@RequestBody @Valid InvoiceQueryForm queryDTO) {
+        return invoiceService.queryByPage(queryDTO);
+    }
+
+    @ApiOperation(value = "查询发票信息详情 @author 善逸")
+    @GetMapping("/oa/invoice/get/{invoiceId}")
+    public ResponseDTO<InvoiceVO> getDetail(@PathVariable Long invoiceId) {
+        return invoiceService.getDetail(invoiceId);
+    }
+
+    @ApiOperation(value = "新建发票信息 @author 善逸")
+    @PostMapping("/oa/invoice/create")
+    public ResponseDTO<String> createInvoice(@RequestBody @Valid InvoiceAddForm createVO) {
+        RequestUser requestUser = SmartRequestUtil.getRequestUser();
+        createVO.setCreateUserId(requestUser.getUserId());
+        createVO.setCreateUserName(requestUser.getUserName());
+        return invoiceService.createInvoice(createVO);
+    }
+
+    @ApiOperation(value = "编辑发票信息 @author 善逸")
+    @PostMapping("/oa/invoice/update")
+    public ResponseDTO<String> updateInvoice(@RequestBody @Valid InvoiceUpdateForm updateVO) {
+        return invoiceService.updateInvoice(updateVO);
+    }
+
+    @ApiOperation(value = "删除发票信息 @author 善逸")
+    @GetMapping("/invoice/delete/{invoiceId}")
+    public ResponseDTO<String> deleteInvoice(@PathVariable Long invoiceId) {
+        return invoiceService.deleteInvoice(invoiceId);
+    }
+
+    @ApiOperation(value = "查询列表 @author lidoudou")
+    @GetMapping("/oa/invoice/query/list/{enterpriseId}")
+    public ResponseDTO<List<InvoiceVO>> queryList(@PathVariable Long enterpriseId) {
+        return invoiceService.queryList(enterpriseId);
+    }
+
+
+}

+ 61 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceDao.java

@@ -0,0 +1,61 @@
+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发票信息
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+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);
+}

+ 158 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/InvoiceService.java

@@ -0,0 +1,158 @@
+package net.lab1024.sa.admin.module.business.oa.invoice;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerConst;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum;
+import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * OA发票信息
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+@Slf4j
+public class InvoiceService {
+
+    @Autowired
+    private InvoiceDao invoiceDao;
+
+    @Autowired
+    private EnterpriseService enterpriseService;
+
+    @Autowired
+    private DataTracerService dataTracerService;
+
+    /**
+     * 分页查询发票信息
+     *
+     * @param queryDTO
+     * @return
+     */
+    public ResponseDTO<PageResult<InvoiceVO>> queryByPage(InvoiceQueryForm queryDTO) {
+        queryDTO.setDeletedFlag(Boolean.FALSE);
+        Page<?> page = SmartPageUtil.convert2PageQuery(queryDTO);
+        List<InvoiceVO> invoiceVOS = invoiceDao.queryPage(page, queryDTO);
+        PageResult<InvoiceVO> pageResult = SmartPageUtil.convert2PageResult(page, invoiceVOS);
+        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);
+    }
+
+    /**
+     * 查询发票信息详情
+     *
+     * @param invoiceId
+     * @return
+     */
+    public ResponseDTO<InvoiceVO> getDetail(Long invoiceId) {
+        // 校验发票信息是否存在
+        InvoiceVO invoiceVO = invoiceDao.getDetail(invoiceId, Boolean.FALSE);
+        if (Objects.isNull(invoiceVO)) {
+            return ResponseDTO.userErrorParam("发票信息不存在");
+        }
+        return ResponseDTO.ok(invoiceVO);
+    }
+
+    /**
+     * 新建发票信息
+     *
+     * @param createVO
+     * @return
+     */
+    @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();
+    }
+
+    /**
+     * 编辑发票信息
+     *
+     * @param updateVO
+     * @return
+     */
+    @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();
+    }
+
+
+    /**
+     * 删除发票信息
+
+     * @param invoiceId
+     * @return
+     */
+    @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();
+    }
+}

+ 59 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceAddForm.java

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

+ 98 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceEntity.java

@@ -0,0 +1,98 @@
+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.common.module.support.datatracer.annoation.DataTracerFieldLabel;
+
+import java.time.LocalDateTime;
+
+/**
+ * OA发票信息
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+
+
+}

+ 40 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceQueryForm.java

@@ -0,0 +1,40 @@
+package net.lab1024.sa.admin.module.business.oa.invoice.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+import org.hibernate.validator.constraints.Length;
+
+import java.time.LocalDate;
+
+/**
+ * OA发票信息查询
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class InvoiceQueryForm extends PageParam {
+
+    @ApiModelProperty("企业ID")
+    private Long enterpriseId;
+
+    @ApiModelProperty("关键字")
+    @Length(max = 200, message = "关键字最多200字符")
+    private String keywords;
+
+    @ApiModelProperty("开始时间")
+    private LocalDate startTime;
+
+    @ApiModelProperty("结束时间")
+    private LocalDate endTime;
+
+    @ApiModelProperty("禁用状态")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty(value = "删除状态", hidden = true)
+    private Boolean deletedFlag;
+}

+ 23 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceUpdateForm.java

@@ -0,0 +1,23 @@
+package net.lab1024.sa.admin.module.business.oa.invoice.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * OA发票信息编辑
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class InvoiceUpdateForm extends InvoiceAddForm {
+
+    @ApiModelProperty("发票信息ID")
+    @NotNull(message = "发票信息ID不能为空")
+    private Long invoiceId;
+}

+ 58 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/invoice/domain/InvoiceVO.java

@@ -0,0 +1,58 @@
+package net.lab1024.sa.admin.module.business.oa.invoice.domain;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * OA发票信息
+ *
+ * @Author 1024创新实验室: 善逸
+ * @Date 2022-06-23 19:32:59
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class InvoiceVO {
+
+    @ApiModelProperty("发票信息ID")
+    private Long invoiceId;
+
+    @ApiModelProperty("开票抬头")
+    private String invoiceHeads;
+
+    @ApiModelProperty("纳税人识别号")
+    private String taxpayerIdentificationNumber;
+
+    @ApiModelProperty("银行账户")
+    private String accountNumber;
+
+    @ApiModelProperty("开户行")
+    private String bankName;
+
+    @ApiModelProperty("备注")
+    private String remark;
+
+    @ApiModelProperty("企业")
+    private Long enterpriseId;
+
+    @ApiModelProperty("企业名称")
+    private String enterpriseName;
+
+    @ApiModelProperty("禁用状态")
+    private Boolean disabledFlag;
+
+    @ApiModelProperty("创建人ID")
+    private Long createUserId;
+
+    @ApiModelProperty("创建人名称")
+    private String createUserName;
+
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新时间")
+    private LocalDateTime updateTime;
+}

+ 30 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/constant/NoticeVisibleRangeDataTypeEnum.java

@@ -0,0 +1,30 @@
+package net.lab1024.sa.admin.module.business.oa.notice.constant;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import net.lab1024.sa.common.common.enumeration.BaseEnum;
+
+/**
+ * 公告、通知 可见范围类型
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Getter
+@AllArgsConstructor
+public enum NoticeVisibleRangeDataTypeEnum implements BaseEnum {
+
+    EMPLOYEE(1, "员工"),
+
+    DEPARTMENT(2, "部门"),
+
+    ;
+
+    private final Integer value;
+
+    private final String desc;
+}

+ 135 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/controller/NoticeController.java

@@ -0,0 +1,135 @@
+package net.lab1024.sa.admin.module.business.oa.notice.controller;
+
+import cn.hutool.extra.servlet.ServletUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+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.common.common.annoation.SaAuth;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartRequestUtil;
+import net.lab1024.sa.common.module.support.repeatsubmit.annoation.RepeatSubmit;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 公告、通知、新闻等等
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat 卓大1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Api(tags = AdminSwaggerTagConst.Business.OA_NOTICE)
+@RestController
+public class NoticeController {
+
+    @Autowired
+    private NoticeService noticeService;
+
+    @Autowired
+    private NoticeTypeService noticeTypeService;
+
+    @Autowired
+    private NoticeEmployeeService noticeEmployeeService;
+
+    // --------------------- 通知公告类型 -------------------------
+
+    @ApiOperation("通知公告类型-获取全部 @author 卓大")
+    @GetMapping("/oa/noticeType/getAll")
+    public ResponseDTO<List<NoticeTypeVO>> getAll() {
+        return ResponseDTO.ok(noticeTypeService.getAll());
+    }
+
+    @ApiOperation("通知公告类型-添加 @author 卓大")
+    @GetMapping("/oa/noticeType/add/{name}")
+    public ResponseDTO<String> add(@PathVariable String name) {
+        return noticeTypeService.add(name);
+    }
+
+    @ApiOperation("通知公告类型-修改 @author 卓大")
+    @GetMapping("/oa/noticeType/update/{noticeTypeId}/{name}")
+    public ResponseDTO<String> update(@PathVariable Long noticeTypeId, @PathVariable String name) {
+        return noticeTypeService.update(noticeTypeId, name);
+    }
+
+    @ApiOperation("通知公告类型-删除 @author 卓大")
+    @GetMapping("/oa/noticeType/delete/{noticeTypeId}")
+    public ResponseDTO<String> deleteNoticeType(@PathVariable Long noticeTypeId) {
+        return noticeTypeService.delete(noticeTypeId);
+    }
+
+    // --------------------- 【管理】通知公告-------------------------
+
+    @ApiOperation("【管理】通知公告-分页查询 @author 卓大")
+    @PostMapping("/oa/notice/query")
+    @SaAuth
+    public ResponseDTO<PageResult<NoticeVO>> query(@RequestBody @Valid NoticeQueryForm queryForm) {
+        return ResponseDTO.ok(noticeService.query(queryForm));
+    }
+
+    @ApiOperation("【管理】通知公告-添加 @author 卓大")
+    @PostMapping("/oa/notice/add")
+    @RepeatSubmit
+    @SaAuth
+    public ResponseDTO<String> add(@RequestBody @Valid NoticeAddForm addForm) {
+        addForm.setCreateUserId(SmartRequestUtil.getRequestUserId());
+        return noticeService.add(addForm);
+    }
+
+    @ApiOperation("【管理】通知公告-更新 @author 卓大")
+    @PostMapping("/oa/notice/update")
+    @RepeatSubmit
+    @SaAuth
+    public ResponseDTO<String> update(@RequestBody @Valid NoticeUpdateForm updateForm) {
+        return noticeService.update(updateForm);
+    }
+
+    @ApiOperation("【管理】通知公告-更新详情 @author 卓大")
+    @GetMapping("/oa/notice/getUpdateVO/{noticeId}")
+    @SaAuth
+    public ResponseDTO<NoticeUpdateFormVO> getUpdateFormVO(@PathVariable Long noticeId) {
+        return ResponseDTO.ok(noticeService.getUpdateFormVO(noticeId));
+    }
+
+    @ApiOperation("【管理】通知公告-删除 @author 卓大")
+    @GetMapping("/oa/notice/delete/{noticeId}")
+    @SaAuth
+    public ResponseDTO<String> delete(@PathVariable Long noticeId) {
+        return noticeService.delete(noticeId);
+    }
+
+    // --------------------- 【员工】查看 通知公告 -------------------------
+    @ApiOperation("【员工】通知公告-查看详情 @author 卓大")
+    @GetMapping("/oa/notice/employee/view/{noticeId}")
+    public ResponseDTO<NoticeDetailVO> view(@PathVariable Long noticeId, HttpServletRequest request) {
+        return noticeEmployeeService.view(
+                SmartRequestUtil.getRequestUserId(),
+                noticeId,
+                ServletUtil.getClientIP(request),
+                request.getHeader("User-Agent")
+        );
+    }
+
+    @ApiOperation("【员工】通知公告-查询全部 @author 卓大")
+    @PostMapping("/oa/notice/employee/query")
+    public ResponseDTO<PageResult<NoticeEmployeeVO>> queryEmployeeNotice(@RequestBody @Valid NoticeEmployeeQueryForm noticeEmployeeQueryForm) {
+        return noticeEmployeeService.queryList(SmartRequestUtil.getRequestUserId(), noticeEmployeeQueryForm);
+    }
+
+    @ApiOperation("【员工】通知公告-查询 查看记录 @author 卓大")
+    @PostMapping("/oa/notice/employee/queryViewRecord")
+    public ResponseDTO<PageResult<NoticeViewRecordVO>> queryViewRecord(@RequestBody @Valid NoticeViewRecordQueryForm noticeViewRecordQueryForm) {
+        return ResponseDTO.ok(noticeEmployeeService.queryViewRecord(noticeViewRecordQueryForm));
+    }
+}

+ 144 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeDao.java

@@ -0,0 +1,144 @@
+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;
+
+/**
+ * 公告、通知、新闻等等
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+public interface NoticeDao extends BaseMapper<NoticeEntity> {
+
+    // ================================= 数据范围相关 【子表】 =================================
+
+    /**
+     * 保存可见范围
+     *
+     * @param noticeId
+     * @param visibleRangeFormList
+     */
+    void insertVisibleRange(@Param("noticeId") Long noticeId, @Param("visibleRangeFormList") List<NoticeVisibleRangeForm> visibleRangeFormList);
+
+    /**
+     * 删除可见范围
+     *
+     * @param noticeId
+     */
+    void deleteVisibleRange(@Param("noticeId") Long noticeId);
+
+    /**
+     * 相关可见范围
+     *
+     * @param noticeId
+     */
+    List<NoticeVisibleRangeVO> queryVisibleRange(@Param("noticeId") Long noticeId);
+
+    // ================================= 通知公告【主表】 相关  =================================
+
+    /**
+     * 后管分页查询资讯
+     *
+     * @param page
+     * @param queryForm
+     * @return
+     */
+    List<NoticeVO> query(Page<?> page, @Param("query") NoticeQueryForm queryForm);
+
+
+    /**
+     * 更新删除状态
+     *
+     * @param noticeId
+     */
+    void updateDeletedFlag(@Param("noticeId") Long noticeId);
+
+    // ================================= 通知公告【员工查看】 相关  =================================
+
+    /**
+     * 查询 员工 查看到的通知公告
+     *
+     * @param page
+     * @param requestEmployeeId
+     * @param noticeEmployeeQueryForm
+     * @return
+     */
+    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
+
+    );
+
+    /**
+     * 查询 员工 未读的通知公告
+     *
+     * @param page
+     * @param requestEmployeeId
+     * @param noticeEmployeeQueryForm
+     * @return
+     */
+    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);
+
+    /**
+     * 查询通知、公告的 查看记录
+     * @param page
+     * @param noticeViewRecordQueryForm
+     * @return
+     */
+    List<NoticeViewRecordVO> queryNoticeViewRecordList(Page page,@Param("queryForm") NoticeViewRecordQueryForm noticeViewRecordQueryForm);
+
+    /**
+     * 保存查看记录
+     * @param noticeId
+     * @param employeeId
+     * @param ip
+     * @param userAgent
+     */
+    void insertViewRecord(@Param("noticeId") Long noticeId, @Param("employeeId") Long employeeId, @Param("ip") String ip, @Param("userAgent") String userAgent,@Param("pageViewCount") Integer pageViewCount);
+
+    /**
+     * 更新查看记录
+     * @param noticeId
+     * @param requestEmployeeId
+     * @param ip
+     * @param userAgent
+     */
+    void updateViewRecord(@Param("noticeId")Long noticeId, @Param("employeeId")Long requestEmployeeId,@Param("ip") String ip, @Param("userAgent")String userAgent);
+
+}

+ 21 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/dao/NoticeTypeDao.java

@@ -0,0 +1,21 @@
+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;
+
+/**
+ * 通知公告类型
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Mapper
+@Component
+public interface NoticeTypeDao extends BaseMapper<NoticeTypeEntity> {
+
+}

+ 99 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeEntity.java

@@ -0,0 +1,99 @@
+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;
+
+/**
+ * 通知公告
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+
+    private Boolean deletedFlag;
+
+    private Long createUserId;
+
+    private LocalDateTime updateTime;
+
+    private LocalDateTime createTime;
+}

+ 41 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/entity/NoticeTypeEntity.java

@@ -0,0 +1,41 @@
+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;
+
+/**
+ * 通知公告类型
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@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;
+}

+ 78 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeAddForm.java

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

+ 35 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeEmployeeQueryForm.java

@@ -0,0 +1,35 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+
+import java.time.LocalDate;
+
+/**
+ * 通知公告 员工查询表单
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeEmployeeQueryForm extends PageParam {
+
+    @ApiModelProperty("标题、作者、来源、文号")
+    private String keywords;
+
+    @ApiModelProperty("分类")
+    private Long noticeTypeId;
+
+    @ApiModelProperty("发布-开始时间")
+    private LocalDate publishTimeBegin;
+
+    @ApiModelProperty("未读标识")
+    private Boolean notViewFlag;
+
+    @ApiModelProperty("发布-截止时间")
+    private LocalDate publishTimeEnd;
+}

+ 48 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeQueryForm.java

@@ -0,0 +1,48 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+
+import java.time.LocalDate;
+
+/**
+ * 通知公告 管理查询表单
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeQueryForm extends PageParam {
+
+    @ApiModelProperty("分类")
+    private Long noticeTypeId;
+
+    @ApiModelProperty("标题、作者、来源")
+    private String keywords;
+
+    @ApiModelProperty("文号")
+    private String documentNumber;
+
+    @ApiModelProperty("创建人")
+    private Long createUserId;
+
+    @ApiModelProperty("删除标识")
+    private Boolean deletedFlag;
+
+    @ApiModelProperty("创建-开始时间")
+    private LocalDate createTimeBegin;
+
+    @ApiModelProperty("创建-截止时间")
+    private LocalDate createTimeEnd;
+
+    @ApiModelProperty("发布-开始时间")
+    private LocalDate publishTimeBegin;
+
+    @ApiModelProperty("发布-截止时间")
+    private LocalDate publishTimeEnd;
+
+}

+ 24 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeUpdateForm.java

@@ -0,0 +1,24 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 通知公告 更新表单
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeUpdateForm extends NoticeAddForm {
+
+    @ApiModelProperty("id")
+    @NotNull(message = "通知id不能为空")
+    private Long noticeId;
+
+}

+ 32 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeViewRecordQueryForm.java

@@ -0,0 +1,32 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.domain.PageParam;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 通知公告 阅读记录查询
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeViewRecordQueryForm extends PageParam {
+
+    @ApiModelProperty("通知公告id")
+    @NotNull(message = "通知公告id不能为空")
+    private Long noticeId;
+
+    @ApiModelProperty("部门id")
+    private Long departmentId;
+
+    @ApiModelProperty("关键字")
+    private String keywords;
+
+
+}

+ 34 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/form/NoticeVisibleRangeForm.java

@@ -0,0 +1,34 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.form;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+import net.lab1024.sa.common.common.validator.enumeration.CheckEnum;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 通知公告 可见范围数据
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class NoticeVisibleRangeForm {
+
+    @ApiModelPropertyEnum(NoticeVisibleRangeDataTypeEnum.class)
+    @CheckEnum(value = NoticeVisibleRangeDataTypeEnum.class, required = true, message = "数据类型错误")
+    private Integer dataType;
+
+    @ApiModelProperty("员工/部门id")
+    @NotNull(message = "员工/部门id不能为空")
+    private Long dataId;
+}

+ 84 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeDetailVO.java

@@ -0,0 +1,84 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.json.serializer.FileKeyVoSerializer;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+/**
+ * 通知公告 详情
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeDetailVO {
+
+    @ApiModelProperty("id")
+    private Long noticeId;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("分类")
+    private Long noticeTypeId;
+
+    @ApiModelProperty("分类名称")
+    private Long noticeTypeName;
+
+    @ApiModelProperty("是否全部可见")
+    @NotNull(message = "是否全部可见不能为空")
+    private Boolean allVisibleFlag;
+
+    @ApiModelProperty("是否定时发布")
+    @NotNull(message = "是否定时发布不能为空")
+    private Boolean scheduledPublishFlag;
+
+    @ApiModelProperty("纯文本内容")
+    private String contentText;
+
+    @ApiModelProperty("html内容")
+    private String contentHtml;
+
+    @ApiModelProperty("附件")
+    @JsonSerialize(using = FileKeyVoSerializer.class)
+    private String attachment;
+
+    @ApiModelProperty("发布时间")
+    @NotNull(message = "发布时间不能为空")
+    private LocalDateTime publishTime;
+
+    @ApiModelProperty("作者")
+    @NotBlank(message = "作者不能为空")
+    private String author;
+
+    @ApiModelProperty("来源")
+    @NotBlank(message = "标题不能为空")
+    private String source;
+
+    @ApiModelProperty("文号")
+    private String documentNumber;
+
+    @ApiModelProperty("页面浏览量")
+    private Integer pageViewCount;
+
+    @ApiModelProperty("用户浏览量")
+    private Integer userViewCount;
+
+    @ApiModelProperty("创建人名称")
+    private Long createUserName;
+
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新时间")
+    private LocalDateTime updateTime;
+
+}

+ 26 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeEmployeeVO.java

@@ -0,0 +1,26 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+/**
+ * 通知公告 员工查看
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeEmployeeVO extends NoticeVO {
+
+    @ApiModelProperty("是否查看")
+    private Boolean viewFlag;
+
+    @ApiModelProperty("发布日期")
+    private LocalDate publishDate;
+
+}

+ 24 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeTypeVO.java

@@ -0,0 +1,24 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 通知公告 类型
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeTypeVO {
+
+    @ApiModelProperty("通知类型id")
+    private Long noticeTypeId;
+
+    @ApiModelProperty("通知类型-名称")
+    private String noticeTypeName;
+
+}

+ 35 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeUpdateFormVO.java

@@ -0,0 +1,35 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.common.common.json.serializer.FileKeyVoSerializer;
+
+import java.util.List;
+
+/**
+ * 用于更新 【通知、公告】 的 VO 对象
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeUpdateFormVO extends NoticeVO {
+
+    @ApiModelProperty("纯文本内容")
+    private String contentText;
+
+    @ApiModelProperty("html内容")
+    private String contentHtml;
+
+    @ApiModelProperty("附件")
+    @JsonSerialize(using = FileKeyVoSerializer.class)
+    private String attachment;
+
+    @ApiModelProperty("可见范围")
+    private List<NoticeVisibleRangeVO> visibleRangeList;
+
+}

+ 75 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVO.java

@@ -0,0 +1,75 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import java.time.LocalDateTime;
+
+
+/**
+ * 新闻、公告  VO
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeVO {
+
+    @ApiModelProperty("id")
+    private Long noticeId;
+
+    @ApiModelProperty("标题")
+    private String title;
+
+    @ApiModelProperty("分类")
+    private Long noticeTypeId;
+
+    @ApiModelProperty("分类名称")
+    private String noticeTypeName;
+
+    @ApiModelProperty("是否全部可见")
+    private Boolean allVisibleFlag;
+
+    @ApiModelProperty("是否定时发布")
+    private Boolean scheduledPublishFlag;
+
+    @ApiModelProperty("发布状态")
+    private Boolean publishFlag;
+
+    @ApiModelProperty("发布时间")
+    private LocalDateTime publishTime;
+
+    @ApiModelProperty("作者")
+    @NotBlank(message = "作者不能为空")
+    private String author;
+
+    @ApiModelProperty("来源")
+    @NotBlank(message = "标题不能为空")
+    private String source;
+
+    @ApiModelProperty("文号")
+    private String documentNumber;
+
+    @ApiModelProperty("页面浏览量")
+    private Integer pageViewCount;
+
+    @ApiModelProperty("用户浏览量")
+    private Integer userViewCount;
+
+    @ApiModelProperty("删除标识")
+    private Boolean deletedFlag;
+
+    @ApiModelProperty("创建人名称")
+    private String createUserName;
+
+    @ApiModelProperty("创建时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("更新时间")
+    private LocalDateTime updateTime;
+
+}

+ 49 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeViewRecordVO.java

@@ -0,0 +1,49 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * 浏览记录 VO
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeViewRecordVO {
+
+    @ApiModelProperty("员工ID")
+    private Long employeeId;
+
+    @ApiModelProperty("员工姓名")
+    private String employeeName;
+
+    @ApiModelProperty("员工部门名称")
+    private String departmentName;
+
+    @ApiModelProperty("查看次数")
+    private Integer pageViewCount;
+
+    @ApiModelProperty("首次ip")
+    private String firstIp;
+
+    @ApiModelProperty("首次用户设备等标识")
+    private String firstUserAgent;
+
+    @ApiModelProperty("首次查看时间")
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("最后一次 ip")
+    private String lastIp;
+
+    @ApiModelProperty("最后一次 用户设备等标识")
+    private String lastUserAgent;
+
+    @ApiModelProperty("最后一次查看时间")
+    private LocalDateTime updateTime;
+}

+ 29 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/domain/vo/NoticeVisibleRangeVO.java

@@ -0,0 +1,29 @@
+package net.lab1024.sa.admin.module.business.oa.notice.domain.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum;
+import net.lab1024.sa.common.common.swagger.ApiModelPropertyEnum;
+
+/**
+ * 新闻、公告 可见范围数据 VO
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Data
+public class NoticeVisibleRangeVO {
+
+    @ApiModelPropertyEnum(NoticeVisibleRangeDataTypeEnum.class)
+    private Integer dataType;
+
+    @ApiModelProperty("员工/部门id")
+    private Long dataId;
+
+    @ApiModelProperty("员工/部门 名称")
+    private String dataName;
+
+}

+ 67 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/manager/NoticeManager.java

@@ -0,0 +1,67 @@
+package net.lab1024.sa.admin.module.business.oa.notice.manager;
+
+import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum;
+import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * 通知、公告 manager
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class NoticeManager {
+
+    @Autowired
+    private NoticeDao noticeDao;
+
+    @Autowired
+    private DataTracerService dataTracerService;
+
+    /**
+     * 保存
+     *
+     * @param noticeEntity
+     * @param visibleRangeFormList
+     */
+    @Transactional(rollbackFor = Throwable.class)
+    public void save(NoticeEntity noticeEntity, List<NoticeVisibleRangeForm> visibleRangeFormList) {
+        noticeDao.insert(noticeEntity);
+        Long noticeId = noticeEntity.getNoticeId();
+        // 保存可见范围
+        if (CollectionUtils.isNotEmpty(visibleRangeFormList)) {
+            noticeDao.insertVisibleRange(noticeId, visibleRangeFormList);
+        }
+        dataTracerService.insert(noticeId, DataTracerTypeEnum.OA_NOTICE);
+    }
+
+    /**
+     * 更新
+     *
+     * @param noticeEntity
+     * @param visibleRangeList
+     */
+    @Transactional(rollbackFor = Throwable.class)
+    public void update(NoticeEntity old, NoticeEntity noticeEntity, List<NoticeVisibleRangeForm> visibleRangeList) {
+        noticeDao.updateById(noticeEntity);
+        Long noticeId = noticeEntity.getNoticeId();
+        // 保存可见范围
+        if (CollectionUtils.isNotEmpty(visibleRangeList)) {
+            noticeDao.deleteVisibleRange(noticeId);
+            noticeDao.insertVisibleRange(noticeId, visibleRangeList);
+        }
+        dataTracerService.update(noticeId, DataTracerTypeEnum.OA_NOTICE, old, noticeEntity);
+    }
+}

+ 159 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeEmployeeService.java

@@ -0,0 +1,159 @@
+package net.lab1024.sa.admin.module.business.oa.notice.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
+import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum;
+import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeEmployeeQueryForm;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeViewRecordQueryForm;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.*;
+import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
+import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
+import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+
+/**
+ * 员工查看 通知。公告
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class NoticeEmployeeService {
+
+    @Autowired
+    private NoticeDao noticeDao;
+
+    @Autowired
+    private NoticeService noticeService;
+
+    @Autowired
+    private DepartmentService departmentService;
+
+    @Autowired
+    private EmployeeService employeeService;
+
+    /**
+     * 查询我的 通知、公告清单
+     *
+     * @return
+     */
+    public ResponseDTO<PageResult<NoticeEmployeeVO>> queryList(Long requestEmployeeId, NoticeEmployeeQueryForm noticeEmployeeQueryForm) {
+        Page<?> page = SmartPageUtil.convert2PageQuery(noticeEmployeeQueryForm);
+
+        //获取请求人的 部门及其子部门
+        List<Long> employeeDepartmentIdList = Lists.newArrayList();
+        EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
+        if (employeeEntity.getDepartmentId() != null) {
+            employeeDepartmentIdList = departmentService.selfAndChildrenIdList(employeeEntity.getDepartmentId());
+        }
+
+        List<NoticeEmployeeVO> noticeList = null;
+        //只查询未读的
+        if (noticeEmployeeQueryForm.getNotViewFlag() != null && noticeEmployeeQueryForm.getNotViewFlag()) {
+            noticeList = noticeDao.queryEmployeeNotViewNotice(page,
+                    requestEmployeeId,
+                    noticeEmployeeQueryForm,
+                    employeeDepartmentIdList,
+                    false,
+                    employeeEntity.getAdministratorFlag(),
+                    NoticeVisibleRangeDataTypeEnum.DEPARTMENT.getValue(),
+                    NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue());
+        } else {
+            // 查询全部
+            noticeList = noticeDao.queryEmployeeNotice(page,
+                    requestEmployeeId,
+                    noticeEmployeeQueryForm,
+                    employeeDepartmentIdList,
+                    false,
+                    employeeEntity.getAdministratorFlag(),
+                    NoticeVisibleRangeDataTypeEnum.DEPARTMENT.getValue(),
+                    NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue());
+        }
+        // 设置发布日期
+        noticeList.forEach(notice -> notice.setPublishDate(notice.getPublishTime().toLocalDate()));
+
+        return ResponseDTO.ok(SmartPageUtil.convert2PageResult(page, noticeList));
+    }
+
+
+    /**
+     * 查询我的 待查看的 通知、公告清单
+     *
+     * @return
+     */
+    public ResponseDTO<NoticeDetailVO> view(Long requestEmployeeId, Long noticeId, String ip, String userAgent) {
+        NoticeUpdateFormVO updateFormVO = noticeService.getUpdateFormVO(noticeId);
+        if (updateFormVO == null || Boolean.TRUE.equals(updateFormVO.getDeletedFlag())) {
+            return ResponseDTO.userErrorParam("通知公告不存在");
+        }
+
+        EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
+        if (!updateFormVO.getAllVisibleFlag() && !checkVisibleRange(updateFormVO.getVisibleRangeList(), requestEmployeeId, employeeEntity.getDepartmentId())) {
+            return ResponseDTO.userErrorParam("对不起,您没有权限查看内容");
+        }
+
+        NoticeDetailVO noticeDetailVO = SmartBeanUtil.copy(updateFormVO, NoticeDetailVO.class);
+        long viewCount = noticeDao.viewRecordCount(noticeId, requestEmployeeId);
+        if (viewCount == 0) {
+            noticeDao.insertViewRecord(noticeId, requestEmployeeId, ip, userAgent, 1);
+        } else {
+            noticeDao.updateViewRecord(noticeId, requestEmployeeId, ip, userAgent);
+        }
+
+        return ResponseDTO.ok(noticeDetailVO);
+    }
+
+    /**
+     * 校验是否有查看权限的范围
+     *
+     * @param visibleRangeList
+     * @param employeeId
+     * @param departmentId
+     * @return
+     */
+    public boolean checkVisibleRange(List<NoticeVisibleRangeVO> visibleRangeList, Long employeeId, Long departmentId) {
+        // 员工范围
+        boolean anyMatch = visibleRangeList.stream().anyMatch(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.equalsValue(e.getDataType()) && Objects.equals(e.getDataId(), employeeId));
+        if (anyMatch) {
+            return true;
+        }
+
+        //部门范围
+        List<Long> visibleDepartmentIdList = visibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.DEPARTMENT.equalsValue(e.getDataType()))
+                .map(NoticeVisibleRangeVO::getDataId).collect(Collectors.toList());
+
+        for (Long visibleDepartmentId : visibleDepartmentIdList) {
+            List<Long> departmentIdList = departmentService.selfAndChildrenIdList(visibleDepartmentId);
+            if (departmentIdList.contains(departmentId)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 分页查询  查看记录
+     *
+     * @param noticeViewRecordQueryForm
+     * @return
+     */
+    public PageResult<NoticeViewRecordVO> queryViewRecord(NoticeViewRecordQueryForm noticeViewRecordQueryForm) {
+        Page<?> page = SmartPageUtil.convert2PageQuery(noticeViewRecordQueryForm);
+        List<NoticeViewRecordVO> noticeViewRecordVOS = noticeDao.queryNoticeViewRecordList(page, noticeViewRecordQueryForm);
+        return SmartPageUtil.convert2PageResult(page, noticeViewRecordVOS);
+    }
+}

+ 250 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeService.java

@@ -0,0 +1,250 @@
+package net.lab1024.sa.admin.module.business.oa.notice.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import net.lab1024.sa.admin.module.business.oa.notice.constant.NoticeVisibleRangeDataTypeEnum;
+import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeDao;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeEntity;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeAddForm;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeQueryForm;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeUpdateForm;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.form.NoticeVisibleRangeForm;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeTypeVO;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeUpdateFormVO;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVO;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeVisibleRangeVO;
+import net.lab1024.sa.admin.module.business.oa.notice.manager.NoticeManager;
+import net.lab1024.sa.admin.module.system.department.dao.DepartmentDao;
+import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEntity;
+import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
+import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
+import net.lab1024.sa.admin.module.system.employee.dao.EmployeeDao;
+import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
+import net.lab1024.sa.common.common.constant.StringConst;
+import net.lab1024.sa.common.common.domain.PageResult;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import net.lab1024.sa.common.module.support.datatracer.constant.DataTracerTypeEnum;
+import net.lab1024.sa.common.module.support.datatracer.service.DataTracerService;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 通知。公告 后台管理业务
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class NoticeService {
+
+    @Autowired
+    private NoticeDao noticeDao;
+
+    @Autowired
+    private NoticeManager noticeManager;
+
+    @Autowired
+    private EmployeeDao employeeDao;
+
+    @Autowired
+    private DepartmentDao departmentDao;
+
+    @Autowired
+    private DepartmentService departmentService;
+
+    @Autowired
+    private NoticeTypeService noticeTypeService;
+
+    @Autowired
+    private DataTracerService dataTracerService;
+
+    /**
+     * 查询 通知、公告
+     *
+     * @param queryForm
+     * @return
+     */
+    public PageResult<NoticeVO> query(NoticeQueryForm queryForm) {
+        Page<?> page = SmartPageUtil.convert2PageQuery(queryForm);
+        List<NoticeVO> list = noticeDao.query(page, queryForm);
+        LocalDateTime now = LocalDateTime.now();
+        list.forEach(e -> e.setPublishFlag(e.getPublishTime().isBefore(now)));
+        return SmartPageUtil.convert2PageResult(page, list);
+    }
+
+    /**
+     * 添加
+     *
+     * @param addForm
+     * @return
+     */
+    public ResponseDTO<String> add(NoticeAddForm addForm) {
+        // 校验并获取可见范围
+        ResponseDTO<String> validate = this.checkAndBuildVisibleRange(addForm);
+        if (!validate.getOk()) {
+            return ResponseDTO.error(validate);
+        }
+
+        // build 资讯
+        NoticeEntity noticeEntity = SmartBeanUtil.copy(addForm, NoticeEntity.class);
+        // 发布时间:不是定时发布时 默认为 当前
+        if (!addForm.getScheduledPublishFlag()) {
+            noticeEntity.setPublishTime(LocalDateTime.now());
+        }
+        // 保存数据
+        noticeManager.save(noticeEntity, addForm.getVisibleRangeList());
+        return ResponseDTO.ok();
+    }
+
+    /**
+     * 校验并返回可见范围
+     *
+     * @param form
+     * @return
+     */
+    private ResponseDTO<String> checkAndBuildVisibleRange(NoticeAddForm form) {
+        // 校验资讯分类
+        NoticeTypeVO noticeType = noticeTypeService.getByNoticeTypeId(form.getNoticeTypeId());
+        if (noticeType == null) {
+            return ResponseDTO.userErrorParam("分类不存在");
+        }
+
+        if (form.getAllVisibleFlag()) {
+            return ResponseDTO.ok();
+        }
+
+        /**
+         * 校验可见范围
+         * 非全部可见时 校验选择的员工|部门
+         */
+        List<NoticeVisibleRangeForm> visibleRangeUpdateList = form.getVisibleRangeList();
+        if (CollectionUtils.isEmpty(visibleRangeUpdateList)) {
+            return ResponseDTO.userErrorParam("未设置可见范围");
+        }
+
+        // 校验可见范围-> 员工
+        List<Long> employeeIdList = visibleRangeUpdateList.stream()
+                .filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.equalsValue(e.getDataType()))
+                .map(NoticeVisibleRangeForm::getDataId)
+                .distinct().collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(employeeIdList)) {
+            employeeIdList = employeeIdList.stream().distinct().collect(Collectors.toList());
+            List<Long> dbEmployeeIdList = employeeDao.selectBatchIds(employeeIdList).stream().map(EmployeeEntity::getEmployeeId).collect(Collectors.toList());
+            Collection<Long> subtract = CollectionUtils.subtract(employeeIdList, dbEmployeeIdList);
+            if (subtract.size() > 0) {
+                return ResponseDTO.userErrorParam("员工id不存在:" + subtract);
+            }
+        }
+
+        // 校验可见范围-> 部门
+        List<Long> deptIdList = visibleRangeUpdateList.stream()
+                .filter(e -> NoticeVisibleRangeDataTypeEnum.DEPARTMENT.equalsValue(e.getDataType()))
+                .map(NoticeVisibleRangeForm::getDataId)
+                .distinct().collect(Collectors.toList());
+        if (CollectionUtils.isNotEmpty(deptIdList)) {
+            deptIdList = deptIdList.stream().distinct().collect(Collectors.toList());
+            List<Long> dbDeptIdList = departmentDao.selectBatchIds(deptIdList).stream().map(DepartmentEntity::getDepartmentId).collect(Collectors.toList());
+            Collection<Long> subtract = CollectionUtils.subtract(deptIdList, dbDeptIdList);
+            if (subtract.size() > 0) {
+                return ResponseDTO.userErrorParam("部门id不存在:" + subtract);
+            }
+        }
+        return ResponseDTO.ok();
+    }
+
+
+    /**
+     * 更新
+     *
+     * @param updateForm
+     * @return
+     */
+    public ResponseDTO<String> update(NoticeUpdateForm updateForm) {
+
+        NoticeEntity oldNoticeEntity = noticeDao.selectById(updateForm.getNoticeId());
+        if (oldNoticeEntity == null) {
+            return ResponseDTO.userErrorParam("通知不存在");
+        }
+
+        // 校验并获取可见范围
+        ResponseDTO<String> res = this.checkAndBuildVisibleRange(updateForm);
+        if (!res.getOk()) {
+            return ResponseDTO.error(res);
+        }
+
+        // 更新
+        NoticeEntity noticeEntity = SmartBeanUtil.copy(updateForm, NoticeEntity.class);
+        noticeManager.update(oldNoticeEntity, noticeEntity, updateForm.getVisibleRangeList());
+        return ResponseDTO.ok();
+    }
+
+
+    /**
+     * 删除
+     *
+     * @param noticeId
+     * @return
+     */
+    public ResponseDTO<String> delete(Long noticeId) {
+        NoticeEntity noticeEntity = noticeDao.selectById(noticeId);
+        if (null == noticeEntity || noticeEntity.getDeletedFlag()) {
+            return ResponseDTO.userErrorParam("通知公告不存在");
+        }
+        // 更新删除状态
+        noticeDao.updateDeletedFlag(noticeId);
+        dataTracerService.delete(noticeId, DataTracerTypeEnum.OA_NOTICE);
+        return ResponseDTO.ok();
+    }
+
+    /**
+     * 获取更新表单用的详情
+     *
+     * @param noticeId
+     * @return
+     */
+    public NoticeUpdateFormVO getUpdateFormVO(Long noticeId) {
+        NoticeEntity noticeEntity = noticeDao.selectById(noticeId);
+        if (null == noticeEntity) {
+            return null;
+        }
+
+        NoticeUpdateFormVO updateFormVO = SmartBeanUtil.copy(noticeEntity, NoticeUpdateFormVO.class);
+        if (!updateFormVO.getAllVisibleFlag()) {
+            List<NoticeVisibleRangeVO> noticeVisibleRangeList = noticeDao.queryVisibleRange(noticeId);
+            List<Long> employeeIdList = noticeVisibleRangeList.stream().filter(e -> NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue().equals(e.getDataType()))
+                    .map(NoticeVisibleRangeVO::getDataId)
+                    .collect(Collectors.toList());
+
+            Map<Long, EmployeeEntity> employeeMap = null;
+            if (CollectionUtils.isNotEmpty(employeeIdList)) {
+                employeeMap = employeeDao.selectBatchIds(employeeIdList).stream().collect(Collectors.toMap(EmployeeEntity::getEmployeeId, Function.identity()));
+            } else {
+                employeeMap = new HashMap<>();
+            }
+            for (NoticeVisibleRangeVO noticeVisibleRange : noticeVisibleRangeList) {
+                if (noticeVisibleRange.getDataType().equals(NoticeVisibleRangeDataTypeEnum.EMPLOYEE.getValue())) {
+                    EmployeeEntity employeeEntity = employeeMap.get(noticeVisibleRange.getDataId());
+                    noticeVisibleRange.setDataName(employeeEntity == null ? StringConst.EMPTY : employeeEntity.getActualName());
+                } else {
+                    DepartmentVO departmentVO = departmentService.getDepartmentById(noticeVisibleRange.getDataId());
+                    noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getName());
+                }
+            }
+            updateFormVO.setVisibleRangeList(noticeVisibleRangeList);
+        }
+        return updateFormVO;
+    }
+}

+ 87 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/business/oa/notice/service/NoticeTypeService.java

@@ -0,0 +1,87 @@
+package net.lab1024.sa.admin.module.business.oa.notice.service;
+
+import cn.hutool.core.util.StrUtil;
+import net.lab1024.sa.admin.module.business.oa.notice.dao.NoticeTypeDao;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.entity.NoticeTypeEntity;
+import net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeTypeVO;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartBeanUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * 通知。公告 类型
+ *
+ * @Author 1024创新实验室-主任: 卓大
+ * @Date 2022-08-12 21:40:39
+ * @Wechat zhuoda1024
+ * @Email lab1024@163.com
+ * @Copyright 1024创新实验室 ( https://1024lab.net ),2012-2022
+ */
+@Service
+public class NoticeTypeService {
+
+    @Autowired
+    private NoticeTypeDao noticeTypeDao;
+
+    /**
+     * 查询全部
+     * @return
+     */
+    public List<NoticeTypeVO> getAll() {
+        return SmartBeanUtil.copyList(noticeTypeDao.selectList(null), NoticeTypeVO.class);
+    }
+
+    public NoticeTypeVO getByNoticeTypeId(Long noticceTypeId) {
+        return SmartBeanUtil.copy(noticeTypeDao.selectById(noticceTypeId), NoticeTypeVO.class);
+    }
+
+    public synchronized ResponseDTO<String> add(String name) {
+        if (StrUtil.isBlank(name)) {
+            return ResponseDTO.userErrorParam("类型名称不能为空");
+        }
+
+        List<NoticeTypeEntity> noticeTypeEntityList = noticeTypeDao.selectList(null);
+        if (!CollectionUtils.isEmpty(noticeTypeEntityList)) {
+            boolean exist = noticeTypeEntityList.stream().map(NoticeTypeEntity::getNoticeTypeName).collect(Collectors.toSet()).contains(name);
+            if (exist) {
+                return ResponseDTO.userErrorParam("类型名称已经存在");
+            }
+        }
+        noticeTypeDao.insert(NoticeTypeEntity.builder().noticeTypeName(name).build());
+        return ResponseDTO.ok();
+    }
+
+    public synchronized ResponseDTO<String> update(Long noticeTypeId, String name) {
+        if (StrUtil.isBlank(name)) {
+            return ResponseDTO.userErrorParam("类型名称不能为空");
+        }
+
+        NoticeTypeEntity noticeTypeEntity = noticeTypeDao.selectById(noticeTypeId);
+        if (noticeTypeEntity == null) {
+            return ResponseDTO.userErrorParam("类型名称不存在");
+        }
+
+        List<NoticeTypeEntity> noticeTypeEntityList = noticeTypeDao.selectList(null);
+        if (!CollectionUtils.isEmpty(noticeTypeEntityList)) {
+            Optional<NoticeTypeEntity> optionalNoticeTypeEntity = noticeTypeEntityList.stream().filter(e -> e.getNoticeTypeName().equals(name)).findFirst();
+            if (optionalNoticeTypeEntity.isPresent() && !optionalNoticeTypeEntity.get().getNoticeTypeId().equals(noticeTypeId)) {
+                return ResponseDTO.userErrorParam("类型名称已经存在");
+            }
+        }
+        noticeTypeEntity.setNoticeTypeName(name);
+        noticeTypeDao.updateById(noticeTypeEntity);
+        return ResponseDTO.ok();
+    }
+
+    public synchronized ResponseDTO<String> delete(Long noticeTypeId) {
+        noticeTypeDao.deleteById(noticeTypeId);
+        return ResponseDTO.ok();
+    }
+
+}

+ 313 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/gm/audit/controller/AuditController.java

@@ -0,0 +1,313 @@
+package net.lab1024.sa.admin.module.gm.audit.controller;
+
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import net.lab1024.sa.admin.module.gm.audit.domain.from.EditAuditRepairFrom;
+import net.lab1024.sa.admin.module.gm.audit.domain.from.editAuditCancelFrom;
+import net.lab1024.sa.admin.module.gm.audit.domain.from.editAuditFlowCompeletedFrom;
+import net.lab1024.sa.admin.module.gm.audit.domain.vo.AuditVo;
+import net.lab1024.sa.admin.module.gm.audit.domain.vo.ManHourVo;
+import net.lab1024.sa.admin.module.gm.audit.service.AuditService;
+import net.lab1024.sa.admin.module.gm.common.service.CommonService;
+import net.lab1024.sa.admin.module.gm.eq.domain.from.EquipmentQueryFrom;
+import net.lab1024.sa.admin.module.gm.eq.domain.vo.EquipmentBindDetailsVo;
+import net.lab1024.sa.admin.module.gm.maintain.domain.vo.MaintainDetailsVo;
+import net.lab1024.sa.admin.module.gm.partapply.domain.vo.BigPartapplyVo;
+import net.lab1024.sa.admin.module.gm.partapply.service.PartapplyService;
+import net.lab1024.sa.admin.module.gm.repair.service.RepairService;
+import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
+import net.lab1024.sa.admin.module.system.menu.service.MenuService;
+import net.lab1024.sa.common.common.annoation.NoNeedLogin;
+import net.lab1024.sa.common.common.domain.EquipmentAddResponse;
+import net.lab1024.sa.common.common.domain.ResponseDTO;
+import net.lab1024.sa.common.common.util.SmartPageUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@RestController
+@Api(tags = "审核")
+@RequestMapping("/authdata")
+public class AuditController {
+
+    @Autowired
+    private RepairService repairService;
+    @Autowired
+    private AuditService auditService;
+    @Autowired
+    private CommonService commonService;
+    @Autowired
+    private PartapplyService partapplyService;
+
+    @Autowired
+    private MenuService menuService;
+
+    @GetMapping("/audit/list")
+    //@NoNeedLogin
+    @ApiOperation("审核列表")
+    public ResponseDTO<List<AuditVo>> GetAuditList(@RequestParam int pageNum, @RequestParam int pageSize, @RequestParam int pastureId, @RequestParam(required = false, defaultValue = "") String eqCodeOrName, @RequestParam(required = false, defaultValue = "") String status, @RequestParam(required = false, defaultValue = "") String auditType, @RequestParam(required = false, defaultValue = "") String pick, @RequestParam(required = false, defaultValue = "") String code, @RequestParam(required = false, defaultValue = "") String sapCode, @RequestParam(required = false, defaultValue = "") String startDate, @RequestParam(required = false, defaultValue = "") String endDate, @RequestParam(required = false, defaultValue = "") String empId) {
+
+        if (auditType.equals("-1")) {
+            auditType = "";
+        }
+
+        List<String> auditTypeList = new ArrayList<>();
+        List<MenuVO> menuList = menuService.getMenuEmp(Integer.parseInt(empId));
+        for (MenuVO menuVO : menuList) {
+            if (menuVO.getMenuId() == 223) {
+                auditTypeList.add("1");
+            } else if (menuVO.getMenuId() == 224) {
+                auditTypeList.add("3");
+            } else if (menuVO.getMenuId() == 222) {
+                auditTypeList.add("0");
+            } else {
+                auditTypeList.add("-1");
+            }
+        }
+        System.out.println(auditType);
+
+        String authAuditType = String.join(",", auditTypeList);
+        System.out.println(authAuditType);
+        EquipmentQueryFrom page = new EquipmentQueryFrom();
+        page.setPageNum(pageNum);
+        page.setPageSize(pageSize);
+        Page pageParam = SmartPageUtil.convert2PageQuery(page);
+        List<AuditVo> auditList = auditService.GetAuditList(pageParam, "", "", "2", status, eqCodeOrName,
+                auditType, pastureId, pick, code, sapCode, startDate, endDate, authAuditType,"");
+        int count = auditService.GetAuditListCount("", "", "2", status, eqCodeOrName, auditType, pastureId,
+                pick, code, sapCode, startDate, endDate, authAuditType,"");
+        ResponseDTO t = ResponseDTO.ok(auditList);
+        t.setCount(count);
+        t.setCode(200);
+        t.setPageSize(pageSize);
+        t.setPageNum(pageNum);
+        return t;
+    }
+
+
+    @PostMapping("/audit/edit")
+    //@NoNeedLogin
+    @ApiOperation("审核")
+    public ResponseDTO<Boolean> editAuditFlowCompeleted(@RequestBody editAuditFlowCompeletedFrom from) {
+        //        P10 下达 - 用户状态改为"20-下达",系统状态设置REL
+//        P40 技术完成
+//        - 系统状态设置TECO
+//        P41 取消技术完成 - 撤销系统状态TECO
+        boolean status = false;
+        try {
+//            0 审核未成功 1 审核成功 2 审核未通过
+            String statusStr = "P10";
+            if (from.getStatus().equals(1)) {
+                statusStr = "P30";
+            } else if (from.getStatus().equals(2)) {
+                statusStr = "P21";
+            }
+            AuditVo auditInfo = auditService.getAudit(from.getCode());
+            if (from.getFlowCompeleted() > 2) {
+                from.setOneAudit(auditInfo.getOneAudit());
+                from.setOneAuditTime(auditInfo.getOneAuditTime());
+                from.setOneAuditName(auditInfo.getOneAuditName());
+            }
+            if (from.getFlowCompeleted() > 4) {
+                from.setTwoAuditName(auditInfo.getTwoAuditName());
+                from.setTwoAudit(auditInfo.getTwoAudit());
+                from.setTwoAuditTime(auditInfo.getTwoAuditTime());
+            }
+//            auditType; // 0 维修  1 领用  2 点巡检审核 3 保养审核
+            if (!from.getStatus().equals(0)) {
+                if (from.getAuditType().equals(0)) {
+                    MaintainDetailsVo wxRepair = repairService.GetRepairDetails(from.getCode(), "");
+                    EquipmentAddResponse res = commonService.editSapBXPush(from.getCode(), wxRepair.getOutsource(), wxRepair.getIsOutsource(), wxRepair.getPrice_unit(), statusStr);
+                    if (res != null) {
+                        ResponseDTO<Boolean> t;
+                        t = ResponseDTO.ok(false);
+                        t.setCode(500);
+                        t.setMsg(res.getMsg());
+                        return t;
+                    }
+//                    if (statusStr.equals("P30")) {
+//                        EquipmentAddResponse res1 = commonService.editSapBXPush(from.getCode(), wxRepair.getOutsource(), wxRepair.getIsOutsource(), wxRepair.getPrice_unit(), "P40");
+//                        if (res1 != null) {
+//                            ResponseDTO<Boolean> t;
+//                            t = ResponseDTO.ok(false);
+//                            t.setCode(500);
+//                            t.setMsg(res1.getMsg());
+//                            return t;
+//                        }
+//                    }
+
+                } else if (from.getAuditType().equals(1)) {
+                    status = auditService.editAuditFlowCompeleted(from);
+//                    statusStr = "P10";
+                    BigPartapplyVo bigpartapply = partapplyService.getBigPartapply(from.getCode());
+                    MaintainDetailsVo wxRepair = repairService.GetRepairDetails(bigpartapply.getRuCode(), "");
+                    System.out.println();
+                    EquipmentAddResponse res = commonService.editSapBXPush(bigpartapply.getRuCode(), wxRepair.getOutsource(), wxRepair.getIsOutsource(), wxRepair.getPrice_unit(), "");
+                    if (res != null) {
+                        from.setStatus(0);
+                        status = auditService.editAuditFlowCompeleted(from);
+                        ResponseDTO<Boolean> t;
+                        t = ResponseDTO.ok(false);
+                        t.setCode(500);
+                        t.setMsg(res.getMsg());
+                        return t;
+                    }
+                } else if (from.getAuditType().equals(2)) {
+                    EquipmentAddResponse res = commonService.editSapBYPush(from.getCode(), auditInfo.getSapCode(), statusStr);
+                    if (res != null) {
+                        ResponseDTO<Boolean> t;
+                        t = ResponseDTO.ok(false);
+                        t.setCode(500);
+                        t.setMsg(res.getMsg());
+                        return t;
+                    }
+//                    if (statusStr.equals("P30")) {
+//                        EquipmentAddResponse res1 = commonService.editSapBYPush(from.getCode(), auditInfo.getSapCode(), "P40");
+//                        if (res != null) {
+//                            ResponseDTO<Boolean> t;
+//                            t = ResponseDTO.ok(false);
+//                            t.setCode(500);
+//                            t.setMsg(res1.getMsg());
+//                            return t;
+//                        }
+//                    }
+                } else if (from.getAuditType().equals(3)) {
+                    status = auditService.editAuditFlowCompeleted(from);
+                    EquipmentAddResponse res = commonService.editSapBYPush(from.getCode(), auditInfo.getSapCode(), statusStr);
+                    if (res != null) {
+                        from.setStatus(0);
+                        status = auditService.editAuditFlowCompeleted(from);
+                        ResponseDTO<Boolean> t;
+                        t = ResponseDTO.ok(false);
+                        t.setCode(500);
+                        t.setMsg(res.getMsg());
+                        return t;
+                    }
+//
+                }
+            }
+
+            status = auditService.editAuditFlowCompeleted(from);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        if (!status) {
+            ResponseDTO<Boolean> t;
+            t = ResponseDTO.ok(false);
+            t.setCode(500);
+            return t;
+        }
+
+        ResponseDTO<Boolean> t;
+        t = ResponseDTO.ok();
+        t.setCode(200);
+        return t;
+    }
+
+
+    @GetMapping("/audit")
+    //@NoNeedLogin
+    @ApiOperation("审核详情")
+    public ResponseDTO<AuditVo> GetAuditList(@RequestParam(required = false, defaultValue = "") String code) {
+        ResponseDTO t = ResponseDTO.ok(auditService.getAudit(code));
+        t.setCode(200);
+        return t;
+    }
+
+    @PostMapping("/audit/repair/edit")
+    //@NoNeedLogin
+    @ApiOperation("报修关单")
+    public ResponseDTO editAuditRepair(@RequestBody EditAuditRepairFrom from) {
+        ResponseDTO t = ResponseDTO.ok();
+        boolean status = auditService.editAuditRepair(from.getCode());
+        if (!status) {
+            t.setCode(500);
+            t.setMsg("修改失败!");
+            return t;
+        }
+        t.setCode(200);
+        t.setMsg("修改成功!");
+        return t;
+    }
+
+
+    /**
+     * @param pastureId
+     * @param eqName          设备名称
+     * @param startTime       报修日期
+     * @param endTime         报修日期
+     * @param startPick       接单日期
+     * @param endPick         接单日期
+     * @param startCompletion 完成日期
+     * @param endCompletion   完成日期
+     * @param startAudit      审核日期
+     * @param endAudit        审核日期
+     */
+    @GetMapping("/audit/manhour/list")
+    //@NoNeedLogin
+    @ApiOperation("PC维修工时列表")
+    public ResponseDTO<List<ManHourVo>> getManHour(@RequestParam int pageNum, @RequestParam int pageSize, @RequestParam(required = false, defaultValue = "") String pastureId, @RequestParam(required = false, defaultValue = "") String eqName, @RequestParam(required = false, defaultValue = "") String startTime, @RequestParam(required = false, defaultValue = "") String endTime, @RequestParam(required = false, defaultValue = "") String startPick, @RequestParam(required = false, defaultValue = "") String endPick, @RequestParam(required = false, defaultValue = "") String startCompletion, @RequestParam(required = false, defaultValue = "") String endCompletion, @RequestParam(required = false, defaultValue = "") String startAudit, @RequestParam(required = false, defaultValue = "") String endAudit, @RequestParam(required = false, defaultValue = "") String repairPerson) {
+        EquipmentQueryFrom page = new EquipmentQueryFrom();
+        page.setPageNum(pageNum);
+        page.setPageSize(pageSize);
+        Page pageParam = SmartPageUtil.convert2PageQuery(page);
+        List<ManHourVo> manHourVoList = auditService.getManHour(pageParam, pastureId, eqName, startTime, endTime, startPick, endPick, startCompletion, endCompletion, startAudit, endAudit, repairPerson);
+        int count = auditService.getManHourCount(pastureId, eqName, startTime, endTime, startPick, endPick, startCompletion, endCompletion, startAudit, endAudit, repairPerson);
+
+        int i = 0;
+        for (ManHourVo manHourVo : manHourVoList) {
+            i++;
+            manHourVo.setNumber((pageNum - 1) * pageSize + i);
+        }
+
+        ResponseDTO t = ResponseDTO.ok(manHourVoList);
+        t.setCount(count);
+        t.setCode(200);
+        t.setPageSize(pageSize);
+        t.setPageNum(pageNum);
+        return t;
+    }
+
+
+    @PostMapping("/audit/edit/cancel")
+    //@NoNeedLogin
+    @ApiOperation("审核取消")
+    public ResponseDTO<Boolean> editAuditCancel(@RequestBody editAuditCancelFrom from) throws Exception {
+        if (from.getAuditType().equals(0)) {
+            MaintainDetailsVo wxRepair = repairService.GetRepairDetails(from.getCode(), "");
+            EquipmentAddResponse res = commonService.editSapBXPush(from.getCode(), wxRepair.getOutsource(), wxRepair.getIsOutsource(), wxRepair.getPrice_unit(), "P31");
+            if (res != null) {
+                ResponseDTO<Boolean> t;
+                t = ResponseDTO.ok(false);
+                t.setCode(500);
+                t.setMsg(res.getMsg());
+                return t;
+            }
+
+        } else if (from.getAuditType().equals(3)) {
+            AuditVo auditInfo = auditService.getAudit(from.getCode());
+            System.out.println(from.getCode());
+            System.out.println(auditInfo.getSapCode());
+            EquipmentAddResponse res = commonService.editSapBYPush(from.getCode(), auditInfo.getSapCode(), "P31");
+            if (res != null) {
+                ResponseDTO<Boolean> t;
+                t = ResponseDTO.ok(false);
+                t.setCode(500);
+                t.setMsg(res.getMsg());
+                return t;
+            }
+        }
+
+        auditService.editAuditRepair(from.getCode());
+        ResponseDTO t = ResponseDTO.ok();
+        t.setCode(200);
+        return t;
+    }
+}
+

+ 68 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/gm/audit/dao/AuditDao.java

@@ -0,0 +1,68 @@
+package net.lab1024.sa.admin.module.gm.audit.dao;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import net.lab1024.sa.admin.module.gm.audit.domain.from.AddAuditFrom;
+import net.lab1024.sa.admin.module.gm.audit.domain.from.EditAuditFrom;
+import net.lab1024.sa.admin.module.gm.audit.domain.from.editAuditFlowCompeletedFrom;
+import net.lab1024.sa.admin.module.gm.audit.domain.vo.AuditVo;
+import net.lab1024.sa.admin.module.gm.audit.domain.vo.ManHourVo;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Mapper
+@Component
+public interface AuditDao {
+    void addAudit(@Param("audit") AddAuditFrom audit);
+
+    List<AuditVo> getAuditList(@Param("page") Page page, @Param("personnel") String personnel,
+                               @Param("createUserId") String createUserId, @Param("processed") String processed,
+                               @Param("status") String status, @Param("eqCodeOrName") String eqCodeOrName,
+                               @Param("fromAuditType") String auditType, @Param("fromPastureId") int pastureId,
+                               @Param("pick") String pick,
+                               @Param("code") String code,
+                               @Param("sapCode") String sapCode,@Param("startDate")String startDate,@Param("endDate")String endDate,
+                               @Param("authAuditType")String  authAuditType,@Param("priok")String  priok);
+
+    int getAuditListCount(@Param("personnel") String personnel, @Param("createUserId") String createUserId,
+                          @Param("processed") String processed, @Param("status") String status,
+                          @Param("eqCodeOrName") String eqCodeOrName, @Param("fromAuditType") String auditType,
+                          @Param("fromPastureId") int pastureId, @Param("pick") String pick,
+                          @Param("code") String code,
+                          @Param("sapCode") String sapCode,@Param("startDate")String startDate,@Param("endDate")String endDate,
+                          @Param("authAuditType")String authAuditType,@Param("priok")String  priok);
+
+    void editAuditPersonnel(@Param("audit") EditAuditFrom audit);
+
+    String getAuditSapCode(@Param("code") String code);
+
+
+    void editAuditFlowCompeleted(@Param("audit") editAuditFlowCompeletedFrom audit);
+
+    void editAuditRepair(@Param("code") String code);
+
+
+    AuditVo getAudit(@Param("code") String code);
+
+    void editAuditProcessed(@Param("code") String code, @Param("processed") int processed);
+
+    int getAuditPartapplyCount(@Param("code") String code, @Param("status") int status);
+
+    int getAuditRepairCount(@Param("eqCode") String eqCode, @Param("otgrp") String otgrp, @Param("oteil") String oteil,
+                            @Param("fegrp") String fegrp, @Param("fecod") String fecod);
+
+    void editRepairPick(@Param("audit") EditAuditFrom audit);
+
+    List<ManHourVo> getManHour(@Param("page") Page page, @Param("pastureId") String pastureId, @Param("eqName") String eqName, @Param("startTime") String startTime,
+                               @Param("endTime") String endTime, @Param("startPick") String startPick, @Param("endPick") String endPick,
+                               @Param("startCompletion") String startCompletion, @Param("endCompletion") String endCompletion,
+                               @Param("startAudit") String startAudit, @Param("endAudit") String endAudit,@Param("repairPerson") String repairPerson);
+
+    int getManHourCount( @Param("pastureId") String pastureId, @Param("eqName") String eqName, @Param("startTime") String startTime,
+                               @Param("endTime") String endTime, @Param("startPick") String startPick, @Param("endPick") String endPick,
+                               @Param("startCompletion") String startCompletion, @Param("endCompletion") String endCompletion,
+                         @Param("startAudit") String startAudit, @Param("endAudit") String endAudit,@Param("repairPerson") String repairPerson);
+
+}

+ 32 - 0
smart-admin-api/sa-admin/src/main/java/net/lab1024/sa/admin/module/gm/audit/domain/from/AddAuditFrom.java

@@ -0,0 +1,32 @@
+package net.lab1024.sa.admin.module.gm.audit.domain.from;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class AddAuditFrom {
+    private int pastureId;
+    private String code;
+    private Integer auditType; // 0 维修 1 领用 2 点巡检审核 3 保养审核
+    private String eqName;
+    private String eqCode;
+    private String date;
+    private String personnelID; // 领用 保养 点巡检 维修人员
+    private String personnelName;
+    private String oneAudit;
+    private String oneAuditName;
+    private Date oneAuditTime;
+    private String twoAudit;
+    private String twoAuditName;
+    private Date twoAuditTime;
+    private String threeAudit;
+    private String threeAuditName;
+    private Date threeAuditTime;
+    private String note; // 未通过原因
+    private Integer status; // 0 审核未成功 1 审核成功 2 审核未通过
+    private Integer flowCompeleted; // 0 未审核 1 第一个审核通过 2 第一个审核未通过 3 第二个审核通过 4 第二个审核未通过 5 第三个审核通过 6 第三个审核未通过
+    private String sapCode;
+    private int  createUserId;
+    private int  processed;
+}

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