wangwei_123 2 days ago
parent
commit
0232ac37be
  1. 9
      .idea/ElectronicLock.iml
  2. 7
      .idea/inspectionProfiles/Project_Default.xml
  3. 6
      .idea/misc.xml
  4. 8
      .idea/modules.xml
  5. 6
      .idea/vcs.xml
  6. 47
      .idea/workspace.xml
  7. 91
      server/dependencies/pom.xml
  8. 3
      server/pom.xml
  9. 13744
      server/sql/2025.08.20.sql
  10. 403
      server/tmp/.scr/auto_export.py
  11. 1
      server/yudao-framework/yudao-common/《芋道 Spring Boot 参数校验 Validation 入门》.md
  12. 1
      server/yudao-framework/yudao-spring-boot-starter-excel/pom.xml
  13. 1
      server/yudao-framework/yudao-spring-boot-starter-job/《芋道 Spring Boot 定时任务入门》.md
  14. 1
      server/yudao-framework/yudao-spring-boot-starter-job/《芋道 Spring Boot 异步任务入门》.md
  15. 1
      server/yudao-framework/yudao-spring-boot-starter-monitor/《芋道 Spring Boot 监控工具 Admin 入门》.md
  16. 1
      server/yudao-framework/yudao-spring-boot-starter-monitor/《芋道 Spring Boot 监控端点 Actuator 入门》.md
  17. 1
      server/yudao-framework/yudao-spring-boot-starter-monitor/《芋道 Spring Boot 链路追踪 SkyWalking 入门》.md
  18. 1
      server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 事件机制 Event 入门》.md
  19. 1
      server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 Kafka 入门》.md
  20. 1
      server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RabbitMQ 入门》.md
  21. 1
      server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RocketMQ 入门》.md
  22. 1
      server/yudao-framework/yudao-spring-boot-starter-mybatis/《芋道 Spring Boot MyBatis 入门》.md
  23. 1
      server/yudao-framework/yudao-spring-boot-starter-mybatis/《芋道 Spring Boot 多数据源(读写分离)入门》.md
  24. 1
      server/yudao-framework/yudao-spring-boot-starter-mybatis/《芋道 Spring Boot 数据库连接池入门》.md
  25. 1
      server/yudao-framework/yudao-spring-boot-starter-redis/《芋道 Spring Boot Cache 入门》.md
  26. 1
      server/yudao-framework/yudao-spring-boot-starter-redis/《芋道 Spring Boot Redis 入门》.md
  27. 2
      server/yudao-framework/yudao-spring-boot-starter-security/《芋道 Spring Boot 安全框架 Spring Security 入门》.md
  28. 8
      server/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/banner/core/BannerApplicationRunner.java
  29. 10
      server/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java
  30. 35
      server/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/DemoFilter.java
  31. 94
      server/yudao-framework/yudao-spring-boot-starter-web/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java
  32. 19
      server/yudao-framework/yudao-spring-boot-starter-web/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java
  33. 1
      server/yudao-framework/yudao-spring-boot-starter-web/《芋道 Spring Boot API 接口文档 Swagger 入门》.md
  34. 1
      server/yudao-framework/yudao-spring-boot-starter-web/《芋道 Spring Boot SpringMVC 入门》.md
  35. 1
      server/yudao-framework/yudao-spring-boot-starter-websocket/《芋道 Spring Boot WebSocket 入门》.md
  36. 1
      server/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md
  37. 1
      server/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/monitor/《芋道 Spring Boot 监控工具 Admin 入门》.md
  38. BIN
      server/yudao-module-infra/src/main/resources/file/erweima.jpg
  39. 103
      server/yudao-module-lock/pom.xml
  40. 120
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/JsSdkController.java
  41. 109
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/LockController.java
  42. 105
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/LockGuideController.java
  43. 109
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/LockWorkRecordController.java
  44. 121
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanController.java
  45. 105
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanItemController.java
  46. 108
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanItemDetailController.java
  47. 111
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanLifeLockController.java
  48. 183
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PointController.java
  49. 4
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/package-info.java
  50. 40
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/IsolationPointDO.java
  51. 61
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/LockDO.java
  52. 66
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/LockGuideDO.java
  53. 64
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/LockWorkRecordDO.java
  54. 41
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanDO.java
  55. 62
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanItemDO.java
  56. 50
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanItemDetailDO.java
  57. 58
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanLifeLockDO.java
  58. 57
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PointDO.java
  59. 27
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/LockEntity.java
  60. 25
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanEntity.java
  61. 40
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanItemDetailEntity.java
  62. 52
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanItemEntity.java
  63. 48
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanLifeLockEntity.java
  64. 44
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/enums/ErrorCodeConstants.java
  65. 6
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/framework/package-info.java
  66. 24
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/framework/web/config/LockWebConfiguration.java
  67. 4
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/framework/web/package-info.java
  68. 26
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/IsolationPointMapper.java
  69. 25
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/LockGuideMapper.java
  70. 37
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/LockMapper.java
  71. 32
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/LockWorkRecordMapper.java
  72. 31
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanItemDetailMapper.java
  73. 32
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanItemMapper.java
  74. 33
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanLifeLockMapper.java
  75. 26
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanMapper.java
  76. 32
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PointMapper.java
  77. 12
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/package-info.java
  78. 64
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/IsolationPointService.java
  79. 63
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/LockGuideService.java
  80. 65
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/LockService.java
  81. 63
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/LockWorkRecordService.java
  82. 64
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanItemDetailService.java
  83. 63
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanItemService.java
  84. 64
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanLifeLockService.java
  85. 66
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanService.java
  86. 82
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PointService.java
  87. 102
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/IsolationPointServiceImpl.java
  88. 86
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/LockGuideServiceImpl.java
  89. 92
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/LockServiceImpl.java
  90. 85
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/LockWorkRecordServiceImpl.java
  91. 90
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanItemDetailServiceImpl.java
  92. 84
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanItemServiceImpl.java
  93. 120
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanLifeLockServiceImpl.java
  94. 184
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanServiceImpl.java
  95. 353
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PointServiceImpl.java
  96. 174
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/util/WordUtils.java
  97. 26
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/IsolationPointPageReqVO.java
  98. 31
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/IsolationPointRespVO.java
  99. 23
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/IsolationPointSaveReqVO.java
  100. 56
      server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/LockGuidePageReqVO.java

9
.idea/ElectronicLock.iml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

7
.idea/inspectionProfiles/Project_Default.xml

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>

6
.idea/misc.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/ElectronicLock.iml" filepath="$PROJECT_DIR$/.idea/ElectronicLock.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

47
.idea/workspace.xml

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ChangeListManager">
<list default="true" id="211851b0-9ab0-4e5f-aa9e-26a8bc90bd1a" name="Changes" comment="" />
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 0
}]]></component>
<component name="ProjectId" id="31XXEBRCJdorsK3ASEM8ZJM1UA5" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
<option name="showMembers" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"WebServerToolWindowFactoryState": "false",
"git-widget-placeholder": "master",
"last_opened_file_path": "C:/Users/admin/Desktop/xiangmu",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="211851b0-9ab0-4e5f-aa9e-26a8bc90bd1a" name="Changes" comment="" />
<created>1755671276644</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1755671276644</updated>
<workItem from="1755671278263" duration="46000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

91
server/dependencies/pom.xml

@ -14,7 +14,7 @@
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
<properties>
<revision>2.6.1-SNAPSHOT</revision>
<revision>2025.08-SNAPSHOT</revision>
<flatten-maven-plugin.version>1.6.0</flatten-maven-plugin.version>
<!-- 统一依赖管理 -->
<spring.boot.version>3.4.5</spring.boot.version>
@ -24,9 +24,9 @@
<!-- DB 相关 -->
<druid.version>1.2.24</druid.version>
<mybatis.version>3.5.19</mybatis.version>
<mybatis-plus.version>3.5.10.1</mybatis-plus.version>
<mybatis-plus.version>3.5.12</mybatis-plus.version>
<mybatis-plus-join.version>1.5.4</mybatis-plus-join.version>
<dynamic-datasource.version>4.3.1</dynamic-datasource.version>
<mybatis-plus-join.version>1.4.13</mybatis-plus-join.version>
<easy-trans.version>3.0.6</easy-trans.version>
<redisson.version>3.41.0</redisson.version>
<dm8.jdbc.version>8.1.3.140</dm8.jdbc.version>
@ -54,7 +54,7 @@
<mapstruct.version>1.6.3</mapstruct.version>
<hutool-5.version>5.8.35</hutool-5.version>
<hutool-6.version>6.0.0-M19</hutool-6.version>
<easyexcel.version>4.0.3</easyexcel.version>
<fastexcel.version>1.2.0</fastexcel.version>
<velocity.version>2.4.1</velocity.version>
<fastjson.version>1.2.83</fastjson.version>
<guava.version>33.4.8-jre</guava.version>
@ -69,22 +69,32 @@
<pf4j-spring.version>0.9.0</pf4j-spring.version>
<vertx.version>4.5.13</vertx.version>
<!-- 三方云服务相关 -->
<commons-io.version>2.17.0</commons-io.version>
<commons-compress.version>1.27.1</commons-compress.version>
<awssdk.version>2.30.14</awssdk.version>
<!--
<justauth.version>1.16.7</justauth.version>
-->
<justauth-starter.version>1.4.0</justauth-starter.version>
<jimureport.version>2.0.0</jimureport.version>
<jimubi.version>1.9.5</jimubi.version>
<!--
<weixin-java.version>4.7.5.B</weixin-java.version>
-->
<word.version>5.2.3</word.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${word.version}</version> <!-- 建议使用较新稳定版本 -->
</dependency>
<!-- (可选,但建议包含) Apache POI for reading old .doc files -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>${word.version}</version>
</dependency>
<!-- 统一依赖管理 -->
<dependency>
<groupId>io.netty</groupId>
@ -255,23 +265,23 @@
</exclusions>
</dependency>
<!-- <dependency>
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>${dm8.jdbc.version}</version>
</dependency>-->
<!--
</dependency>
<dependency>
<groupId>org.opengauss</groupId>
<artifactId>opengauss-jdbc</artifactId>
<version>${opengauss.jdbc.version}</version>
</dependency>-->
<!--
</dependency>
<dependency>
<groupId>cn.com.kingbase</groupId>
<artifactId>kingbase8</artifactId>
<version>${kingbase.jdbc.version}</version>
</dependency>-->
</dependency>
<dependency>
<groupId>com.taosdata.jdbc</groupId>
@ -412,6 +422,18 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.github.fppt</groupId> <!-- 单元测试,我们采用内嵌的 Redis 数据库 -->
<artifactId>jedis-mock</artifactId>
<version>${jedis-mock.version}</version>
</dependency>
<dependency>
<groupId>uk.co.jemos.podam</groupId> <!-- 单元测试,随机生成 POJO 类 -->
<artifactId>podam</artifactId>
<version>${podam.version}</version>
</dependency>
<!-- 工作流相关 -->
<dependency>
<groupId>org.flowable</groupId>
@ -449,11 +471,11 @@
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
<version>${mapstruct.version}</version>
</dependency>
<!-- <dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>-->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
@ -472,20 +494,11 @@
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>${commons-compress.version}</version>
<groupId>cn.idev.excel</groupId>
<artifactId>fastexcel</artifactId>
<version>${fastexcel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <!-- 文件类型的识别 -->
@ -553,25 +566,25 @@
<version>${awssdk.version}</version>
</dependency>
<!-- <dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId> &lt;!&ndash; 社交登陆(例如说,个人微信、企业微信等等) &ndash;&gt;
<artifactId>JustAuth</artifactId> <!-- 社交登陆(例如说,个人微信、企业微信等等) -->
<version>${justauth.version}</version>
</dependency>&ndash;&gt;-->
<!-- <dependency>
</dependency>
<dependency>
<groupId>com.xkcoding.justauth</groupId>
<artifactId>justauth-spring-boot-starter</artifactId>
<version>${justauth-starter.version}</version>
<exclusions>
&lt;!&ndash; 移除,避免和项目里的 hutool-all 冲突 &ndash;&gt;
<!-- 移除,避免和项目里的 hutool-all 冲突 -->
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</exclusion>
</exclusions>
</dependency>-->
</dependency>
<!-- <dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId>
<version>${weixin-java.version}</version>
@ -585,7 +598,7 @@
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
<version>${weixin-java.version}</version>
</dependency>-->
</dependency>
<!-- 积木报表-->
<dependency>

3
server/pom.xml

@ -17,7 +17,8 @@
<module>yudao-module-infra</module>
<module>yudao-module-bpm</module>
<module>yudao-module-report</module>
<module>yudao-module-iot</module>
<module>yudao-module-lock</module>
<!--<module>yudao-module-iot</module>-->
</modules>
<name>${project.artifactId}</name>

13744
server/sql/2025.08.20.sql

File diff suppressed because one or more lines are too long

403
server/tmp/.scr/auto_export.py

@ -0,0 +1,403 @@
#!/usr/bin/env python
# -*-coding:utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.chrome.options import Options
import time
import sys
import getopt
import json
import os
import shutil
import platform
import re
# import traceback
import base64
import io
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
# 默认文件下载目录 改成自己服务器的
DEFAULT_BASE_DOWNLOAD_PATH = os.path.dirname(os.path.realpath('__file__')) + os.sep + "downloads" + os.sep
# update-begin---author:chenrui ---date:20240130 for:[QQYUN-8127]通过接口导出功能要获取token和查询参数------------
# 临时下载目录
TEMP_DOWNLOAD_PATH = os.sep + "temp" + os.sep
# update-end---author:chenrui ---date:20240130 for:[QQYUN-8127]通过接口导出功能要获取token和查询参数------------
# 默认积木报表访问地址 改成自己的
DEFAULT_BASE_SHARE_VIEW_URL = "http://localhost:8085/jmreport/view/"
# 结束日志标识
LOG_END_MARK = "$JM$END$"
def append_common_params(payload: str, token: str) -> str:
"""
拼接报表的通用参数
:param payload:
:param token:
:return:
"""
if payload is None or len(payload) == 0:
return ""
if token is not None and len(token) > 0:
token = "token=" + token
if "?" in payload:
payload += "&" + token
else:
payload += "?" + token
if "?" in payload:
payload += "&directDld=1"
else:
payload += "?directDld=1"
return payload
def dict_2_str_payload(payload: dict) -> str:
"""
字典数据转换为查询payload
:param payload:
:return:
"""
if payload is not None and len(payload) > 0:
return str("&".join([key + "=" + val for key, val in payload.items() if key is not None and len(key) > 0]))
else:
return ""
def init_args(argv=None):
"""初始化参数"""
global opts
print('共有:', len(argv), '个参数。')
if len(argv) <= 0:
raise Exception('参数异常')
arg = argv[0]
if arg is not None and len(arg) > 0:
opts = json.loads(base64.b64decode(arg))
# 批次号
batch_no = None
# 导出类型
export_type = 'PDF'
# 报表ids
report_ids = None
# 报表参数,与report_ids二选一
report_params = list()
# 积木报表预览页面地址
base_share_view_url = DEFAULT_BASE_SHARE_VIEW_URL
# 报表下载基础目录
base_download_path = DEFAULT_BASE_DOWNLOAD_PATH
# token
token = ''
if 'batch_no' in opts:
batch_no = opts['batch_no']
if 'export_type' in opts:
export_type = opts['export_type']
if 'report_ids' in opts:
report_ids = opts['report_ids']
if 'report_params' in opts:
report_params = opts['report_params']
if 'jimu_view_url' in opts:
base_share_view_url = opts['jimu_view_url']
if 'base_download_path' in opts:
base_download_path = opts['base_download_path']
if 'token' in opts:
token = opts['token']
if export_type.upper() == "EXCEL":
export_type = "Excel"
elif export_type.upper() == "PDF":
export_type = "PDF"
else:
export_type = "PDF"
# 拼接报表查询参数
reports: list[dict] = list()
if report_params is not None and len(report_params) > 0:
for report_param in report_params:
report_query = report_param['id']
if 'params' in report_param:
params = report_param['params']
if params is not None and len(params) > 0:
payload = dict_2_str_payload(params)
if payload is not None and len(payload) > 0:
report_query += "?" + payload
custom_export_type = export_type
if 'export_type' in report_param:
custom_export_type = report_param['export_type']
custom_export_type = export_type if custom_export_type is None else custom_export_type
reports.append({"url": append_common_params(report_query, token), "export_type": custom_export_type})
elif report_ids is not None and len(report_ids) > 0:
reports = [{"url": append_common_params(report_id, token), "export_type": export_type} for report_id in
report_ids]
# 确保传入路径正确,统一修改所有的/ 和 \\为当前系统的盘符
base_download_path = base_download_path.replace("/", os.sep).replace("\\", os.sep)
if not os.path.isabs(base_download_path):
raise Exception("导出失败,下载目录必须是绝对路径")
if "windows" in platform.platform().lower() and base_download_path.startswith("\\"):
# windows 系统下 并且没有写盘符时,拼接盘符
run_path = os.path.dirname(os.path.realpath('__file__'))
base_download_path = os.path.splitdrive(run_path)[0] + base_download_path
options = {
'batch_no': batch_no,
'export_type': export_type,
'reports': reports,
"base_share_view_url": base_share_view_url,
"base_download_path": base_download_path
}
print("运行参数:" + json.dumps(options))
return options
def auto_export(options):
print(" >>> java进入Python 脚本方法,options = ", options)
"""
自动导出函数
:param options: {batch_no:批次号,export_type:导出类型,reports:[{url:报表url,export_type:导出类型}]}
"""
# 整理参数
batch_no = options['batch_no']
export_type = options['export_type']
reports = None
# 优先使用report
if "reports" in options:
reports = options['reports']
if not reports or reports is None:
if "report_ids" in options:
report_ids = options['report_ids']
if not report_ids:
raise Exception('报表id不能为空')
else:
# reports 为空,将report_ids转换为reports
reports = [{"url": report_id, "export_type": export_type} for report_id in report_ids]
else:
raise Exception('报表id不能为空')
if not batch_no or not reports:
raise Exception('批次编号或报表id不能为空')
# 下载目录
download_path = options["base_download_path"] + batch_no
# 获取域名
base_share_view_url = options["base_share_view_url"]
match = re.match(r'(http[s]?://[^/]+)', base_share_view_url)
if match:
base_url = match.group(1)
else:
base_url = ""
# 获取webDriver
driver = build_web_driver(download_path, base_url)
# 确保目录存在
if os.path.exists(download_path) is False:
os.makedirs(download_path)
# update-begin---author:chenrui ---date:20240129 for:[QQYUN-8127]通过接口导出功能要获取token和查询参数------------
else:
# 清空文件夹并重建
shutil.rmtree(download_path)
os.makedirs(download_path)
# 确保临时目录存在
if os.path.exists(download_path + TEMP_DOWNLOAD_PATH) is False:
os.makedirs(download_path + TEMP_DOWNLOAD_PATH)
# update-end---author:chenrui ---date:20240129 for:[QQYUN-8127]通过接口导出功能要获取token和查询参数------------
downloaded_count = 0
download_failure_rids = []
# 导出失败的报表标题
failure_report_title = ""
# 开始自动导出
for report in reports:
report_url = report['url']
custom_export_type = report['export_type']
if not custom_export_type:
custom_export_type = export_type
else:
if custom_export_type.upper() == "EXCEL":
custom_export_type = "Excel"
elif custom_export_type.upper() == "PDF":
custom_export_type = "PDF"
else:
custom_export_type = "PDF"
print("开始导出报表:" + report_url)
# 打开url网页
driver.get(options["base_share_view_url"] + report_url)
# 等待数据查询完成
export_el = WebDriverWait(driver, 10, 0.2).until_not(
EC.presence_of_element_located((By.CLASS_NAME, "ivu-spin-fullscreen"))
)
# 等待导出按钮加载完成
export_el = WebDriverWait(driver, 10, 0.2).until(
EC.presence_of_element_located((By.CLASS_NAME, "export"))
)
# 获取title
title = driver.title
if len(title) > 0 and "-" in title:
title = title[:title.rindex("-")].strip()
print("报表名称:" + title)
if not download_check(download_path, title, custom_export_type.lower(), 1):
# 报表不存在,开始下载
print("报表{}未下载,开始下载...".format(title))
# 等待0.5秒,防止页面未完成渲染
time.sleep(0.5)
# 鼠标移到导出按钮
ActionChains(driver).move_to_element(export_el).perform()
# 点击导出pdf按钮
driver.find_element(By.ID, custom_export_type).click()
# 检查是否下载完成
if not download_check(download_path, title, custom_export_type.lower(), 30, 1):
print("报表{}下载失败".format(title))
failure_report_title += title + " "
download_failure_rids.append(report_url)
else:
downloaded_count = downloaded_count + 1
print("报表:" + report_url + "导出完成")
else:
# 报表存在
downloaded_count = downloaded_count + 1
# update-begin---author:chenrui ---date:20240129 for:统一py脚本的返回结果格式------------
err_msg = ""
if len(reports) != downloaded_count:
err_msg = "报表[" + failure_report_title + "]导出失败"
result = {
"success": len(reports) == downloaded_count,
"message": err_msg,
"result": {
"report_count": len(reports),
"downloaded_count": downloaded_count,
"failure_rids": download_failure_rids,
"download_path": download_path,
**options
}
}
# update-end---author:chenrui ---date:20240129 for:统一py脚本的返回结果格式------------
# 退出浏览器
driver.quit()
return result
def build_web_driver(download_path, safe_domain=""):
"""
构建webDriver
:param safe_domain: 安全域名
:param download_path: 下载目录
:return: webDriver
"""
chrome_options = Options()
# 不使用沙箱
chrome_options.add_argument('--no-sandbox')
# 将浏览器静音
chrome_options.add_argument("--mute-audio")
# 当程序结束时,浏览器不会关闭
# chrome_options.add_experimental_option("detach", True)
# 开启无界面浏览器(minos必须开启无界面)
chrome_options.add_argument("--headless")
# 禁用gpu
chrome_options.add_argument("--disable-gpu")
# 添加安全域名
if safe_domain is not None and bool(safe_domain):
chrome_options.add_argument("--unsafely-treat-insecure-origin-as-secure=" + safe_domain)
if 'linux' in platform.platform().lower():
# fix:DevToolsActivePort file doesn't
chrome_options.add_argument('--disable-dev-shm-usage')
chrome_options.add_argument('--remote-debugging-port=9222')
# 设置下载路径
prefs = {'profile.default_content_settings.popups': 0,
'download.prompt_for_download': False,
'safebrowsing.disable_download_protection': True,
'download.default_directory': download_path + TEMP_DOWNLOAD_PATH}
chrome_options.add_experimental_option('prefs', prefs)
# 忽略不安全的错误
chrome_options.add_argument('ignore-certificate-errors')
# Chrome浏览器
driver = webdriver.Chrome(options=chrome_options)
return driver
def download_check(check_path, check_file_name, check_ext, check_times=3, check_interval=5):
"""
检测函数
:param check_path:检测路径
:param check_file_name: 检查文件名称
:param check_ext:检测扩展名
:param check_times:检测次数默认值:3
:param check_interval:检测时间间隔默认值:5
:return:返回真假
"""
temp_check_path = check_path + TEMP_DOWNLOAD_PATH
if os.path.exists(temp_check_path) is False:
return False
else:
for number in range(0, int(check_times)):
print("验证文件{}是否存在;第{}次检测.".format(check_file_name, str(number + 1)))
# time.sleep(0.2)
# 读取目录下所有文件
# update-begin---author:chenrui ---date:20240129 for:[QQYUN-8127]通过接口导出功能要获取token和查询参数------------
files = os.listdir(temp_check_path)
file_number = len(files)
if file_number > 0:
# 存在多个文件,检查当前文件是否存在
for file in files:
if str(check_file_name.strip()) in str(file):
# 文件存在
dest_move_file_path = check_path
if os.path.exists(check_path + os.sep + str(file)):
print("文件{}存在;重命名该文件.".format(check_file_name, str(number + 1)))
filename, extension = os.path.splitext(file)
dest_move_file_path += (os.sep + filename
+ "({})".format(str(int(time.time())))
+ extension)
shutil.move(temp_check_path + str(file), dest_move_file_path)
# update-end---author:chenrui ---date:20240129 for:[QQYUN-8127]通过接口导出功能要获取token和查询参数------------
return True
# 文件不存在
if check_times != 1 or number < check_times - 1:
time.sleep(int(check_interval)) # 休眠一会
return False
if __name__ == '__main__':
"""
入口
"""
result = {}
try:
print(" >>> java进入Python ==> step.1 进入Main方法")
args = sys.argv[1:]
# #本地调试参数
# args = ['-b', '1713260060264cubcWF', '-r',
# '537516331017523200?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MTM1NTgxNDQsInVzZXJuYW1lIjoiMTg2MTE3ODg1MjUifQ.JXZLzqgkuZRcbEYFn0l-L0DXZzOw3hJZIzn0y2EmzQM',
# '-t', 'PDF', '-s', 'http://localhost:8087/jmreport/view/', '-d', 'E:\\opt\\jmpydownload\\']
print(" >>> java进入Python ==> step.2 初始化参数")
export_options = init_args(args)
print(" >>> java进入Python ==> step.3 开始执行py脚本")
result = auto_export(export_options)
print(" >>> java进入Python ==> step.4 返回执行结果")
except Exception as e:
print("异常日志:", e)
# traceback.print_exc()
msg = ""
if hasattr(e, "msg"):
msg = e.msg
else:
msg = str(e)
# update-begin---author:chenrui ---date:20240129 for:统一py脚本的返回结果格式------------
result = {
"success": False,
"message": msg,
"result": None
}
# update-end---author:chenrui ---date:20240129 for:统一py脚本的返回结果格式------------
print(LOG_END_MARK + json.dumps(result) + LOG_END_MARK)

1
server/yudao-framework/yudao-common/《芋道 Spring Boot 参数校验 Validation 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Validation/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-excel/pom.xml

@ -62,6 +62,7 @@
<optional>true</optional> <!-- 设置为 optional,只有在 AreaConvert 的时候使用 -->
</dependency>
<!-- Test 测试相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>

1
server/yudao-framework/yudao-spring-boot-starter-job/《芋道 Spring Boot 定时任务入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Job/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-job/《芋道 Spring Boot 异步任务入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Async-Job/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-monitor/《芋道 Spring Boot 监控工具 Admin 入门》.md

@ -0,0 +1 @@
<https://www.iocoder.cn/Spring-Boot/Admin/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-monitor/《芋道 Spring Boot 监控端点 Actuator 入门》.md

@ -0,0 +1 @@
<https://www.iocoder.cn/Spring-Boot/Actuator/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-monitor/《芋道 Spring Boot 链路追踪 SkyWalking 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/SkyWalking/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 事件机制 Event 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/RocketMQ/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 Kafka 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Kafka/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RabbitMQ 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/RabbitMQ/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mq/《芋道 Spring Boot 消息队列 RocketMQ 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/RocketMQ/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mybatis/《芋道 Spring Boot MyBatis 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mybatis/《芋道 Spring Boot 多数据源(读写分离)入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/dynamic-datasource/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-mybatis/《芋道 Spring Boot 数据库连接池入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-redis/《芋道 Spring Boot Cache 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Cache/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-redis/《芋道 Spring Boot Redis 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Redis/?yudao>

2
server/yudao-framework/yudao-spring-boot-starter-security/《芋道 Spring Boot 安全框架 Spring Security 入门》.md

@ -0,0 +1,2 @@
* 芋道 Spring Security 入门:<http://www.iocoder.cn/Spring-Boot/Spring-Security/?yudao>
* Spring Security 基本概念:<http://www.iocoder.cn/Fight/Spring-Security-4-1-0-Basic-concept-description/?yudao>

8
server/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/banner/core/BannerApplicationRunner.java

@ -20,7 +20,7 @@ public class BannerApplicationRunner implements ApplicationRunner {
public void run(ApplicationArguments args) {
ThreadUtil.execute(() -> {
ThreadUtil.sleep(1, TimeUnit.SECONDS); // 延迟 1 秒,保证输出到结尾
log.info("\n----------------------------------------------------------\n\t" +
/* log.info("\n----------------------------------------------------------\n\t" +
"项目启动成功!\n\t" +
"接口文档: \t{} \n\t" +
"开发文档: \t{} \n\t" +
@ -28,7 +28,7 @@ public class BannerApplicationRunner implements ApplicationRunner {
"----------------------------------------------------------",
"https://doc.iocoder.cn/api-doc/",
"https://doc.iocoder.cn",
"https://t.zsxq.com/02Yf6M7Qn");
"https://t.zsxq.com/02Yf6M7Qn");*/
// 数据报表
if (isNotPresent("cn.iocoder.yudao.module.report.framework.security.config.SecurityConfiguration")) {
@ -38,7 +38,7 @@ public class BannerApplicationRunner implements ApplicationRunner {
if (isNotPresent("cn.iocoder.yudao.module.bpm.framework.flowable.config.BpmFlowableConfiguration")) {
System.out.println("[工作流模块 yudao-module-bpm - 已禁用][参考 https://doc.iocoder.cn/bpm/ 开启]");
}
// 商城系统
/* // 商城系统
if (isNotPresent("cn.iocoder.yudao.module.trade.framework.web.config.TradeWebConfiguration")) {
System.out.println("[商城系统 yudao-module-mall - 已禁用][参考 https://doc.iocoder.cn/mall/build/ 开启]");
}
@ -57,7 +57,7 @@ public class BannerApplicationRunner implements ApplicationRunner {
// 支付平台
if (isNotPresent("cn.iocoder.yudao.module.pay.framework.pay.config.PayConfiguration")) {
System.out.println("[支付系统 yudao-module-pay - 已禁用][参考 https://doc.iocoder.cn/pay/build/ 开启]");
}
}*/
// AI 大模型
if (isNotPresent("cn.iocoder.yudao.module.ai.framework.web.config.AiWebConfiguration")) {
System.out.println("[AI 大模型 yudao-module-ai - 已禁用][参考 https://doc.iocoder.cn/ai/build/ 开启]");

10
server/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/config/YudaoWebAutoConfiguration.java

@ -3,7 +3,6 @@ package cn.iocoder.yudao.framework.web.config;
import cn.iocoder.yudao.framework.common.biz.infra.logger.ApiErrorLogCommonApi;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.web.core.filter.CacheRequestBodyFilter;
import cn.iocoder.yudao.framework.web.core.filter.DemoFilter;
import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.yudao.framework.web.core.handler.GlobalResponseBodyHandler;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
@ -102,15 +101,6 @@ public class YudaoWebAutoConfiguration implements WebMvcConfigurer {
return createFilterBean(new CacheRequestBodyFilter(), WebFilterOrderEnum.REQUEST_BODY_CACHE_FILTER);
}
/**
* 创建 DemoFilter Bean演示模式
*/
@Bean
@ConditionalOnProperty(value = "yudao.demo", havingValue = "true")
public FilterRegistrationBean<DemoFilter> demoFilter() {
return createFilterBean(new DemoFilter(), WebFilterOrderEnum.DEMO_FILTER);
}
public static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
bean.setOrder(order);

35
server/yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/filter/DemoFilter.java

@ -1,35 +0,0 @@
package cn.iocoder.yudao.framework.web.core.filter;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.servlet.ServletUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.DEMO_DENY;
/**
* 演示 Filter禁止用户发起写操作避免影响测试数据
*
* @author 芋道源码
*/
public class DemoFilter extends OncePerRequestFilter {
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
String method = request.getMethod();
return !StrUtil.equalsAnyIgnoreCase(method, "POST", "PUT", "DELETE") // 写操作时,不进行过滤率
|| WebFrameworkUtils.getLoginUserId(request) == null; // 非登录用户时,不进行过滤
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
// 直接返回 DEMO_DENY 的结果。即,请求不继续
ServletUtils.writeJSON(response, CommonResult.error(DEMO_DENY));
}
}

94
server/yudao-framework/yudao-spring-boot-starter-web/src/test/java/cn/iocoder/yudao/framework/desensitize/core/DesensitizeTest.java

@ -0,0 +1,94 @@
package cn.iocoder.yudao.framework.desensitize.core;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.desensitize.core.annotation.Address;
import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.EmailDesensitize;
import cn.iocoder.yudao.framework.desensitize.core.regex.annotation.RegexDesensitize;
import cn.iocoder.yudao.framework.desensitize.core.slider.annotation.*;
import lombok.Data;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* {@link DesensitizeTest} 的单元测试
*/
@ExtendWith(MockitoExtension.class)
public class DesensitizeTest {
@Test
public void test() {
// 准备参数
DesensitizeDemo desensitizeDemo = new DesensitizeDemo();
desensitizeDemo.setNickname("芋道源码");
desensitizeDemo.setBankCard("9988002866797031");
desensitizeDemo.setCarLicense("粤A66666");
desensitizeDemo.setFixedPhone("01086551122");
desensitizeDemo.setIdCard("530321199204074611");
desensitizeDemo.setPassword("123456");
desensitizeDemo.setPhoneNumber("13248765917");
desensitizeDemo.setSlider1("ABCDEFG");
desensitizeDemo.setSlider2("ABCDEFG");
desensitizeDemo.setSlider3("ABCDEFG");
desensitizeDemo.setEmail("1@email.com");
desensitizeDemo.setRegex("你好,我是芋道源码");
desensitizeDemo.setAddress("北京市海淀区上地十街10号");
desensitizeDemo.setOrigin("芋道源码");
// 调用
DesensitizeDemo d = JsonUtils.parseObject(JsonUtils.toJsonString(desensitizeDemo), DesensitizeDemo.class);
// 断言
assertNotNull(d);
assertEquals("芋***", d.getNickname());
assertEquals("998800********31", d.getBankCard());
assertEquals("粤A6***6", d.getCarLicense());
assertEquals("0108*****22", d.getFixedPhone());
assertEquals("530321**********11", d.getIdCard());
assertEquals("******", d.getPassword());
assertEquals("132****5917", d.getPhoneNumber());
assertEquals("#######", d.getSlider1());
assertEquals("ABC*EFG", d.getSlider2());
assertEquals("*******", d.getSlider3());
assertEquals("1****@email.com", d.getEmail());
assertEquals("你好,我是*", d.getRegex());
assertEquals("北京市海淀区上地十街10号*", d.getAddress());
assertEquals("芋道源码", d.getOrigin());
}
@Data
public static class DesensitizeDemo {
@ChineseNameDesensitize
private String nickname;
@BankCardDesensitize
private String bankCard;
@CarLicenseDesensitize
private String carLicense;
@FixedPhoneDesensitize
private String fixedPhone;
@IdCardDesensitize
private String idCard;
@PasswordDesensitize
private String password;
@MobileDesensitize
private String phoneNumber;
@SliderDesensitize(prefixKeep = 6, suffixKeep = 1, replacer = "#")
private String slider1;
@SliderDesensitize(prefixKeep = 3, suffixKeep = 3)
private String slider2;
@SliderDesensitize(prefixKeep = 10)
private String slider3;
@EmailDesensitize
private String email;
@RegexDesensitize(regex = "芋道源码", replacer = "*")
private String regex;
@Address
private String address;
private String origin;
}
}

19
server/yudao-framework/yudao-spring-boot-starter-web/src/test/java/cn/iocoder/yudao/framework/desensitize/core/handler/AddressHandler.java

@ -0,0 +1,19 @@
package cn.iocoder.yudao.framework.desensitize.core.handler;
import cn.iocoder.yudao.framework.desensitize.core.DesensitizeTest;
import cn.iocoder.yudao.framework.desensitize.core.base.handler.DesensitizationHandler;
import cn.iocoder.yudao.framework.desensitize.core.annotation.Address;
/**
* {@link Address} 的脱敏处理器
*
* 用于 {@link DesensitizeTest} 测试使用
*/
public class AddressHandler implements DesensitizationHandler<Address> {
@Override
public String desensitize(String origin, Address annotation) {
return origin + annotation.replacer();
}
}

1
server/yudao-framework/yudao-spring-boot-starter-web/《芋道 Spring Boot API 接口文档 Swagger 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Swagger/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-web/《芋道 Spring Boot SpringMVC 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/SpringMVC/?yudao>

1
server/yudao-framework/yudao-spring-boot-starter-websocket/《芋道 Spring Boot WebSocket 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/WebSocket/?yudao>

1
server/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/convert/《芋道 Spring Boot 对象转换 MapStruct 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/MapStruct/?yudao>

1
server/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/framework/monitor/《芋道 Spring Boot 监控工具 Admin 入门》.md

@ -0,0 +1 @@
<http://www.iocoder.cn/Spring-Boot/Admin/?yudao>

BIN
server/yudao-module-infra/src/main/resources/file/erweima.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

103
server/yudao-module-lock/pom.xml

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>cn.iocoder.boot</groupId>
<artifactId>cc-admin-master</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>yudao-module-lock</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>
</description>
<dependencies>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-module-infra</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-web</artifactId>
</dependency>
<!-- 业务组件 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-data-permission</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
</dependency>
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>cn.iocoder.boot</groupId>
<artifactId>yudao-spring-boot-starter-excel</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>captcha-spring-boot-starter</artifactId> <!-- 验证码,一般用于登录使用 -->
</dependency>
<dependency>
<groupId>org.dromara.hutool</groupId>
<artifactId>hutool-extra</artifactId> <!-- 邮件 -->
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-mp-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-cp-spring-boot-starter</artifactId>
<version>4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>5.2.3</version>
</dependency>
</dependencies>
</project>

120
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/JsSdkController.java

@ -0,0 +1,120 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.security.PermitAll;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpMessageService;
import me.chanjar.weixin.cp.api.WxCpUserService;
import me.chanjar.weixin.cp.bean.WxCpAgentJsapiSignature;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import me.chanjar.weixin.cp.api.WxCpService;
import java.net.http.HttpClient;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@Tag(name = "企业微信回调")
@RestController
@RequestMapping("/js/weixin")
@Slf4j
public class JsSdkController {
@Autowired
private WxCpService wxCpService;
@GetMapping("/getConfigSignature")
@PermitAll
@TenantIgnore
public WxJsapiSignature getConfigSignature(@RequestParam(required = false) String url) {
try {
return wxCpService.createJsapiSignature(url);
} catch (Exception e) {
log.error("[getConfigSignature][url({}) 发生异常]", url, e);
}
return null;
}
@GetMapping("/getAgentConfigSignature")
@PermitAll
@TenantIgnore
public WxCpAgentJsapiSignature getAgentConfigSignature(@RequestParam(required = false) String url) {
try {
return wxCpService.createAgentJsapiSignature(url);
} catch (Exception e) {
log.error("[getConfigSignature][url({}) 发生异常]", url, e);
}
return null;
}
@GetMapping("/sendMessage")
@PermitAll
@TenantIgnore
public void sendMessage(@RequestParam(required = false) String data) {
WxCpMessageService messageService = wxCpService.getMessageService();
String title = "解锁完成";
String description = "<div class=\"gray\">2025年8月7日</div>" +
"<div class=\"normal\">下午3:00解锁完成</div>" +
"<div class=\"highlight\">请停止作业</div>";
String url = "https://example.com/meeting/details/123";
String btnText = " ";
WxCpMessage message = WxCpMessage.TEXTCARD()
.agentId(1000002)
.toUser("@all")
.title(title)
.description(description)
.url(url)
.btnTxt(btnText)
.build();
// 3. 调用 send 方法发送消息
try {
WxCpMessageSendResult sendResult = messageService.send(message);
// 你可以根据 sendResult 的内容进行后续处理
System.out.println("消息发送成功: " + sendResult);
} catch (WxErrorException e) {
// 异常处理,例如记录日志、发送告警等
System.err.println("消息发送失败: " + e.getError().getErrorMsg());
}
}
@GetMapping("/call/action")
@PermitAll
@TenantIgnore
public void action(@RequestParam(required = false) String data) {
System.out.println(data);
log.info(data);
}
@GetMapping("/call/data")
@PermitAll
@TenantIgnore
public void data(@RequestParam(required = false) String data) {
System.out.println(data);
log.info(data);
}
}

109
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/LockController.java

@ -0,0 +1,109 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.LockDO;
import cn.iocoder.yudao.module.lock.service.LockService;
import cn.iocoder.yudao.module.lock.vo.LockPageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockRespVO;
import cn.iocoder.yudao.module.lock.vo.LockSaveReqVO;
import jakarta.annotation.security.PermitAll;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 电子锁")
@RestController
@RequestMapping("/electron/lock")
@Validated
public class LockController {
@Resource
private LockService lockService;
@PostMapping("/create")
@Operation(summary = "创建电子锁")
@PreAuthorize("@ss.hasPermission('electron:lock:create')")
public CommonResult<Long> createLock(@Valid @RequestBody LockSaveReqVO createReqVO) {
return success(lockService.createLock(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新电子锁")
@PreAuthorize("@ss.hasPermission('electron:lock:update')")
public CommonResult<Boolean> updateLock(@Valid @RequestBody LockSaveReqVO updateReqVO) {
lockService.updateLock(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除电子锁")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('electron:lock:delete')")
public CommonResult<Boolean> deleteLock(@RequestParam("id") Long id) {
lockService.deleteLock(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除电子锁")
@PreAuthorize("@ss.hasPermission('electron:lock:delete')")
public CommonResult<Boolean> deleteLockList(@RequestParam("ids") List<Long> ids) {
lockService.deleteLockListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得电子锁")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('electron:lock:query')")
public CommonResult<LockRespVO> getLock(@RequestParam("id") Long id) {
LockDO lock = lockService.getLock(id);
return success(BeanUtils.toBean(lock, LockRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得电子锁分页")
@PreAuthorize("@ss.hasPermission('electron:lock:query')")
public CommonResult<PageResult<LockRespVO>> getLockPage(@Valid LockPageReqVO pageReqVO) {
PageResult<LockDO> pageResult = lockService.getLockPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, LockRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出电子锁 Excel")
@PreAuthorize("@ss.hasPermission('electron:lock:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportLockExcel(@Valid LockPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<LockDO> list = lockService.getLockPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "电子锁.xls", "数据", LockRespVO.class,
BeanUtils.toBean(list, LockRespVO.class));
}
}

105
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/LockGuideController.java

@ -0,0 +1,105 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.LockGuideDO;
import cn.iocoder.yudao.module.lock.service.LockGuideService;
import cn.iocoder.yudao.module.lock.vo.LockGuidePageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockGuideRespVO;
import cn.iocoder.yudao.module.lock.vo.LockGuideSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 隔离指导书")
@RestController
@RequestMapping("/guide/lock-guide")
@Validated
public class LockGuideController {
@Resource
private LockGuideService lockGuideService;
@PostMapping("/create")
@Operation(summary = "创建隔离指导书")
@PreAuthorize("@ss.hasPermission('guide:lock-guide:create')")
public CommonResult<Long> createLockGuide(@Valid @RequestBody LockGuideSaveReqVO createReqVO) {
return success(lockGuideService.createLockGuide(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新隔离指导书")
@PreAuthorize("@ss.hasPermission('guide:lock-guide:update')")
public CommonResult<Boolean> updateLockGuide(@Valid @RequestBody LockGuideSaveReqVO updateReqVO) {
lockGuideService.updateLockGuide(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除隔离指导书")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('guide:lock-guide:delete')")
public CommonResult<Boolean> deleteLockGuide(@RequestParam("id") Long id) {
lockGuideService.deleteLockGuide(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除隔离指导书")
@PreAuthorize("@ss.hasPermission('guide:lock-guide:delete')")
public CommonResult<Boolean> deleteLockGuideList(@RequestParam("ids") List<Long> ids) {
lockGuideService.deleteLockGuideListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得隔离指导书")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('guide:lock-guide:query')")
public CommonResult<LockGuideRespVO> getLockGuide(@RequestParam("id") Long id) {
LockGuideDO lockGuide = lockGuideService.getLockGuide(id);
return success(BeanUtils.toBean(lockGuide, LockGuideRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得隔离指导书分页")
@PreAuthorize("@ss.hasPermission('guide:lock-guide:query')")
public CommonResult<PageResult<LockGuideRespVO>> getLockGuidePage(@Valid LockGuidePageReqVO pageReqVO) {
PageResult<LockGuideDO> pageResult = lockGuideService.getLockGuidePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, LockGuideRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出隔离指导书 Excel")
@PreAuthorize("@ss.hasPermission('guide:lock-guide:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportLockGuideExcel(@Valid LockGuidePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<LockGuideDO> list = lockGuideService.getLockGuidePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "隔离指导书.xls", "数据", LockGuideRespVO.class,
BeanUtils.toBean(list, LockGuideRespVO.class));
}
}

109
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/LockWorkRecordController.java

@ -0,0 +1,109 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.LockWorkRecordDO;
import cn.iocoder.yudao.module.lock.service.LockWorkRecordService;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordPageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordRespVO;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 电子锁操作记录")
@RestController
@RequestMapping("/electron/lock-word-record")
@Validated
public class LockWorkRecordController {
@Resource
private LockWorkRecordService lockWorkRecordService;
@GetMapping("/page")
@Operation(summary = "获得电子锁操作记录分页")
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:query')")
public CommonResult<PageResult<LockWorkRecordRespVO>> getLockWorkRecordPage(@Valid LockWorkRecordPageReqVO pageReqVO) {
PageResult<LockWorkRecordDO> pageResult = lockWorkRecordService.getLockWorkRecordPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, LockWorkRecordRespVO.class));
}
@PostMapping("/create")
@Operation(summary = "创建电子锁操作记录")
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:create')")
public CommonResult<Long> createLockWorkRecord(@Valid @RequestBody LockWorkRecordSaveReqVO createReqVO) {
return success(lockWorkRecordService.createLockWorkRecord(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新电子锁操作记录")
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:update')")
public CommonResult<Boolean> updateLockWorkRecord(@Valid @RequestBody LockWorkRecordSaveReqVO updateReqVO) {
lockWorkRecordService.updateLockWorkRecord(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除电子锁操作记录")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:delete')")
public CommonResult<Boolean> deleteLockWorkRecord(@RequestParam("id") Long id) {
lockWorkRecordService.deleteLockWorkRecord(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除电子锁操作记录")
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:delete')")
public CommonResult<Boolean> deleteLockWorkRecordList(@RequestParam("ids") List<Long> ids) {
lockWorkRecordService.deleteLockWorkRecordListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得电子锁操作记录")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:query')")
public CommonResult<LockWorkRecordRespVO> getLockWorkRecord(@RequestParam("id") Long id) {
LockWorkRecordDO lockWorkRecord = lockWorkRecordService.getLockWorkRecord(id);
return success(BeanUtils.toBean(lockWorkRecord, LockWorkRecordRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出电子锁操作记录 Excel")
@PreAuthorize("@ss.hasPermission('electron:lock-word-record:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportLockWorkRecordExcel(@Valid LockWorkRecordPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<LockWorkRecordDO> list = lockWorkRecordService.getLockWorkRecordPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "电子锁操作记录.xls", "数据", LockWorkRecordRespVO.class,
BeanUtils.toBean(list, LockWorkRecordRespVO.class));
}
}

121
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanController.java

@ -0,0 +1,121 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.PlanDO;
import cn.iocoder.yudao.module.lock.dal.entity.PlanEntity;
import cn.iocoder.yudao.module.lock.service.PlanItemDetailService;
import cn.iocoder.yudao.module.lock.service.PlanItemService;
import cn.iocoder.yudao.module.lock.service.PlanLifeLockService;
import cn.iocoder.yudao.module.lock.service.PlanService;
import cn.iocoder.yudao.module.lock.vo.PlanPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanRespVO;
import cn.iocoder.yudao.module.lock.vo.PlanSaveReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanSelectVo;
import jakarta.annotation.security.PermitAll;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 隔离计划")
@RestController
@RequestMapping("/isolation/plan")
@Validated
public class PlanController {
@Resource
private PlanService planService;
@PostMapping("/create")
@Operation(summary = "创建隔离计划")
@PreAuthorize("@ss.hasPermission('isolation:plan:create')")
public CommonResult<Long> createPlan(@Valid @RequestBody PlanSaveReqVO createReqVO) {
return success(planService.createPlan(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新隔离计划")
@PreAuthorize("@ss.hasPermission('isolation:plan:update')")
public CommonResult<Boolean> updatePlan(@Valid @RequestBody PlanSaveReqVO updateReqVO) {
planService.updatePlan(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除隔离计划")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('isolation:plan:delete')")
public CommonResult<Boolean> deletePlan(@RequestParam("id") Long id) {
planService.deletePlan(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除隔离计划")
@PreAuthorize("@ss.hasPermission('isolation:plan:delete')")
public CommonResult<Boolean> deletePlanList(@RequestParam("ids") List<Long> ids) {
planService.deletePlanListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得隔离计划")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('isolation:plan:query')")
public CommonResult<PlanRespVO> getPlan(@RequestParam("id") Long id) {
PlanDO plan = planService.getPlan(id);
return success(BeanUtils.toBean(plan, PlanRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得隔离计划分页")
@PreAuthorize("@ss.hasPermission('isolation:plan:query')")
public CommonResult<PageResult<PlanRespVO>> getPlanPage(@Valid PlanPageReqVO pageReqVO) {
PageResult<PlanDO> pageResult = planService.getPlanPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PlanRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出隔离计划 Excel")
@PreAuthorize("@ss.hasPermission('isolation:plan:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPlanExcel(@Valid PlanPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PlanDO> list = planService.getPlanPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "隔离计划.xls", "数据", PlanRespVO.class,
BeanUtils.toBean(list, PlanRespVO.class));
}
@GetMapping("/planListAll")
@Operation(summary = "获得所有隔离计划")
@PermitAll
public CommonResult<List<PlanEntity>> getPlanListAll(@Valid PlanSelectVo pageReqVO) {
return success(planService.listAll(pageReqVO));
}
}

105
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanItemController.java

@ -0,0 +1,105 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.PlanItemDO;
import cn.iocoder.yudao.module.lock.service.PlanItemService;
import cn.iocoder.yudao.module.lock.vo.PlanItemPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemRespVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 隔离计划子项")
@RestController
@RequestMapping("/isolation/plan-item")
@Validated
public class PlanItemController {
@Resource
private PlanItemService planItemService;
@PostMapping("/create")
@Operation(summary = "创建隔离计划子项")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item:create')")
public CommonResult<Long> createPlanItem(@Valid @RequestBody PlanItemSaveReqVO createReqVO) {
return success(planItemService.createPlanItem(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新隔离计划子项")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item:update')")
public CommonResult<Boolean> updatePlanItem(@Valid @RequestBody PlanItemSaveReqVO updateReqVO) {
planItemService.updatePlanItem(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除隔离计划子项")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('isolation:plan-item:delete')")
public CommonResult<Boolean> deletePlanItem(@RequestParam("id") Long id) {
planItemService.deletePlanItem(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除隔离计划子项")
@PreAuthorize("@ss.hasPermission('isolation:plan-item:delete')")
public CommonResult<Boolean> deletePlanItemList(@RequestParam("ids") List<Long> ids) {
planItemService.deletePlanItemListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得隔离计划子项")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item:query')")
public CommonResult<PlanItemRespVO> getPlanItem(@RequestParam("id") Long id) {
PlanItemDO planItem = planItemService.getPlanItem(id);
return success(BeanUtils.toBean(planItem, PlanItemRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得隔离计划子项分页")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item:query')")
public CommonResult<PageResult<PlanItemRespVO>> getPlanItemPage(@Valid PlanItemPageReqVO pageReqVO) {
PageResult<PlanItemDO> pageResult = planItemService.getPlanItemPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PlanItemRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出隔离计划子项 Excel")
@PreAuthorize("@ss.hasPermission('isolation:plan-item:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPlanItemExcel(@Valid PlanItemPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PlanItemDO> list = planItemService.getPlanItemPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "隔离计划子项.xls", "数据", PlanItemRespVO.class,
BeanUtils.toBean(list, PlanItemRespVO.class));
}
}

108
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanItemDetailController.java

@ -0,0 +1,108 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.PlanItemDetailDO;
import cn.iocoder.yudao.module.lock.service.PlanItemDetailService;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailRespVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 隔离计划子项详情")
@RestController
@RequestMapping("/isolation/plan-item-detail")
@Validated
public class PlanItemDetailController {
@Resource
private PlanItemDetailService planItemDetailService;
@PostMapping("/create")
@Operation(summary = "创建隔离计划子项详情")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:create')")
public CommonResult<Long> createPlanItemDetail(@Valid @RequestBody PlanItemDetailSaveReqVO createReqVO) {
return success(planItemDetailService.createPlanItemDetail(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新隔离计划子项详情")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:update')")
public CommonResult<Boolean> updatePlanItemDetail(@Valid @RequestBody PlanItemDetailSaveReqVO updateReqVO) {
planItemDetailService.updatePlanItemDetail(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除隔离计划子项详情")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:delete')")
public CommonResult<Boolean> deletePlanItemDetail(@RequestParam("id") Long id) {
planItemDetailService.deletePlanItemDetail(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除隔离计划子项详情")
@PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:delete')")
public CommonResult<Boolean> deletePlanItemDetailList(@RequestParam("ids") List<Long> ids) {
planItemDetailService.deletePlanItemDetailListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得隔离计划子项详情")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
// @PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:query')")
public CommonResult<PlanItemDetailRespVO> getPlanItemDetail(@RequestParam("id") Long id) {
PlanItemDetailDO planItemDetail = planItemDetailService.getPlanItemDetail(id);
return success(BeanUtils.toBean(planItemDetail, PlanItemDetailRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得隔离计划子项详情分页")
//@PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:query')")
public CommonResult<PageResult<PlanItemDetailRespVO>> getPlanItemDetailPage(@Valid PlanItemDetailPageReqVO pageReqVO) {
PageResult<PlanItemDetailDO> pageResult = planItemDetailService.getPlanItemDetailPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PlanItemDetailRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出隔离计划子项详情 Excel")
@PreAuthorize("@ss.hasPermission('isolation:plan-item-detail:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPlanItemDetailExcel(@Valid PlanItemDetailPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PlanItemDetailDO> list = planItemDetailService.getPlanItemDetailPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "隔离计划子项详情.xls", "数据", PlanItemDetailRespVO.class,
BeanUtils.toBean(list, PlanItemDetailRespVO.class));
}
}

111
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PlanLifeLockController.java

@ -0,0 +1,111 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.PlanLifeLockDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.service.PlanLifeLockService;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockRespVO;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockSaveReqVO;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 个人生命锁")
@RestController
@RequestMapping("/isolation/plan-life-lock")
@Validated
public class PlanLifeLockController {
@Resource
private PlanLifeLockService planLifeLockService;
@PostMapping("/create")
@Operation(summary = "创建个人生命锁")
//@PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:create')")
public CommonResult<Long> createPlanLifeLock(@Valid @RequestBody PlanLifeLockSaveReqVO createReqVO) {
return success(planLifeLockService.createPlanLifeLock(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新个人生命锁")
//@PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:update')")
public CommonResult<Boolean> updatePlanLifeLock(@Valid @RequestBody PlanLifeLockSaveReqVO updateReqVO) {
planLifeLockService.updatePlanLifeLock(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除个人生命锁")
@Parameter(name = "id", description = "编号", required = true)
//@PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:delete')")
public CommonResult<Boolean> deletePlanLifeLock(@RequestParam("id") Long id) {
planLifeLockService.deletePlanLifeLock(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除个人生命锁")
@PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:delete')")
public CommonResult<Boolean> deletePlanLifeLockList(@RequestParam("ids") List<Long> ids) {
planLifeLockService.deletePlanLifeLockListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得个人生命锁")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
//@PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:query')")
public CommonResult<PlanLifeLockRespVO> getPlanLifeLock(@RequestParam("id") Long id) {
PlanLifeLockDO planLifeLock = planLifeLockService.getPlanLifeLock(id);
return success(BeanUtils.toBean(planLifeLock, PlanLifeLockRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得个人生命锁分页")
// @PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:query')")
public CommonResult<PageResult<PlanLifeLockRespVO>> getPlanLifeLockPage(@Valid PlanLifeLockPageReqVO pageReqVO) {
PageResult<PlanLifeLockDO> pageResult = planLifeLockService.getPlanLifeLockPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PlanLifeLockRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出个人生命锁 Excel")
@PreAuthorize("@ss.hasPermission('isolation:plan-life-lock:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPlanLifeLockExcel(@Valid PlanLifeLockPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PlanLifeLockDO> list = planLifeLockService.getPlanLifeLockPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "个人生命锁.xls", "数据", PlanLifeLockRespVO.class,
BeanUtils.toBean(list, PlanLifeLockRespVO.class));
}
}

183
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/admin/PointController.java

@ -0,0 +1,183 @@
package cn.iocoder.yudao.module.lock.controller.admin;
import cn.iocoder.yudao.module.lock.dal.PointDO;
import cn.iocoder.yudao.module.lock.dal.entity.LockEntity;
import cn.iocoder.yudao.module.lock.dal.entity.PlanEntity;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.service.PointService;
import cn.iocoder.yudao.module.lock.vo.LockStatusVo;
import cn.iocoder.yudao.module.lock.vo.PointPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PointRespVO;
import cn.iocoder.yudao.module.lock.vo.PointSaveReqVO;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.extractor.POITextExtractor;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.*;
import jakarta.servlet.http.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.*;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
import org.springframework.web.multipart.MultipartFile;
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.*;
@Tag(name = "管理后台 - 隔离点")
@RestController
@RequestMapping("/isolation/point")
@Validated
public class PointController {
@Resource
private PointService pointService;
@PostMapping("/create")
@Operation(summary = "创建隔离点")
@PreAuthorize("@ss.hasPermission('isolation:point:create')")
public CommonResult<Long> createPoint(@Valid @RequestBody PointSaveReqVO createReqVO) {
return success(pointService.createPoint(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新隔离点")
@PreAuthorize("@ss.hasPermission('isolation:point:update')")
public CommonResult<Boolean> updatePoint(@Valid @RequestBody PointSaveReqVO updateReqVO) {
pointService.updatePoint(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除隔离点")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('isolation:point:delete')")
public CommonResult<Boolean> deletePoint(@RequestParam("id") Long id) {
pointService.deletePoint(id);
return success(true);
}
@DeleteMapping("/delete-list")
@Parameter(name = "ids", description = "编号", required = true)
@Operation(summary = "批量删除隔离点")
@PreAuthorize("@ss.hasPermission('isolation:point:delete')")
public CommonResult<Boolean> deletePointList(@RequestParam("ids") List<Long> ids) {
pointService.deletePointListByIds(ids);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得隔离点")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('isolation:point:query')")
public CommonResult<PointRespVO> getPoint(@RequestParam("id") Long id) {
PointDO point = pointService.getPoint(id);
return success(BeanUtils.toBean(point, PointRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得隔离点分页")
@PreAuthorize("@ss.hasPermission('isolation:point:query')")
public CommonResult<PageResult<PointRespVO>> getPointPage(@Valid PointPageReqVO pageReqVO) {
PageResult<PointDO> pageResult = pointService.getPointPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, PointRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出隔离点 Excel")
@PreAuthorize("@ss.hasPermission('isolation:point:export')")
@ApiAccessLog(operateType = EXPORT)
public void exportPointExcel(@Valid PointPageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<PointDO> list = pointService.getPointPage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "隔离点.xls", "数据", PointRespVO.class,
BeanUtils.toBean(list, PointRespVO.class));
}
@GetMapping("/getListAll")
@Operation(summary = "获取全部")
public CommonResult<LockEntity> getListAll() {
return success(pointService.getListAll());
}
@PutMapping("/bindlock")
@Operation(summary = "修改锁状态")
public CommonResult<Boolean> bindlock(@RequestBody LockStatusVo updateReqVO) {
pointService.bindlock(updateReqVO);
return success(true);
}
@PutMapping("/createLock")
@Operation(summary = "上锁")
public CommonResult<Boolean> createLock(@RequestBody LockStatusVo updateReqVO) {
pointService.createLock(updateReqVO);
return success(true);
}
@PutMapping("/verifyLock")
@Operation(summary = "验证")
public CommonResult<Boolean> verifyLock(@RequestBody LockStatusVo updateReqVO) {
pointService.verifyLock(updateReqVO);
return success(true);
}
@PutMapping("/verifyUnLock")
@Operation(summary = "验证解锁")
public CommonResult<Boolean> verifyUnLock(@RequestBody LockStatusVo updateReqVO) {
pointService.verifyUnLock(updateReqVO);
return success(true);
}
@PutMapping("/unLock")
@Operation(summary = "解锁")
public CommonResult<Boolean> unLock(@RequestBody LockStatusVo updateReqVO) {
pointService.unLock(updateReqVO);
return success(true);
}
@PostMapping(value = "/import", consumes = "multipart/form-data")
@Operation(summary = "从 Word 文件导入隔离点")
public CommonResult<Boolean> importPointsFromWord(@Valid @RequestPart("file") MultipartFile file) {
if (Objects.isNull(file) || file.isEmpty()) {
throw exception(ErrorCodeConstants.IMPORT_ERROR);
}
String contentType = file.getContentType();
if (!"application/vnd.openxmlformats-officedocument.wordprocessingml.document".equals(contentType) &&
!"application/msword".equals(contentType)) {
throw exception(ErrorCodeConstants.IMPORT_FILE_ERROR);
}
pointService.importPointsFromWord(file);
return success(true);
}
}

4
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/controller/package-info.java

@ -0,0 +1,4 @@
/**
* infra 模块的 web 配置
*/
package cn.iocoder.yudao.module.lock.controller;

40
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/IsolationPointDO.java

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 指导书与隔离点关联 DO
*
* @author 超级管理员
*/
@TableName("guide_isolation_point")
@KeySequence("guide_isolation_point_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IsolationPointDO extends BaseDO {
/**
* id
*/
@TableId
private Long id;
/**
* 隔离指导书ID
*/
private Long guideId;
/**
* 隔离点ID
*/
private Long isolationPointId;
}

61
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/LockDO.java

@ -0,0 +1,61 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 电子锁 DO
*
* @author 超级管理员
*/
@TableName("electron_lock")
@KeySequence("electron_lock_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LockDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 编号
*/
private String lockNumber;
/**
* 名称
*/
private String lockName;
/**
* 状态
*/
private Integer lockStatus;
/**
* 锁具类型
*/
private Integer lockType;
/**
* 启用状态: 0=未启用, 1=已启用
*/
private Integer lockEnableStatus;
/**
* 上次充电时间
*/
private LocalDateTime lockLastChargeTime;
/**
* 蓝牙ID
*/
private String lockBluetoothId;
}

66
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/LockGuideDO.java

@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.lock.dal;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 隔离指导书 DO
*
* @author 超级管理员
*/
@TableName("guide")
@KeySequence("guide_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LockGuideDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 工作内容和范围
*/
private String guideContent;
/**
* 隔离指导书名称
*/
private String name;
/**
* 隔离计划编号
*/
private String code;
/**
* 集中挂牌人ID
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Long operatorId;
/**
* 集中挂牌协助人ID
*/
private Long operatorHelperId;
/**
* 验证人ID
*/
private Long verifierId;
/**
* 验证协助人ID
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Long verifierHelperId;
}

64
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/LockWorkRecordDO.java

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 电子锁操作记录 DO
*
* @author 超级管理员
*/
@TableName("electron_lock_work_record")
@KeySequence("electron_lock_work_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LockWorkRecordDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 操作人ID
*/
private Long operatorId;
/**
* 电子锁ID
*/
private Long lockId;
/**
* 关联的子项详情ID (某些操作可能不关联)
*/
private Long isolationPlanItemDetailId;
/**
* 记录类型
*/
private String recordType;
/**
* 操作签名 (图片路径)
*/
private String signaturePath;
/**
* 操作前照片 (图片路径)
*/
private String beforePhotoPath;
/**
* 操作后照片 (图片路径)
*/
private String afterPhotoPath;
/**
* 操作GPS坐标
*/
private String gpsCoordinates;
}

41
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanDO.java

@ -0,0 +1,41 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 隔离计划 DO
*
* @author 超级管理员
*/
@TableName("isolation_plan")
@KeySequence("isolation_plan_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PlanDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 计划名称
*/
private String ipName;
/**
* 计划状态
*/
private Integer status;
}

62
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanItemDO.java

@ -0,0 +1,62 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 隔离计划子项 DO
*
* @author 超级管理员
*/
@TableName("isolation_plan_item")
@KeySequence("isolation_plan_item_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PlanItemDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 隔离计划ID
*/
private Long isolationPlanId;
/**
* 隔离指导书ID
*/
private Long guideId;
/**
* 集中挂牌人ID
*/
private Long operatorId;
/**
* 集中挂牌协助人ID
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Long operatorHelperId;
/**
* 验证人ID
*/
private Long verifierId;
/**
* 验证协助人ID
*/
@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Long verifierHelperId;
/**
* 子项状态: 0=未完成, 1=已完成
*/
private Integer status;
}

50
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanItemDetailDO.java

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 隔离计划子项详情 DO
*
* @author 超级管理员
*/
@TableName("isolation_plan_item_detail")
@KeySequence("isolation_plan_item_detail_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PlanItemDetailDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 隔离计划子项ID
*/
private Long isolationPlanItemId;
/**
* 隔离点ID
*/
private Long isolationPointId;
/**
* 电子锁ID
*/
private Long lockId;
/**
* 锁箱状态: 0=未上锁, 1=已上锁, 2=已解锁
*/
private Integer lockStatus;
private Long operateRecordId;
private Long verifyRecordId;
}

58
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PlanLifeLockDO.java

@ -0,0 +1,58 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 个人生命锁 DO
*
* @author 超级管理员
*/
@TableName("isolation_plan_life_lock")
@KeySequence("isolation_plan_life_lock_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PlanLifeLockDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 子项详情ID
*/
private Long isolationPlanItemDetailId;
/**
* 上锁人ID
*/
private Long userId;
/**
* 生命锁类型
*/
private Integer lockType;
/**
* 锁定状态: 0=未上锁, 1=已上锁
*/
private Integer lockStatus;
/**
* 上锁时间
*/
private LocalDateTime lockTime;
/**
* 解锁时间
*/
private LocalDateTime unlockTime;
}

57
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/PointDO.java

@ -0,0 +1,57 @@
package cn.iocoder.yudao.module.lock.dal;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* 隔离点 DO
*
* @author 超级管理员
*/
@TableName("isolation_point")
@KeySequence("isolation_point_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PointDO extends BaseDO {
/**
* 主键ID
*/
@TableId
private Long id;
/**
* 隔离点类型
*/
private String ipType;
/**
* 隔离点名称
*/
private String ipName;
/**
* 隔离点位置
*/
private String ipLocation;
/**
* 隔离点编号
*/
private String ipNumber;
/**
* 隔离点状态
*/
private Integer status;
/**
* 所需设备锁数量
*/
private Integer guideLockNums;
}

27
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/LockEntity.java

@ -0,0 +1,27 @@
package cn.iocoder.yudao.module.lock.dal.entity;
import cn.iocoder.yudao.module.lock.dal.*;
import lombok.Data;
import java.util.List;
@Data
public class LockEntity {
private List<IsolationPointDO> isolationPointList;
private List<LockDO> lockList;
private List<LockGuideDO> lockGuideList;
private List<PlanDO> planList;
private List<PlanItemDetailDO> planItemDetailList;
private List<PlanItemDO> planItemList;
private List<PlanLifeLockDO> planLifeLockList;
private List<PointDO> pointList;
}

25
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanEntity.java

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.lock.dal.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.List;
@Data
public class PlanEntity {
@TableId
private Long id;
/**
* 计划名称
*/
private String ipName;
/**
* 计划状态
*/
private Integer status;
private List<PlanItemEntity> planItemEntityList;
}

40
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanItemDetailEntity.java

@ -0,0 +1,40 @@
package cn.iocoder.yudao.module.lock.dal.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.util.List;
/**
* 隔离计划子项详情 DO
*
* @author 超级管理员
*/
@Data
public class PlanItemDetailEntity {
@TableId
private Long id;
/**
* 隔离计划子项ID
*/
private Long isolationPlanItemId;
/**
* 隔离点ID
*/
private Long isolationPointId;
private Long operateRecordId;
private Long verifyRecordId;
/**
* 电子锁ID
*/
private Long lockId;
/**
* 锁状态: 0=未上锁, 1=已上锁, 2=已解锁
*/
private Integer lockStatus;
private List<PlanLifeLockEntity> lockEntities;
}

52
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanItemEntity.java

@ -0,0 +1,52 @@
package cn.iocoder.yudao.module.lock.dal.entity;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.util.List;
/**
* 隔离计划子项 DO
*
* @author 超级管理员
*/
@Data
public class PlanItemEntity {
@TableId
private Long id;
/**
* 隔离计划ID
*/
private Long isolationPlanId;
/**
* 隔离指导书ID
*/
private Long guideId;
/**
* 集中挂牌人ID
*/
private Long operatorId;
/**
* 集中挂牌协助人ID
*/
private Long operatorHelperId;
/**
* 验证人ID
*/
private Long verifierId;
/**
* 验证协助人ID
*/
private Long verifierHelperId;
/**
* 子项状态: 0=未完成, 1=已完成
*/
private Integer status;
private List<PlanItemDetailEntity> planItemDetailEntityList;
}

48
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/dal/entity/PlanLifeLockEntity.java

@ -0,0 +1,48 @@
package cn.iocoder.yudao.module.lock.dal.entity;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.time.LocalDateTime;
/**
* 个人生命锁 DO
*
* @author 超级管理员
*/
@Data
public class PlanLifeLockEntity {
@TableId
private Long id;
/**
* 子项详情ID
*/
private Long isolationPlanItemDetailId;
/**
* 上锁人ID
*/
private Long userId;
/**
* 生命锁类型
*/
private Integer lockType;
/**
* 锁定状态: 0=未上锁, 1=已上锁
*/
private Integer lockStatus;
/**
* 上锁时间
*/
private LocalDateTime lockTime;
/**
* 解锁时间
*/
private LocalDateTime unlockTime;
}

44
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/enums/ErrorCodeConstants.java

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.lock.enums;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
public interface ErrorCodeConstants {
ErrorCode LOCK_NOT_EXISTS = new ErrorCode(1_005_000_001, "电子锁不存在");
ErrorCode LOCK_WORD_RECORD_NOT_EXISTS = new ErrorCode(1_005_000_002, "电子锁操作记录不存在");
ErrorCode ISOLATION_POINT_NOT_EXISTS = new ErrorCode(1_005_000_003, "指导书与隔离点关联不存在");
ErrorCode PLAN_NOT_EXISTS = new ErrorCode(1_005_000_004, "隔离计划不存在");
ErrorCode PLAN_ITEM_NOT_EXISTS = new ErrorCode(1_005_000_005, "隔离计划子项不存在");
ErrorCode LOCK_GUIDE_NOT_EXISTS = new ErrorCode(1_005_000_006, "隔离指导书不存在");
ErrorCode PLAN_ITEM_DETAIL_NOT_EXISTS = new ErrorCode(1_005_000_007, "隔离计划子项详情不存在");
ErrorCode PLAN_LIFE_LOCK_NOT_EXISTS = new ErrorCode(1_005_000_008, "个人生命锁不存在");
ErrorCode POINT_NOT_EXISTS = new ErrorCode(1_005_000_009, "隔离点不存在");
ErrorCode POINT_NUMBER_EXISTS = new ErrorCode(1_005_000_009, "隔离点编号已经存在");
ErrorCode CENTRALIZED_LISTING_LOCK_NOT_EXISTS = new ErrorCode(1_005_000_010, "请先创建集中挂牌人锁");
ErrorCode CENTRALIZED_LISTING_LOCK_EXISTS = new ErrorCode(1_005_000_010, "请勿重复创建挂牌人锁");
ErrorCode ISOLATION_POINT_EXISTS = new ErrorCode(1_005_000_011, "指导书与隔离点关联已经存在");
ErrorCode PLAN_LIFE_LOCK_EXISTS = new ErrorCode(1_005_000_001, "需要等受影响人锁全部解开才能开锁");
ErrorCode LOCK_STATUS_ERROR = new ErrorCode(1_005_000_001, "已经上锁无法重复上锁");
ErrorCode DETAIL_UNLOCK_STATUS_ERROR = new ErrorCode(1_005_000_001, "该锁已经解锁");
ErrorCode DETAIL_LOCK_STATUS_ERROR = new ErrorCode(1_005_000_001, "该锁已经验证");
ErrorCode DETAIL_LOCK_VERITY_ERROR = new ErrorCode(1_005_000_001, "该锁未验证");
ErrorCode PLAN_ITEM_DETAIL_LOCK_STATUS_ERROR = new ErrorCode(1_005_000_001, "无法重复上锁");
ErrorCode IMPORT_ERROR = new ErrorCode(1_005_000_001, "上传的 Word 文件不能为空");
ErrorCode IMPORT_FILE_ERROR = new ErrorCode(1_005_000_001, "仅支持 Word 文件(.doc 或 .docx");
}

6
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/framework/package-info.java

@ -0,0 +1,6 @@
/**
* 属于 report 模块的 framework 封装
*
* @author 芋道源码
*/
package cn.iocoder.yudao.module.lock.framework;

24
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/framework/web/config/LockWebConfiguration.java

@ -0,0 +1,24 @@
package cn.iocoder.yudao.module.lock.framework.web.config;
import cn.iocoder.yudao.framework.swagger.config.YudaoSwaggerAutoConfiguration;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* infra 模块的 web 组件的 Configuration
*
* @author 芋道源码
*/
@Configuration(proxyBeanMethods = false)
public class LockWebConfiguration {
/**
*
*/
@Bean
public GroupedOpenApi lockGroupedOpenApi() {
return YudaoSwaggerAutoConfiguration.buildGroupedOpenApi("lock");
}
}

4
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/framework/web/package-info.java

@ -0,0 +1,4 @@
/**
* infra 模块的 web 配置
*/
package cn.iocoder.yudao.module.lock.framework.web;

26
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/IsolationPointMapper.java

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.IsolationPointDO;
import cn.iocoder.yudao.module.lock.vo.IsolationPointPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
/**
* 指导书与隔离点关联 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface IsolationPointMapper extends BaseMapperX<IsolationPointDO> {
default PageResult<IsolationPointDO> selectPage(IsolationPointPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<IsolationPointDO>()
.eqIfPresent(IsolationPointDO::getGuideId, reqVO.getGuideId())
.eqIfPresent(IsolationPointDO::getIsolationPointId, reqVO.getIsolationPointId())
.betweenIfPresent(IsolationPointDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(IsolationPointDO::getId));
}
}

25
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/LockGuideMapper.java

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.LockGuideDO;
import cn.iocoder.yudao.module.lock.vo.LockGuidePageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
/**
* 隔离指导书 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface LockGuideMapper extends BaseMapperX<LockGuideDO> {
default PageResult<LockGuideDO> selectPage(LockGuidePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<LockGuideDO>()
.eqIfPresent(LockGuideDO::getGuideContent, reqVO.getGuideContent())
.betweenIfPresent(LockGuideDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(LockGuideDO::getId));
}
}

37
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/LockMapper.java

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.LockDO;
import cn.iocoder.yudao.module.lock.vo.LockPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* 电子锁 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface LockMapper extends BaseMapperX<LockDO> {
default PageResult<LockDO> selectPage(LockPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<LockDO>()
.eqIfPresent(LockDO::getLockNumber, reqVO.getLockNumber())
.likeIfPresent(LockDO::getLockName, reqVO.getLockName())
.eqIfPresent(LockDO::getLockStatus, reqVO.getLockStatus())
.eqIfPresent(LockDO::getLockType, reqVO.getLockType())
.eqIfPresent(LockDO::getLockEnableStatus, reqVO.getLockEnableStatus())
.betweenIfPresent(LockDO::getLockLastChargeTime, reqVO.getLockLastChargeTime())
.eqIfPresent(LockDO::getLockBluetoothId, reqVO.getLockBluetoothId())
.betweenIfPresent(LockDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(LockDO::getId));
}
void updateStatus(@Param("id") Long id,@Param("status")Integer status);
}

32
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/LockWorkRecordMapper.java

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.LockWorkRecordDO;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
/**
* 电子锁操作记录 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface LockWorkRecordMapper extends BaseMapperX<LockWorkRecordDO> {
default PageResult<LockWorkRecordDO> selectPage(LockWorkRecordPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<LockWorkRecordDO>()
.eqIfPresent(LockWorkRecordDO::getOperatorId, reqVO.getOperatorId())
.eqIfPresent(LockWorkRecordDO::getLockId, reqVO.getLockId())
.eqIfPresent(LockWorkRecordDO::getIsolationPlanItemDetailId, reqVO.getIsolationPlanItemDetailId())
.eqIfPresent(LockWorkRecordDO::getRecordType, reqVO.getRecordType())
.eqIfPresent(LockWorkRecordDO::getSignaturePath, reqVO.getSignaturePath())
.eqIfPresent(LockWorkRecordDO::getBeforePhotoPath, reqVO.getBeforePhotoPath())
.eqIfPresent(LockWorkRecordDO::getAfterPhotoPath, reqVO.getAfterPhotoPath())
.eqIfPresent(LockWorkRecordDO::getGpsCoordinates, reqVO.getGpsCoordinates())
.betweenIfPresent(LockWorkRecordDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(LockWorkRecordDO::getId));
}
}

31
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanItemDetailMapper.java

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.PlanItemDetailDO;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Update;
/**
* 隔离计划子项详情 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface PlanItemDetailMapper extends BaseMapperX<PlanItemDetailDO> {
default PageResult<PlanItemDetailDO> selectPage(PlanItemDetailPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PlanItemDetailDO>()
.eqIfPresent(PlanItemDetailDO::getIsolationPlanItemId, reqVO.getIsolationPlanItemId())
.eqIfPresent(PlanItemDetailDO::getIsolationPointId, reqVO.getIsolationPointId())
.eqIfPresent(PlanItemDetailDO::getLockId, reqVO.getLockId())
.eqIfPresent(PlanItemDetailDO::getLockStatus, reqVO.getLockStatus())
.betweenIfPresent(PlanItemDetailDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PlanItemDetailDO::getId));
}
void updateDetailLockStatus(Integer status,Long planItemDetailId, Long lockId,Long operateRecordId,Long verifyRecordId);
}

32
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanItemMapper.java

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.PlanItemDO;
import cn.iocoder.yudao.module.lock.vo.PlanItemPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
/**
* 隔离计划子项 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface PlanItemMapper extends BaseMapperX<PlanItemDO> {
default PageResult<PlanItemDO> selectPage(PlanItemPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PlanItemDO>()
.eqIfPresent(PlanItemDO::getIsolationPlanId, reqVO.getIsolationPlanId())
.eqIfPresent(PlanItemDO::getGuideId, reqVO.getGuideId())
.eqIfPresent(PlanItemDO::getOperatorId, reqVO.getOperatorId())
.eqIfPresent(PlanItemDO::getOperatorHelperId, reqVO.getOperatorHelperId())
.eqIfPresent(PlanItemDO::getVerifierId, reqVO.getVerifierId())
.eqIfPresent(PlanItemDO::getVerifierHelperId, reqVO.getVerifierHelperId())
.eqIfPresent(PlanItemDO::getStatus, reqVO.getStatus())
.betweenIfPresent(PlanItemDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PlanItemDO::getId));
}
void updateStatus(Long isolationPlanItemId, Integer status);
}

33
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanLifeLockMapper.java

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.PlanLifeLockDO;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
import java.util.Date;
/**
* 个人生命锁 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface PlanLifeLockMapper extends BaseMapperX<PlanLifeLockDO> {
default PageResult<PlanLifeLockDO> selectPage(PlanLifeLockPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PlanLifeLockDO>()
.eqIfPresent(PlanLifeLockDO::getIsolationPlanItemDetailId, reqVO.getIsolationPlanItemDetailId())
.eqIfPresent(PlanLifeLockDO::getUserId, reqVO.getUserId())
.eqIfPresent(PlanLifeLockDO::getLockType, reqVO.getLockType())
.eqIfPresent(PlanLifeLockDO::getLockStatus, reqVO.getLockStatus())
.betweenIfPresent(PlanLifeLockDO::getLockTime, reqVO.getLockTime())
.betweenIfPresent(PlanLifeLockDO::getUnlockTime, reqVO.getUnlockTime())
.betweenIfPresent(PlanLifeLockDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PlanLifeLockDO::getId));
}
void updateStatus(Long id, Integer status, Date unlockTime);
}

26
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PlanMapper.java

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.PlanDO;
import cn.iocoder.yudao.module.lock.vo.PlanPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
/**
* 隔离计划 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface PlanMapper extends BaseMapperX<PlanDO> {
default PageResult<PlanDO> selectPage(PlanPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PlanDO>()
.likeIfPresent(PlanDO::getIpName, reqVO.getIpName())
.betweenIfPresent(PlanDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PlanDO::getId));
}
void updateStatus(Long planId, Integer status);
}

32
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/mapper/PointMapper.java

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.lock.mapper;
import cn.iocoder.yudao.module.lock.dal.PointDO;
import cn.iocoder.yudao.module.lock.vo.PointPageReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;
import java.util.List;
/**
* 隔离点 Mapper
*
* @author 超级管理员
*/
@Mapper
public interface PointMapper extends BaseMapperX<PointDO> {
default PageResult<PointDO> selectPage(PointPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<PointDO>()
.likeIfPresent(PointDO::getIpName, reqVO.getIpName())
.eqIfPresent(PointDO::getIpLocation, reqVO.getIpLocation())
.eqIfPresent(PointDO::getIpNumber, reqVO.getIpNumber())
.betweenIfPresent(PointDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(PointDO::getId));
}
void updateStatusBatch(@Param("idList") List<Long> idList, @Param("status") Integer status);
}

12
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/package-info.java

@ -0,0 +1,12 @@
/**
* bpm 包下业务流程管理Business Process Management我们放工作流的功能基于 Flowable 6 版本实现
* 例如说流程定义表单配置审核中心我的申请我的待办我的已办等等
*
* bpm 解释https://baike.baidu.com/item/BPM/1933
*
* 1. Controller URL /bpm/ 开头避免和其它 Module 冲突
* 2. DataObject 表名 bpm_ 开头方便在数据库中区分
*
* 注意由于 Bpm 模块下容易和其它模块重名所以类名都加载 Bpm 的前缀~
*/
package cn.iocoder.yudao.module.lock;

64
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/IsolationPointService.java

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.IsolationPointDO;
import cn.iocoder.yudao.module.lock.vo.IsolationPointPageReqVO;
import cn.iocoder.yudao.module.lock.vo.IsolationPointSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 指导书与隔离点关联 Service 接口
*
* @author 超级管理员
*/
public interface IsolationPointService {
/**
* 创建指导书与隔离点关联
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createIsolationPoint(@Valid IsolationPointSaveReqVO createReqVO);
/**
* 更新指导书与隔离点关联
*
* @param updateReqVO 更新信息
*/
void updateIsolationPoint(@Valid IsolationPointSaveReqVO updateReqVO);
/**
* 删除指导书与隔离点关联
*
* @param id 编号
*/
void deleteIsolationPoint(Long id);
/**
* 批量删除指导书与隔离点关联
*
* @param ids 编号
*/
void deleteIsolationPointListByIds(List<Long> ids);
/**
* 获得指导书与隔离点关联
*
* @param id 编号
* @return 指导书与隔离点关联
*/
IsolationPointDO getIsolationPoint(Long id);
/**
* 获得指导书与隔离点关联分页
*
* @param pageReqVO 分页查询
* @return 指导书与隔离点关联分页
*/
PageResult<IsolationPointDO> getIsolationPointPage(IsolationPointPageReqVO pageReqVO);
}

63
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/LockGuideService.java

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.LockGuideDO;
import cn.iocoder.yudao.module.lock.vo.LockGuidePageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockGuideSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 隔离指导书 Service 接口
*
* @author 超级管理员
*/
public interface LockGuideService {
/**
* 创建隔离指导书
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createLockGuide(@Valid LockGuideSaveReqVO createReqVO);
/**
* 更新隔离指导书
*
* @param updateReqVO 更新信息
*/
void updateLockGuide(@Valid LockGuideSaveReqVO updateReqVO);
/**
* 删除隔离指导书
*
* @param id 编号
*/
void deleteLockGuide(Long id);
/**
* 批量删除隔离指导书
*
* @param ids 编号
*/
void deleteLockGuideListByIds(List<Long> ids);
/**
* 获得隔离指导书
*
* @param id 编号
* @return 隔离指导书
*/
LockGuideDO getLockGuide(Long id);
/**
* 获得隔离指导书分页
*
* @param pageReqVO 分页查询
* @return 隔离指导书分页
*/
PageResult<LockGuideDO> getLockGuidePage(LockGuidePageReqVO pageReqVO);
}

65
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/LockService.java

@ -0,0 +1,65 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.LockDO;
import cn.iocoder.yudao.module.lock.vo.LockPageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 电子锁 Service 接口
*
* @author 超级管理员
*/
public interface LockService {
/**
* 创建电子锁
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createLock(@Valid LockSaveReqVO createReqVO);
/**
* 更新电子锁
*
* @param updateReqVO 更新信息
*/
void updateLock(@Valid LockSaveReqVO updateReqVO);
/**
* 删除电子锁
*
* @param id 编号
*/
void deleteLock(Long id);
/**
* 批量删除电子锁
*
* @param ids 编号
*/
void deleteLockListByIds(List<Long> ids);
/**
* 获得电子锁
*
* @param id 编号
* @return 电子锁
*/
LockDO getLock(Long id);
/**
* 获得电子锁分页
*
* @param pageReqVO 分页查询
* @return 电子锁分页
*/
PageResult<LockDO> getLockPage(LockPageReqVO pageReqVO);
}

63
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/LockWorkRecordService.java

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.LockWorkRecordDO;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordPageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 电子锁操作记录 Service 接口
*
* @author 超级管理员
*/
public interface LockWorkRecordService {
/**
* 创建电子锁操作记录
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createLockWorkRecord(@Valid LockWorkRecordSaveReqVO createReqVO);
/**
* 更新电子锁操作记录
*
* @param updateReqVO 更新信息
*/
void updateLockWorkRecord(@Valid LockWorkRecordSaveReqVO updateReqVO);
/**
* 删除电子锁操作记录
*
* @param id 编号
*/
void deleteLockWorkRecord(Long id);
/**
* 批量删除电子锁操作记录
*
* @param ids 编号
*/
void deleteLockWorkRecordListByIds(List<Long> ids);
/**
* 获得电子锁操作记录
*
* @param id 编号
* @return 电子锁操作记录
*/
LockWorkRecordDO getLockWorkRecord(Long id);
/**
* 获得电子锁操作记录分页
*
* @param pageReqVO 分页查询
* @return 电子锁操作记录分页
*/
PageResult<LockWorkRecordDO> getLockWorkRecordPage(LockWorkRecordPageReqVO pageReqVO);
}

64
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanItemDetailService.java

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.PlanItemDetailDO;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 隔离计划子项详情 Service 接口
*
* @author 超级管理员
*/
public interface PlanItemDetailService {
/**
* 创建隔离计划子项详情
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPlanItemDetail(@Valid PlanItemDetailSaveReqVO createReqVO);
/**
* 更新隔离计划子项详情
*
* @param updateReqVO 更新信息
*/
void updatePlanItemDetail(@Valid PlanItemDetailSaveReqVO updateReqVO);
/**
* 删除隔离计划子项详情
*
* @param id 编号
*/
void deletePlanItemDetail(Long id);
/**
* 批量删除隔离计划子项详情
*
* @param ids 编号
*/
void deletePlanItemDetailListByIds(List<Long> ids);
/**
* 获得隔离计划子项详情
*
* @param id 编号
* @return 隔离计划子项详情
*/
PlanItemDetailDO getPlanItemDetail(Long id);
/**
* 获得隔离计划子项详情分页
*
* @param pageReqVO 分页查询
* @return 隔离计划子项详情分页
*/
PageResult<PlanItemDetailDO> getPlanItemDetailPage(PlanItemDetailPageReqVO pageReqVO);
}

63
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanItemService.java

@ -0,0 +1,63 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.PlanItemDO;
import cn.iocoder.yudao.module.lock.vo.PlanItemPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 隔离计划子项 Service 接口
*
* @author 超级管理员
*/
public interface PlanItemService {
/**
* 创建隔离计划子项
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPlanItem(@Valid PlanItemSaveReqVO createReqVO);
/**
* 更新隔离计划子项
*
* @param updateReqVO 更新信息
*/
void updatePlanItem(@Valid PlanItemSaveReqVO updateReqVO);
/**
* 删除隔离计划子项
*
* @param id 编号
*/
void deletePlanItem(Long id);
/**
* 批量删除隔离计划子项
*
* @param ids 编号
*/
void deletePlanItemListByIds(List<Long> ids);
/**
* 获得隔离计划子项
*
* @param id 编号
* @return 隔离计划子项
*/
PlanItemDO getPlanItem(Long id);
/**
* 获得隔离计划子项分页
*
* @param pageReqVO 分页查询
* @return 隔离计划子项分页
*/
PageResult<PlanItemDO> getPlanItemPage(PlanItemPageReqVO pageReqVO);
}

64
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanLifeLockService.java

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.PlanLifeLockDO;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 个人生命锁 Service 接口
*
* @author 超级管理员
*/
public interface PlanLifeLockService {
/**
* 创建个人生命锁
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPlanLifeLock(@Valid PlanLifeLockSaveReqVO createReqVO);
/**
* 更新个人生命锁
*
* @param updateReqVO 更新信息
*/
void updatePlanLifeLock(@Valid PlanLifeLockSaveReqVO updateReqVO);
/**
* 删除个人生命锁
*
* @param id 编号
*/
void deletePlanLifeLock(Long id);
/**
* 批量删除个人生命锁
*
* @param ids 编号
*/
void deletePlanLifeLockListByIds(List<Long> ids);
/**
* 获得个人生命锁
*
* @param id 编号
* @return 个人生命锁
*/
PlanLifeLockDO getPlanLifeLock(Long id);
/**
* 获得个人生命锁分页
*
* @param pageReqVO 分页查询
* @return 个人生命锁分页
*/
PageResult<PlanLifeLockDO> getPlanLifeLockPage(PlanLifeLockPageReqVO pageReqVO);
List<PlanLifeLockDO> getListAll(Long isolationPlanItemDetailId);
}

66
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PlanService.java

@ -0,0 +1,66 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.PlanDO;
import cn.iocoder.yudao.module.lock.dal.entity.PlanEntity;
import cn.iocoder.yudao.module.lock.vo.PlanPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanSaveReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanSelectVo;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
/**
* 隔离计划 Service 接口
*
* @author 超级管理员
*/
public interface PlanService {
/**
* 创建隔离计划
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPlan(@Valid PlanSaveReqVO createReqVO);
/**
* 更新隔离计划
*
* @param updateReqVO 更新信息
*/
void updatePlan(@Valid PlanSaveReqVO updateReqVO);
/**
* 删除隔离计划
*
* @param id 编号
*/
void deletePlan(Long id);
/**
* 批量删除隔离计划
*
* @param ids 编号
*/
void deletePlanListByIds(List<Long> ids);
/**
* 获得隔离计划
*
* @param id 编号
* @return 隔离计划
*/
PlanDO getPlan(Long id);
/**
* 获得隔离计划分页
*
* @param pageReqVO 分页查询
* @return 隔离计划分页
*/
PageResult<PlanDO> getPlanPage(PlanPageReqVO pageReqVO);
List<PlanEntity> listAll(PlanSelectVo pageReqVO);
}

82
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/PointService.java

@ -0,0 +1,82 @@
package cn.iocoder.yudao.module.lock.service;
import java.util.*;
import cn.iocoder.yudao.module.lock.dal.PointDO;
import cn.iocoder.yudao.module.lock.dal.entity.LockEntity;
import cn.iocoder.yudao.module.lock.dal.entity.PlanEntity;
import cn.iocoder.yudao.module.lock.vo.LockStatusVo;
import cn.iocoder.yudao.module.lock.vo.PointPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PointSaveReqVO;
import jakarta.validation.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.springframework.web.multipart.MultipartFile;
/**
* 隔离点 Service 接口
*
* @author 超级管理员
*/
public interface PointService {
/**
* 创建隔离点
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createPoint(@Valid PointSaveReqVO createReqVO);
/**
* 更新隔离点
*
* @param updateReqVO 更新信息
*/
void updatePoint(@Valid PointSaveReqVO updateReqVO);
/**
* 删除隔离点
*
* @param id 编号
*/
void deletePoint(Long id);
/**
* 批量删除隔离点
*
* @param ids 编号
*/
void deletePointListByIds(List<Long> ids);
/**
* 获得隔离点
*
* @param id 编号
* @return 隔离点
*/
PointDO getPoint(Long id);
/**
* 获得隔离点分页
*
* @param pageReqVO 分页查询
* @return 隔离点分页
*/
PageResult<PointDO> getPointPage(PointPageReqVO pageReqVO);
LockEntity getListAll();
void bindlock(LockStatusVo updateReqVO);
void createLock(LockStatusVo updateReqVO);
void verifyLock(LockStatusVo updateReqVO);
void verifyUnLock(LockStatusVo updateReqVO);
void unLock(LockStatusVo updateReqVO);
void importPointsFromWord(MultipartFile file);
}

102
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/IsolationPointServiceImpl.java

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.IsolationPointDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.IsolationPointMapper;
import cn.iocoder.yudao.module.lock.service.IsolationPointService;
import cn.iocoder.yudao.module.lock.vo.IsolationPointPageReqVO;
import cn.iocoder.yudao.module.lock.vo.IsolationPointSaveReqVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 指导书与隔离点关联 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class IsolationPointServiceImpl implements IsolationPointService {
@Resource
private IsolationPointMapper isolationPointMapper;
@Override
public Long createIsolationPoint(IsolationPointSaveReqVO createReqVO) {
// 插入
QueryWrapper<IsolationPointDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("guide_id", createReqVO.getGuideId());
objectQueryWrapper.eq("isolation_point_id", createReqVO.getIsolationPointId());
IsolationPointDO isolationPointDO = isolationPointMapper.selectOne(objectQueryWrapper);
if (isolationPointDO != null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.ISOLATION_POINT_EXISTS);
}
IsolationPointDO isolationPoint = BeanUtils.toBean(createReqVO, IsolationPointDO.class);
isolationPointMapper.insert(isolationPoint);
// 返回
return isolationPoint.getId();
}
@Override
public void updateIsolationPoint(IsolationPointSaveReqVO updateReqVO) {
// 校验存在
validateIsolationPointExists(updateReqVO.getId());
QueryWrapper<IsolationPointDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("guide_id", updateReqVO.getGuideId());
objectQueryWrapper.eq("isolation_point_id", updateReqVO.getIsolationPointId());
IsolationPointDO isolationPointDO = isolationPointMapper.selectOne(objectQueryWrapper);
if (isolationPointDO != null && !isolationPointDO.getId().equals(updateReqVO.getId())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.ISOLATION_POINT_EXISTS);
}
// 更新
IsolationPointDO updateObj = BeanUtils.toBean(updateReqVO, IsolationPointDO.class);
isolationPointMapper.updateById(updateObj);
}
@Override
public void deleteIsolationPoint(Long id) {
// 校验存在
validateIsolationPointExists(id);
// 删除
isolationPointMapper.deleteById(id);
}
@Override
public void deleteIsolationPointListByIds(List<Long> ids) {
// 删除
isolationPointMapper.deleteByIds(ids);
}
private void validateIsolationPointExists(Long id) {
if (isolationPointMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.ISOLATION_POINT_NOT_EXISTS);
}
}
@Override
public IsolationPointDO getIsolationPoint(Long id) {
return isolationPointMapper.selectById(id);
}
@Override
public PageResult<IsolationPointDO> getIsolationPointPage(IsolationPointPageReqVO pageReqVO) {
return isolationPointMapper.selectPage(pageReqVO);
}
}

86
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/LockGuideServiceImpl.java

@ -0,0 +1,86 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.LockGuideDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.LockGuideMapper;
import cn.iocoder.yudao.module.lock.service.LockGuideService;
import cn.iocoder.yudao.module.lock.vo.LockGuidePageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockGuideSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 隔离指导书 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class LockGuideServiceImpl implements LockGuideService {
@Resource
private LockGuideMapper lockGuideMapper;
@Override
public Long createLockGuide(LockGuideSaveReqVO createReqVO) {
// 插入
LockGuideDO lockGuide = BeanUtils.toBean(createReqVO, LockGuideDO.class);
lockGuideMapper.insert(lockGuide);
// 返回
return lockGuide.getId();
}
@Override
public void updateLockGuide(LockGuideSaveReqVO updateReqVO) {
// 校验存在
validateLockGuideExists(updateReqVO.getId());
// 更新
LockGuideDO updateObj = BeanUtils.toBean(updateReqVO, LockGuideDO.class);
lockGuideMapper.updateById(updateObj);
}
@Override
public void deleteLockGuide(Long id) {
// 校验存在
validateLockGuideExists(id);
// 删除
lockGuideMapper.deleteById(id);
}
@Override
public void deleteLockGuideListByIds(List<Long> ids) {
// 删除
lockGuideMapper.deleteByIds(ids);
}
private void validateLockGuideExists(Long id) {
if (lockGuideMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.LOCK_GUIDE_NOT_EXISTS);
}
}
@Override
public LockGuideDO getLockGuide(Long id) {
return lockGuideMapper.selectById(id);
}
@Override
public PageResult<LockGuideDO> getLockGuidePage(LockGuidePageReqVO pageReqVO) {
return lockGuideMapper.selectPage(pageReqVO);
}
}

92
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/LockServiceImpl.java

@ -0,0 +1,92 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.LockDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.LockMapper;
import cn.iocoder.yudao.module.lock.service.LockService;
import cn.iocoder.yudao.module.lock.vo.LockPageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockSaveReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 电子锁 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
@Slf4j
public class LockServiceImpl implements LockService {
@Resource
private LockMapper lockMapper;
@Override
public Long createLock(LockSaveReqVO createReqVO) {
// 插入
LockDO lock = BeanUtils.toBean(createReqVO, LockDO.class);
lockMapper.insert(lock);
// 返回
return lock.getId();
}
@Override
public void updateLock(LockSaveReqVO updateReqVO) {
// 校验存在
log.info("[updateLock][updateReqVO({})]", updateReqVO);
validateLockExists(updateReqVO.getId());
// 更新
LockDO updateObj = BeanUtils.toBean(updateReqVO, LockDO.class);
lockMapper.updateById(updateObj);
}
@Override
public void deleteLock(Long id) {
// 校验存在
validateLockExists(id);
// 删除
lockMapper.deleteById(id);
}
@Override
public void deleteLockListByIds(List<Long> ids) {
// 删除
lockMapper.deleteByIds(ids);
}
private void validateLockExists(Long id) {
LockDO lockDO = lockMapper.selectById(id);
if (lockDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.LOCK_NOT_EXISTS);
}
}
@Override
public LockDO getLock(Long id) {
return lockMapper.selectById(id);
}
@Override
public PageResult<LockDO> getLockPage(LockPageReqVO pageReqVO) {
return lockMapper.selectPage(pageReqVO);
}
}

85
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/LockWorkRecordServiceImpl.java

@ -0,0 +1,85 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.LockWorkRecordDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.LockWorkRecordMapper;
import cn.iocoder.yudao.module.lock.service.LockWorkRecordService;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordPageReqVO;
import cn.iocoder.yudao.module.lock.vo.LockWorkRecordSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 电子锁操作记录 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class LockWorkRecordServiceImpl implements LockWorkRecordService {
@Resource
private LockWorkRecordMapper lockWorkRecordMapper;
@Override
public Long createLockWorkRecord(LockWorkRecordSaveReqVO createReqVO) {
// 插入
LockWorkRecordDO lockWorkRecord = BeanUtils.toBean(createReqVO, LockWorkRecordDO.class);
lockWorkRecordMapper.insert(lockWorkRecord);
// 返回
return lockWorkRecord.getId();
}
@Override
public void updateLockWorkRecord(LockWorkRecordSaveReqVO updateReqVO) {
// 校验存在
validateLockWorkRecordExists(updateReqVO.getId());
// 更新
LockWorkRecordDO updateObj = BeanUtils.toBean(updateReqVO, LockWorkRecordDO.class);
lockWorkRecordMapper.updateById(updateObj);
}
@Override
public void deleteLockWorkRecord(Long id) {
// 校验存在
validateLockWorkRecordExists(id);
// 删除
lockWorkRecordMapper.deleteById(id);
}
@Override
public void deleteLockWorkRecordListByIds(List<Long> ids) {
// 删除
lockWorkRecordMapper.deleteByIds(ids);
}
private void validateLockWorkRecordExists(Long id) {
if (lockWorkRecordMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.LOCK_WORD_RECORD_NOT_EXISTS);
}
}
@Override
public LockWorkRecordDO getLockWorkRecord(Long id) {
return lockWorkRecordMapper.selectById(id);
}
@Override
public PageResult<LockWorkRecordDO> getLockWorkRecordPage(LockWorkRecordPageReqVO pageReqVO) {
return lockWorkRecordMapper.selectPage(pageReqVO);
}
}

90
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanItemDetailServiceImpl.java

@ -0,0 +1,90 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.PlanItemDetailDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.PlanItemDetailMapper;
import cn.iocoder.yudao.module.lock.service.PlanItemDetailService;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemDetailSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 隔离计划子项详情 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class PlanItemDetailServiceImpl implements PlanItemDetailService {
@Resource
private PlanItemDetailMapper planItemDetailMapper;
@Override
public Long createPlanItemDetail(PlanItemDetailSaveReqVO createReqVO) {
// 插入
PlanItemDetailDO planItemDetail = BeanUtils.toBean(createReqVO, PlanItemDetailDO.class);
planItemDetailMapper.insert(planItemDetail);
// 返回
return planItemDetail.getId();
}
@Override
public void updatePlanItemDetail(PlanItemDetailSaveReqVO updateReqVO) {
// 校验存在
validatePlanItemDetailExists(updateReqVO.getId());
// 更新
PlanItemDetailDO updateObj = BeanUtils.toBean(updateReqVO, PlanItemDetailDO.class);
planItemDetailMapper.updateById(updateObj);
}
private void checkLockStatus(PlanItemDetailSaveReqVO updateReqVO) {
if (updateReqVO.getLockStatus() != null){
}
}
@Override
public void deletePlanItemDetail(Long id) {
// 校验存在
validatePlanItemDetailExists(id);
// 删除
planItemDetailMapper.deleteById(id);
}
@Override
public void deletePlanItemDetailListByIds(List<Long> ids) {
// 删除
planItemDetailMapper.deleteByIds(ids);
}
private void validatePlanItemDetailExists(Long id) {
if (planItemDetailMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_NOT_EXISTS);
}
}
@Override
public PlanItemDetailDO getPlanItemDetail(Long id) {
return planItemDetailMapper.selectById(id);
}
@Override
public PageResult<PlanItemDetailDO> getPlanItemDetailPage(PlanItemDetailPageReqVO pageReqVO) {
return planItemDetailMapper.selectPage(pageReqVO);
}
}

84
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanItemServiceImpl.java

@ -0,0 +1,84 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.PlanItemDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.PlanItemMapper;
import cn.iocoder.yudao.module.lock.service.PlanItemService;
import cn.iocoder.yudao.module.lock.vo.PlanItemPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanItemSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
/**
* 隔离计划子项 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class PlanItemServiceImpl implements PlanItemService {
@Resource
private PlanItemMapper planItemMapper;
@Override
public Long createPlanItem(PlanItemSaveReqVO createReqVO) {
// 插入
PlanItemDO planItem = BeanUtils.toBean(createReqVO, PlanItemDO.class);
planItemMapper.insert(planItem);
// 返回
return planItem.getId();
}
@Override
public void updatePlanItem(PlanItemSaveReqVO updateReqVO) {
// 校验存在
validatePlanItemExists(updateReqVO.getId());
// 更新
PlanItemDO updateObj = BeanUtils.toBean(updateReqVO, PlanItemDO.class);
planItemMapper.updateById(updateObj);
}
@Override
public void deletePlanItem(Long id) {
// 校验存在
validatePlanItemExists(id);
// 删除
planItemMapper.deleteById(id);
}
@Override
public void deletePlanItemListByIds(List<Long> ids) {
// 删除
planItemMapper.deleteByIds(ids);
}
private void validatePlanItemExists(Long id) {
if (planItemMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_NOT_EXISTS);
}
}
@Override
public PlanItemDO getPlanItem(Long id) {
return planItemMapper.selectById(id);
}
@Override
public PageResult<PlanItemDO> getPlanItemPage(PlanItemPageReqVO pageReqVO) {
return planItemMapper.selectPage(pageReqVO);
}
}

120
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanLifeLockServiceImpl.java

@ -0,0 +1,120 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.LockDO;
import cn.iocoder.yudao.module.lock.dal.PlanItemDetailDO;
import cn.iocoder.yudao.module.lock.dal.PlanLifeLockDO;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.PlanItemDetailMapper;
import cn.iocoder.yudao.module.lock.mapper.PlanLifeLockMapper;
import cn.iocoder.yudao.module.lock.service.PlanLifeLockService;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanLifeLockSaveReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
/**
* 个人生命锁 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class PlanLifeLockServiceImpl implements PlanLifeLockService {
@Resource
private PlanLifeLockMapper planLifeLockMapper;
@Resource
private PlanItemDetailMapper planItemDetailMapper;
public Long createPlanLifeLock(PlanLifeLockSaveReqVO createReqVO) {
List<PlanLifeLockDO> listAll = getListAll(createReqVO.getIsolationPlanItemDetailId());
if (listAll.isEmpty() && !createReqVO.getLockType().equals("1")){
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CENTRALIZED_LISTING_LOCK_NOT_EXISTS);
}
for (PlanLifeLockDO planLifeLockDO : listAll) {
if (planLifeLockDO.getLockType().equals("1") && createReqVO.getLockType().equals("1")){
throw ServiceExceptionUtil.exception(ErrorCodeConstants.CENTRALIZED_LISTING_LOCK_EXISTS);
}
}
// 插入
PlanLifeLockDO planLifeLock = BeanUtils.toBean(createReqVO, PlanLifeLockDO.class);
planLifeLockMapper.insert(planLifeLock);
// 返回
return planLifeLock.getId();
}
@Override
public void updatePlanLifeLock(PlanLifeLockSaveReqVO updateReqVO) {
// 校验存在
validatePlanLifeLockExists(updateReqVO.getId());
// 更新
PlanLifeLockDO updateObj = BeanUtils.toBean(updateReqVO, PlanLifeLockDO.class);
planLifeLockMapper.updateById(updateObj);
}
@Override
public void deletePlanLifeLock(Long id) {
// 校验存在
validatePlanLifeLockExists(id);
// 删除
planLifeLockMapper.deleteById(id);
}
@Override
public void deletePlanLifeLockListByIds(List<Long> ids) {
// 删除
planLifeLockMapper.deleteByIds(ids);
}
private void validatePlanLifeLockExists(Long id) {
PlanLifeLockDO planLifeLockDO = planLifeLockMapper.selectById(id);
if (planLifeLockDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_LIFE_LOCK_NOT_EXISTS);
}
PlanItemDetailDO planItemDetailDO = planItemDetailMapper.selectById(planLifeLockDO.getIsolationPlanItemDetailId());
if (!planItemDetailDO.getLockStatus().equals(3)){
throw ServiceExceptionUtil.exception(ErrorCodeConstants.DETAIL_UNLOCK_STATUS_ERROR);
}
QueryWrapper<PlanLifeLockDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("isolation_plan_item_detail_id", planLifeLockDO.getIsolationPlanItemDetailId());
objectQueryWrapper.eq("lock_type", 5);//5是受影响人锁
objectQueryWrapper.eq("lock_status", 1);//1是锁已上锁
List<PlanLifeLockDO> planLifeLockDOS = planLifeLockMapper.selectList(objectQueryWrapper);
if (!planLifeLockDOS.isEmpty() && !planLifeLockDO.getLockType().equals(5)){
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_LIFE_LOCK_EXISTS);
}
}
@Override
public PlanLifeLockDO getPlanLifeLock(Long id) {
return planLifeLockMapper.selectById(id);
}
@Override
public PageResult<PlanLifeLockDO> getPlanLifeLockPage(PlanLifeLockPageReqVO pageReqVO) {
return planLifeLockMapper.selectPage(pageReqVO);
}
@Override
public List<PlanLifeLockDO> getListAll(Long isolationPlanItemDetailId) {
QueryWrapper<PlanLifeLockDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("isolation_plan_item_detail_id",isolationPlanItemDetailId);
return planLifeLockMapper.selectList(objectQueryWrapper);
}
}

184
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PlanServiceImpl.java

@ -0,0 +1,184 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.lock.dal.PlanDO;
import cn.iocoder.yudao.module.lock.dal.PlanItemDO;
import cn.iocoder.yudao.module.lock.dal.PlanItemDetailDO;
import cn.iocoder.yudao.module.lock.dal.PlanLifeLockDO;
import cn.iocoder.yudao.module.lock.dal.entity.PlanEntity;
import cn.iocoder.yudao.module.lock.dal.entity.PlanItemDetailEntity;
import cn.iocoder.yudao.module.lock.dal.entity.PlanItemEntity;
import cn.iocoder.yudao.module.lock.dal.entity.PlanLifeLockEntity;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.PlanItemDetailMapper;
import cn.iocoder.yudao.module.lock.mapper.PlanItemMapper;
import cn.iocoder.yudao.module.lock.mapper.PlanLifeLockMapper;
import cn.iocoder.yudao.module.lock.mapper.PlanMapper;
import cn.iocoder.yudao.module.lock.service.PlanItemDetailService;
import cn.iocoder.yudao.module.lock.service.PlanItemService;
import cn.iocoder.yudao.module.lock.service.PlanLifeLockService;
import cn.iocoder.yudao.module.lock.service.PlanService;
import cn.iocoder.yudao.module.lock.vo.PlanPageReqVO;
import cn.iocoder.yudao.module.lock.vo.PlanSaveReqVO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.lock.vo.PlanSelectVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static java.util.stream.Collectors.groupingBy;
/**
* 隔离计划 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class PlanServiceImpl implements PlanService {
@Resource
private PlanMapper planMapper;
@Resource
private PlanItemMapper planItemMapper;
@Resource
private PlanLifeLockMapper planLifeLockMapper;
@Resource
private PlanItemDetailMapper planItemDetailMapper;
@Override
public Long createPlan(PlanSaveReqVO createReqVO) {
// 插入
PlanDO plan = BeanUtils.toBean(createReqVO, PlanDO.class);
planMapper.insert(plan);
// 返回
return plan.getId();
}
@Override
public void updatePlan(PlanSaveReqVO updateReqVO) {
// 校验存在
validatePlanExists(updateReqVO.getId());
// 更新
PlanDO updateObj = BeanUtils.toBean(updateReqVO, PlanDO.class);
planMapper.updateById(updateObj);
}
@Override
public void deletePlan(Long id) {
// 校验存在
validatePlanExists(id);
// 删除
planMapper.deleteById(id);
}
@Override
public void deletePlanListByIds(List<Long> ids) {
// 删除
planMapper.deleteByIds(ids);
}
private void validatePlanExists(Long id) {
if (planMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_NOT_EXISTS);
}
}
@Override
public PlanDO getPlan(Long id) {
return planMapper.selectById(id);
}
@Override
public PageResult<PlanDO> getPlanPage(PlanPageReqVO pageReqVO) {
return planMapper.selectPage(pageReqVO);
}
@Override
public List<PlanEntity> listAll(PlanSelectVo pageReqVO) {
// 1. 查询顶层 Plan
var queryWrapper = new QueryWrapper<PlanDO>();
if (StringUtils.isNotBlank(pageReqVO.getIpName())) {
queryWrapper.like("ip_name", pageReqVO.getIpName());
}
if (pageReqVO.getStatus() != null){
queryWrapper.eq("status", pageReqVO.getStatus());
}
List<PlanDO> planDOS = planMapper.selectList(queryWrapper);
if (CollectionUtil.isEmpty(planDOS)) {
return new ArrayList<>();
}
// --- 核心优化:使用通用方法批量查询所有子层级 ---
var planIds = planDOS.stream().map(PlanDO::getId).toList();
// 批量查询所有 PlanItem
List<PlanItemDO> planItemDOS = selectInBatch(planIds, "isolation_plan_id", planItemMapper);
var planItemIds = planItemDOS.stream().map(PlanItemDO::getId).toList();
// 批量查询所有 PlanItemDetail
List<PlanItemDetailDO> planItemDetailDOS = selectInBatch(planItemIds, "isolation_plan_item_id", planItemDetailMapper);
var planItemDetailIds = planItemDetailDOS.stream().map(PlanItemDetailDO::getId).toList();
// 批量查询所有 PlanLifeLock
List<PlanLifeLockDO> planLifeLockDOS = selectInBatch(planItemDetailIds, "isolation_plan_item_detail_id", planLifeLockMapper);
// 1. 将所有查询到的 DO 列表转换为 Entity 列表
List<PlanEntity> planEntities = BeanUtils.toBean(planDOS, PlanEntity.class);
List<PlanItemEntity> itemEntities = BeanUtils.toBean(planItemDOS, PlanItemEntity.class);
List<PlanItemDetailEntity> detailEntities = BeanUtils.toBean(planItemDetailDOS, PlanItemDetailEntity.class);
List<PlanLifeLockEntity> lockEntities = BeanUtils.toBean(planLifeLockDOS, PlanLifeLockEntity.class);
Map<Long, List<PlanLifeLockEntity>> locksByDetailId = lockEntities.stream()
.collect(groupingBy(PlanLifeLockEntity::getIsolationPlanItemDetailId));
Map<Long, List<PlanItemDetailEntity>> detailsByItemId = detailEntities.stream()
.collect(groupingBy(PlanItemDetailEntity::getIsolationPlanItemId));
Map<Long, List<PlanItemEntity>> itemsByPlanId = itemEntities.stream()
.collect(groupingBy(PlanItemEntity::getIsolationPlanId));
// 3. 遍历顶层列表,高效地组装整个对象树
planEntities.forEach(plan -> {
List<PlanItemEntity> items = itemsByPlanId.getOrDefault(plan.getId(), Collections.emptyList());
items.forEach(item -> {
List<PlanItemDetailEntity> details = detailsByItemId.getOrDefault(item.getId(), Collections.emptyList());
details.forEach(detail ->
detail.setLockEntities(locksByDetailId.getOrDefault(detail.getId(), Collections.emptyList()))
);
item.setPlanItemDetailEntityList(details);
});
plan.setPlanItemEntityList(items);
});
return planEntities;
}
/**
* 抽取出的通用方法根据父ID列表批量查询子记录
* @param ids 父ID列表
* @param columnName "in" 查询的列名
* @param mapper 对应的 MyBatis Mapper
* @return 查询到的子记录列表
*/
private <T, M extends BaseMapper<T>> List<T> selectInBatch(List<Long> ids, String columnName, M mapper) {
if (CollectionUtil.isEmpty(ids)) {
return new ArrayList<>();
}
return mapper.selectList(new QueryWrapper<T>().in(columnName, ids));
}
}

353
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/service/impl/PointServiceImpl.java

@ -0,0 +1,353 @@
package cn.iocoder.yudao.module.lock.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.lock.dal.*;
import cn.iocoder.yudao.module.lock.dal.entity.*;
import cn.iocoder.yudao.module.lock.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.lock.mapper.*;
import cn.iocoder.yudao.module.lock.service.LockWorkRecordService;
import cn.iocoder.yudao.module.lock.service.PointService;
import cn.iocoder.yudao.module.lock.util.WordUtils;
import cn.iocoder.yudao.module.lock.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import java.time.LocalDateTime;
import java.util.*;
import java.util.List;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import org.springframework.web.multipart.MultipartFile;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static java.util.stream.Collectors.groupingBy;
/**
* 隔离点 Service 实现类
*
* @author 超级管理员
*/
@Service
@Validated
public class PointServiceImpl implements PointService {
private static final int LOCK_STATUS_UNLOCKED = 0;
private static final int LOCK_STATUS_LOCKED = 5;
private static final int UNLOCK_STATUS_LOCKED = 4;
private static final int PLAN_ITEM_STATUS_UNLOCKED = 1;
private static final int PLAN_STATUS_PARTIALLY_UNLOCKED = 2;
private static final int LOCK_MAIN_STATUS_UNLOCKED = 2;
private static final int CREATE_LOCK_STATUS = 7;
private static final int VERITY_STATUS_UNLOCKED = 3;
@Resource
private PointMapper pointMapper;
@Resource
private IsolationPointMapper isolationPointMapper;
@Resource
private LockGuideMapper lockGuideMapper;
@Resource
private PlanItemDetailMapper planItemDetailMapper;
@Resource
private PlanItemMapper planItemMapper;
@Resource
private PlanLifeLockMapper planLifeLockMapper;
@Resource
private LockMapper lockMapper;
@Resource
private PlanMapper planMapper;
@Override
public Long createPoint(PointSaveReqVO createReqVO) {
// 插入
PointDO point = BeanUtils.toBean(createReqVO, PointDO.class);
QueryWrapper<PointDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("ip_number", point.getIpNumber());
PointDO pointDO = pointMapper.selectOne(objectQueryWrapper);
if (pointDO != null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.POINT_NUMBER_EXISTS);
}
pointMapper.insert(point);
// 返回
return point.getId();
}
@Override
public void updatePoint(PointSaveReqVO updateReqVO) {
// 校验存在
validatePointExists(updateReqVO.getId());
QueryWrapper<PointDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("ip_number", updateReqVO.getIpNumber());
PointDO pointDO = pointMapper.selectOne(objectQueryWrapper);
if (pointDO != null && !pointDO.getId().equals(updateReqVO.getId())) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.POINT_NUMBER_EXISTS);
}
// 更新
PointDO updateObj = BeanUtils.toBean(updateReqVO, PointDO.class);
pointMapper.updateById(updateObj);
}
@Override
public void deletePoint(Long id) {
// 校验存在
validatePointExists(id);
// 删除
pointMapper.deleteById(id);
}
@Override
public void deletePointListByIds(List<Long> ids) {
// 删除
pointMapper.deleteByIds(ids);
}
private void validatePointExists(Long id) {
if (pointMapper.selectById(id) == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.POINT_NOT_EXISTS);
}
}
@Override
public PointDO getPoint(Long id) {
return pointMapper.selectById(id);
}
@Override
public PageResult<PointDO> getPointPage(PointPageReqVO pageReqVO) {
return pointMapper.selectPage(pageReqVO);
}
@Override
public LockEntity getListAll() {
LockEntity lockEntity = new LockEntity();
lockEntity.setPointList(pointMapper.selectList());
lockEntity.setIsolationPointList(isolationPointMapper.selectList());
lockEntity.setLockGuideList(lockGuideMapper.selectList());
lockEntity.setPlanItemDetailList(planItemDetailMapper.selectList());
lockEntity.setPlanItemList(planItemMapper.selectList());
lockEntity.setPlanLifeLockList(planLifeLockMapper.selectList());
lockEntity.setLockList(lockMapper.selectList());
lockEntity.setPlanList(planMapper.selectList());
return lockEntity;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void bindlock(LockStatusVo updateReqVO) {
QueryWrapper<PlanItemDetailDO> objectQueryWrapper = new QueryWrapper<>();
objectQueryWrapper.eq("id", updateReqVO.getPlanItemDetailId());
List<PlanItemDetailDO> planItemDetailDOS = planItemDetailMapper.selectList(objectQueryWrapper);
if (CollectionUtils.isEmpty(planItemDetailDOS)) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_NOT_EXISTS);
}
if (planItemDetailDOS.get(0).getLockStatus().equals(1)) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_LOCK_STATUS_ERROR);
}
lockMapper.updateStatus(updateReqVO.getLockId(), 7);//上锁已验证
List<Long> pointIdList = planItemDetailDOS.stream().map(PlanItemDetailDO::getIsolationPointId).toList();
pointMapper.updateStatusBatch(pointIdList, 1);
planItemDetailMapper.updateDetailLockStatus(1, updateReqVO.getPlanItemDetailId(), updateReqVO.getLockId(), null, null);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void createLock(LockStatusVo updateReqVO) {
PlanItemDetailDO planItemDetailDO = planItemDetailMapper.selectById(updateReqVO.getPlanItemDetailId());
if (planItemDetailDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_NOT_EXISTS);
}
LockDO lockDO = lockMapper.selectById(planItemDetailDO.getLockId());
if (lockDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.LOCK_NOT_EXISTS);
}
if (lockDO.getLockStatus() != CREATE_LOCK_STATUS) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.LOCK_STATUS_ERROR);
}
lockMapper.updateStatus(lockDO.getId(), 3);
planItemDetailMapper.updateDetailLockStatus(2, updateReqVO.getPlanItemDetailId(), null, updateReqVO.getOperateRecordld(), null);
createPlanLiteLock(1, updateReqVO);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void verifyLock(LockStatusVo updateReqVO) {
PlanItemDetailDO planItemDetailDO = planItemDetailMapper.selectById(updateReqVO.getPlanItemDetailId());
if (planItemDetailDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_NOT_EXISTS);
}
if (planItemDetailDO.getLockStatus() != PLAN_STATUS_PARTIALLY_UNLOCKED) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.DETAIL_LOCK_VERITY_ERROR);
}
createPlanLiteLock(3, updateReqVO);
planItemDetailMapper.updateDetailLockStatus(3, updateReqVO.getPlanItemDetailId(), null, null, updateReqVO.getVerifyRecordId());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void verifyUnLock(LockStatusVo updateReqVO) {
PlanItemDetailDO planItemDetailDO = planItemDetailMapper.selectById(updateReqVO.getPlanItemDetailId());
if (planItemDetailDO == null) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_NOT_EXISTS);
}
if (planItemDetailDO.getLockStatus() != VERITY_STATUS_UNLOCKED) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.DETAIL_LOCK_STATUS_ERROR);
}
QueryWrapper<PlanLifeLockDO> lockDOQueryWrapper = new QueryWrapper<>();
lockDOQueryWrapper.eq("isolation_plan_item_detail_id", planItemDetailDO.getId());
lockDOQueryWrapper.eq("lock_type", 5);
List<PlanLifeLockDO> lockDOS = planLifeLockMapper.selectList(lockDOQueryWrapper);
boolean lockStatus = lockDOS.stream().anyMatch(plan -> plan.getLockStatus() == 1);
if (lockStatus) {
throw exception(ErrorCodeConstants.PLAN_LIFE_LOCK_EXISTS);
}
planItemDetailDO.setLockStatus(UNLOCK_STATUS_LOCKED);
planItemDetailMapper.updateById(planItemDetailDO);
planLifeLockMapper.updateStatus(updateReqVO.getLifelockId(), 0, new Date());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void unLock(LockStatusVo updateReqVO) {
PlanItemDetailDO planItemDetailDO = planItemDetailMapper.selectById(updateReqVO.getPlanItemDetailId());
if (planItemDetailDO == null) {
throw exception(ErrorCodeConstants.PLAN_ITEM_DETAIL_NOT_EXISTS);
}
if (planItemDetailDO.getLockStatus() != UNLOCK_STATUS_LOCKED) {
throw exception(ErrorCodeConstants.DETAIL_UNLOCK_STATUS_ERROR);
}
QueryWrapper<PlanLifeLockDO> lockDOQueryWrapper = new QueryWrapper<>();
lockDOQueryWrapper.eq("isolation_plan_item_detail_id", planItemDetailDO.getId());
lockDOQueryWrapper.eq("lock_type", 5);
List<PlanLifeLockDO> lockDOS = planLifeLockMapper.selectList(lockDOQueryWrapper);
boolean lockStatus = lockDOS.stream().anyMatch(plan -> plan.getLockStatus() == 1);
if (lockStatus) {
throw exception(ErrorCodeConstants.PLAN_LIFE_LOCK_EXISTS);
}
planItemDetailMapper.updateDetailLockStatus(LOCK_STATUS_LOCKED, updateReqVO.getPlanItemDetailId(),
null, null, null);
planLifeLockMapper.updateStatus(updateReqVO.getLifelockId(), LOCK_STATUS_UNLOCKED, new Date());
lockMapper.updateStatus(planItemDetailDO.getLockId(), LOCK_MAIN_STATUS_UNLOCKED);
// 2. 查询关联的生命锁状态
QueryWrapper<PlanLifeLockDO> lifeLockQuery = new QueryWrapper<PlanLifeLockDO>()
.eq("isolation_plan_item_detail_id", updateReqVO.getPlanItemDetailId());
List<PlanLifeLockDO> lifeLocks = planLifeLockMapper.selectList(lifeLockQuery);
boolean allUnlocked = lifeLocks.stream().allMatch(plan -> plan.getLockStatus() == LOCK_STATUS_UNLOCKED);
QueryWrapper<PlanItemDetailDO> objectQueryWrapper11 = new QueryWrapper<>();
objectQueryWrapper11.eq("isolation_plan_item_id", planItemDetailDO.getIsolationPlanItemId());
List<PlanItemDetailDO> planItemDetailDOS1 = planItemDetailMapper.selectList(objectQueryWrapper11);
boolean detailLocked = planItemDetailDOS1.stream().allMatch(plan -> plan.getLockStatus() == LOCK_STATUS_LOCKED);
if (allUnlocked && detailLocked) {
updatePlanAndItemStatus(planItemDetailDO.getIsolationPlanItemId(), updateReqVO.getPlanId());
}
// 3. 更新隔离点位状态
QueryWrapper<PlanItemDetailDO> objectQueryWrapper1 = new QueryWrapper<>();
objectQueryWrapper1.eq("isolation_point_id", planItemDetailDO.getIsolationPointId());
List<PlanItemDetailDO> planItemDetailDOS = planItemDetailMapper.selectList(objectQueryWrapper1);
boolean pointStatus = planItemDetailDOS.stream().allMatch(plan -> plan.getLockStatus() == LOCK_STATUS_LOCKED);
if (pointStatus) {
pointMapper.updateStatusBatch(Collections.singletonList(planItemDetailDO.getIsolationPointId()), 0);
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void importPointsFromWord(MultipartFile file) {
try {
String rawContent = WordUtils.extractTextFromWord(file);
LockWordPointVo lockWordPointVo = WordUtils.parseAndPrintStructuredContent(rawContent);
ArrayList<PointDO> objects = new ArrayList<>();
if (CollectionUtil.isNotEmpty(lockWordPointVo.getDataVoList())) {
for (LockWordPointDataVo lockWordPointDataVo : lockWordPointVo.getDataVoList()) {
PointDO pointDO = new PointDO();
pointDO.setStatus(0);
pointDO.setIpName(lockWordPointDataVo.getLocation());
pointDO.setIpNumber(lockWordPointDataVo.getSequence());
pointDO.setIpType("1");
pointDO.setGuideLockNums(Integer.valueOf(lockWordPointVo.getDeviceLock()));
objects.add(pointDO);
}
}
pointMapper.insertBatch(objects);
} catch (Exception e) {
throw ServiceExceptionUtil.exception(ErrorCodeConstants.IMPORT_ERROR);
}
}
private void updatePlanAndItemStatus(Long isolationPlanItemId, Long planId) {
// 更新计划项状态
planItemMapper.updateStatus(isolationPlanItemId, PLAN_ITEM_STATUS_UNLOCKED);
// 检查是否需要更新主计划的状态
QueryWrapper<PlanItemDO> planItemQuery = new QueryWrapper<PlanItemDO>()
.eq("isolation_plan_id", planId);
List<PlanItemDO> planItems = planItemMapper.selectList(planItemQuery);
boolean anyPlanItemUnlocked = planItems.stream()
.allMatch(plan -> plan.getStatus() == PLAN_ITEM_STATUS_UNLOCKED);
if (anyPlanItemUnlocked) {
planMapper.updateStatus(planId, PLAN_ITEM_STATUS_UNLOCKED);
}
}
private void createPlanLiteLock(Integer type, LockStatusVo updateReqVO) {
Long userId = WebFrameworkUtils.getLoginUserId();
PlanLifeLockDO planLifeLockDO = new PlanLifeLockDO();
planLifeLockDO.setIsolationPlanItemDetailId(updateReqVO.getPlanItemDetailId());
planLifeLockDO.setUserId(userId);
planLifeLockDO.setLockType(type);
planLifeLockDO.setLockStatus(1);
planLifeLockDO.setLockTime(LocalDateTime.now());
planLifeLockMapper.insert(planLifeLockDO);
}
}

174
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/util/WordUtils.java

@ -0,0 +1,174 @@
package cn.iocoder.yudao.module.lock.util;
import cn.iocoder.yudao.module.lock.vo.LockWordPointDataVo;
import cn.iocoder.yudao.module.lock.vo.LockWordPointVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.extractor.ExtractorFactory;
import org.apache.poi.extractor.POITextExtractor;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.regex.Pattern;
@Slf4j
public class WordUtils {
public static void main(String[] args) {
// =================================================================
// 请将此路径修改为您本地Word文件的实际路径
// 支持 .doc 和 .docx 格式
// =================================================================
var filePath = "C:\\Users\\admin\\Desktop\\1.docx"; // <-- 请确保路径正确
var file = new File(filePath);
if (!file.exists() || !file.isFile()) {
// 2. 使用 log.error 记录错误
log.error("错误:文件不存在或不是一个有效的文件路径 -> {}", filePath);
return;
}
try {
// 1. 从 Word 文件中提取纯文本
var rawContent = extractTextFrom(file);
// 2. 解析提取出的文本并按结构化格式打印
parseAndPrintStructuredContent(rawContent);
} catch (Exception e) {
// 3. 记录异常信息和堆栈
log.error("处理文件时发生未知异常。", e);
}
}
/**
* 整合所有解析逻辑并结构化地打印出来
*
* @param rawContent Word 中提取的完整纯文本
*/
public static LockWordPointVo parseAndPrintStructuredContent(String rawContent) {
var energyPattern = Pattern.compile("☑ ([^、☐\\s]+)");
var energyMatcher = energyPattern.matcher(rawContent);
var selectedEnergies = new ArrayList<String>();
while (energyMatcher.find()) {
selectedEnergies.add(energyMatcher.group(1));
}
if (selectedEnergies.isEmpty()) {
log.info("未找到任何已勾选的能量项。");
} else {
log.info("已勾选的能量: " + String.join(", ", selectedEnergies));
}
LockWordPointVo lockWordPointVo = new LockWordPointVo();
// --- 2. 解析:上锁前准备 ---
String deviceLock = extractAndPrint("设备锁数量", rawContent, "准备设备锁:([^;]+);");
String repairBrand = extractAndPrint("停机大修牌数量", rawContent, "停机大修牌:([^;]+);");
String sixClip = extractAndPrint("6孔锁夹数量", rawContent, "6孔锁夹:([^;]+);");
String locking = extractAndPrint("上锁装置", rawContent, "上锁装置:([^\n\r]+)");
lockWordPointVo.setDeviceLock(deviceLock);
lockWordPointVo.setRepairBrand(repairBrand);
lockWordPointVo.setSixClip(sixClip);
lockWordPointVo.setLocking(locking);
// --- 3. 解析:表格数据 ---
var dataList = new ArrayList<LockWordPointDataVo>();
var lines = rawContent.split("\\r?\\n");
var isParsingTable = false;
for (var line : lines) {
var trimmedLine = line.trim();
if (trimmedLine.isEmpty()) continue;
if (trimmedLine.startsWith("验证方法")) break; // 表格内容结束
if (trimmedLine.contains("隔离序号") && trimmedLine.contains("隔离点编号")) {
isParsingTable = true;
continue; // 这是标题行,跳过
}
if (isParsingTable) {
var parts = trimmedLine.split("\t");
if (parts.length >= 4) { // 确保数据足够,避免数组越界
var data = new LockWordPointDataVo(parts[0], parts[1], parts[2], parts[3]);
dataList.add(data);
} else {
log.warn("检测到格式不正确的表格行,已跳过: {}", trimmedLine);
}
}
}
// 打印解析出的表格数据
if (dataList.isEmpty()) {
log.warn("未找到或未能解析出表格数据。");
} else {
lockWordPointVo.setDataVoList(dataList);
}
return lockWordPointVo;
}
/**
* 辅助方法根据正则表达式从文本中提取信息并打印
*
* @param label 信息的标签
* @param content 原始内容
* @param regex 正则表达式
*/
private static String extractAndPrint(String label, String content, String regex) {
var pattern = Pattern.compile(regex);
var matcher = pattern.matcher(content);
String value = null;
if (matcher.find()) {
value = matcher.group(1).replaceAll("[把个]|至少", "").trim();
log.info(label + ": " + (value.isEmpty() ? "未填写" : value));
} else {
log.error(label + ": 未找到");
}
return value;
}
/**
* 使用 ExtractorFactory 自动识别上传的 Office 文件真实格式并提取纯文本
* 该方法直接处理 MultipartFile避免了先将文件存到本地的需要
*
* @param multipartFile 要处理的上传文件 (e.g., .doc, .docx, .xls, .xlsx, .ppt, .pptx)
* @return 提取出的纯文本
* @throws Exception 如果文件处理失败例如文件为空无法识别格式或读取错误
*/
public static String extractTextFromWord(MultipartFile multipartFile) throws Exception {
// 1. 校验文件是否为空,增加健壮性
if (multipartFile == null || multipartFile.isEmpty()) {
throw new IllegalArgumentException("文件不能为空。");
}
// 2. 使用 try-with-resources 确保 InputStream 和 Extractor 被自动关闭
// 直接从 MultipartFile 获取输入流,而不是从本地文件
try (InputStream inputStream = multipartFile.getInputStream();
POITextExtractor extractor = ExtractorFactory.createExtractor(inputStream)) {
if (extractor == null) {
// 3. 优化了异常提示信息
throw new IllegalArgumentException("无法识别的文件类型或文件已损坏。请确保是标准的Office格式。");
}
// 4. 返回提取的文本
return extractor.getText();
}
}
public static String extractTextFrom(File file) throws Exception {
// Java 7+ try-with-resources 自动关闭资源
try (InputStream inputStream = new FileInputStream(file);
POITextExtractor extractor = ExtractorFactory.createExtractor(inputStream)) {
if (extractor == null) {
throw new IllegalArgumentException("无法识别的文件类型,文件可能已损坏或非标准Office格式。");
}
return extractor.getText();
}
}
}

26
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/IsolationPointPageReqVO.java

@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.lock.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 指导书与隔离点关联分页 Request VO")
@Data
public class IsolationPointPageReqVO extends PageParam {
@Schema(description = "隔离指导书ID", example = "22721")
private Long guideId;
@Schema(description = "隔离点ID", example = "7504")
private Long isolationPointId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

31
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/IsolationPointRespVO.java

@ -0,0 +1,31 @@
package cn.iocoder.yudao.module.lock.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - 指导书与隔离点关联 Response VO")
@Data
@ExcelIgnoreUnannotated
public class IsolationPointRespVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11289")
@ExcelProperty("id")
private Long id;
@Schema(description = "隔离指导书ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "22721")
@ExcelProperty("隔离指导书ID")
private Long guideId;
@Schema(description = "隔离点ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7504")
@ExcelProperty("隔离点ID")
private Long isolationPointId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

23
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/IsolationPointSaveReqVO.java

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.lock.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import jakarta.validation.constraints.*;
@Schema(description = "管理后台 - 指导书与隔离点关联新增/修改 Request VO")
@Data
public class IsolationPointSaveReqVO {
@Schema(description = "id", requiredMode = Schema.RequiredMode.REQUIRED, example = "11289")
private Long id;
@Schema(description = "隔离指导书ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "22721")
//@NotNull(message = "隔离指导书ID不能为空")
private Long guideId;
@Schema(description = "隔离点ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "7504")
//@NotNull(message = "隔离点ID不能为空")
private Long isolationPointId;
}

56
server/yudao-module-lock/src/main/java/cn/iocoder/yudao/module/lock/vo/LockGuidePageReqVO.java

@ -0,0 +1,56 @@
package cn.iocoder.yudao.module.lock.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 隔离指导书分页 Request VO")
@Data
public class LockGuidePageReqVO extends PageParam {
@Schema(description = "工作内容和范围")
private String guideContent;
/**
* 隔离指导书名称
*/
@Schema(description = "隔离指导书名称")
private String name;
/**
* 隔离计划编号
*/
@Schema(description = "隔离计划编号")
private String code;
/**
* 集中挂牌人ID
*/
@Schema(description = "集中挂牌人ID")
private Long operatorId;
/**
* 集中挂牌协助人ID
*/
@Schema(description = "集中挂牌协助人ID")
private Long operatorHelperId;
/**
* 验证人ID
*/
@Schema(description = "验证人ID")
private Long verifierId;
/**
* 验证协助人ID
*/
@Schema(description = "验证协助人ID")
private Long verifierHelperId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

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

Loading…
Cancel
Save