gaoluyang
2026-09-30 3544b0b9487c235387a91179d95669a66515399d
feat(migration): 接入 5 个 cnas 模块骨架,补迁 ruoyi-common/ruoyi-system 缺失文件

- 根 pom 注册 cnas-require/manage/device/process/personnel 并声明 poi-tl、
fastjson(v1 兼容包)、weixin-java-cp/common、aspose-words、itextpdf
- ruoyi-common 增 fastjson + 企业微信依赖;ruoyi-admin 声明 5 个 cnas 模块
- 补迁 ruoyi-common 25 个文件(InformationNotification、PersonalScope、
WxCpUtils、IfsApiUtils 等)与 ruoyi-system 13 个文件(通知/客户/部门
mapper+service+XML)
- 机械转换:javax.annotation→jakarta.annotation;Swagger2 注解→OpenAPI 3 @Schema
- 两处第三方依赖规避:去掉未使用的 org.jetbrains.annotations 导入,
IoUtils.copy→InputStream.transferTo

已核对 lims-xjxj 中存在 custom/department_lims/information_notification/user
表,mapper XML 表名一致。
已添加43个文件
已修改3个文件
2370 ■■■■■ 文件已修改
cnas-device/pom.xml 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-manage/pom.xml 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-personnel/pom.xml 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-process/pom.xml 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-require/pom.xml 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-admin/pom.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/pom.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/annotation/PersonalScope.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/IfsProperties.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/PersonnelProperties.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/config/WechatProperty.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/DeviceImpowerConstants.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/DictDataConstants.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/InsOrderTypeConstants.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/constant/MenuJumpPathConstants.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/Custom.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/DepartmentDto.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/DepartmentLims.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/InformationNotification.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/InformationNotificationDto.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderType.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/ApplicationContextHolder.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateImageUtil.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/FileSaveUtil.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/GZipUtil.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/LimsDateUtil.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/Md5Util.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/MyUtil.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/SignatureImageUtil.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/WxCpUtils.java 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/api/IfsApiUtils.java 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/ParameterEscaperUtil.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/src/main/resources/ttf/signature.ttf 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysRoleVo.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserVo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/CustomMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/DepartmentLimsMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/mapper/InformationNotificationMapper.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/CustomService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/InformationNotificationService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/CustomServiceImpl.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InformationNotificationServiceImpl.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/CustomMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/DepartmentLimsMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-system/src/main/resources/mapper/system/InformationNotificationMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cnas-device/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
<?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>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.9.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cnas-device</artifactId>
    <description>
        CNAS è®¾å¤‡æ¨¡å—
    </description>
    <dependencies>
        <!--业务模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>inspect-server</artifactId>
        </dependency>
        <!-- MyBatis-Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
        </dependency>
        <!-- Excel å·¥å…· -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
        </dependency>
        <!-- hutool å·¥å…·ç±» -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!-- fastjson v1 API å…¼å®¹åŒ… -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <!-- poi-tl:Word æŠ¥è¡¨æ¨¡æ¿å¡«å…… -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>
cnas-manage/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,63 @@
<?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>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.9.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cnas-manage</artifactId>
    <description>
        CNAS ç®¡ç†æ¨¡å—
    </description>
    <dependencies>
        <!--业务模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>inspect-server</artifactId>
        </dependency>
        <!-- MyBatis-Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
        </dependency>
        <!-- Excel å·¥å…· -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
        </dependency>
        <!-- hutool å·¥å…·ç±» -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!-- poi-tl:Word æŠ¥è¡¨æ¨¡æ¿å¡«å…… -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
        </dependency>
        <!-- word è½¬ pdf -->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>
cnas-personnel/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
<?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>com.ruoyi</groupId>
        <artifactId>ruoyi</artifactId>
        <version>3.9.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cnas-personnel</artifactId>
    <description>
        CNAS äººå‘˜æ¨¡å—
    </description>
    <dependencies>
        <!-- é€šç”¨å·¥å…·-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
        <!-- æ ¸å¿ƒæ¨¡å—-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-framework</artifactId>
        </dependency>
        <!-- ç³»ç»Ÿæ¨¡å—-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
        </dependency>
        <!--业务模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>inspect-server</artifactId>
        </dependency>
        <!-- MyBatis-Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
        </dependency>
        <!-- Excel å·¥å…· -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
        </dependency>
        <!-- poi-tl:Word æŠ¥è¡¨æ¨¡æ¿å¡«å…… -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>
cnas-process/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,73 @@
<?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>
        <artifactId>ruoyi</artifactId>
        <groupId>com.ruoyi</groupId>
        <version>3.9.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cnas-process</artifactId>
    <description>
        CNAS è¿‡ç¨‹æ¨¡å—
    </description>
    <dependencies>
        <!--业务模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>inspect-server</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>cnas-device</artifactId>
        </dependency>
        <!-- MyBatis-Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
        </dependency>
        <!-- Excel å·¥å…· -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
        </dependency>
        <!-- hutool å·¥å…·ç±» -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!-- fastjson v1 API å…¼å®¹åŒ… -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <!-- poi-tl:Word æŠ¥è¡¨æ¨¡æ¿å¡«å…… -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
        </dependency>
        <!-- word è½¬ pdf -->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>aspose-words</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>
cnas-require/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
<?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>com.ruoyi</groupId>
        <artifactId>ruoyi</artifactId>
        <version>3.9.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>cnas-require</artifactId>
    <description>
        CNAS è¦æ±‚模块
    </description>
    <dependencies>
        <!-- é€šç”¨å·¥å…·-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-common</artifactId>
        </dependency>
        <!-- æ ¸å¿ƒæ¨¡å—-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-framework</artifactId>
        </dependency>
        <!--业务模块-->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>inspect-server</artifactId>
        </dependency>
        <!-- MyBatis-Plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot4-starter</artifactId>
        </dependency>
        <!-- Excel å·¥å…· -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
        </dependency>
        <!-- hutool å·¥å…·ç±» -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!-- fastjson v1 API å…¼å®¹åŒ… -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <!-- poi-tl:Word æŠ¥è¡¨æ¨¡æ¿å¡«å…… -->
        <dependency>
            <groupId>com.deepoove</groupId>
            <artifactId>poi-tl</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>
pom.xml
@@ -38,6 +38,11 @@
        <guava.version>33.6.0-jre</guava.version>
        <commons.text.version>1.10.0</commons.text.version>
        <swagger.annotations.version>2.2.52</swagger.annotations.version>
        <poi.tl.version>1.12.2</poi.tl.version>
        <fastjson.compat.version>2.0.23</fastjson.compat.version>
        <weixin.version>4.1.0</weixin.version>
        <aspose.words.version>15.12.0</aspose.words.version>
        <itextpdf.version>5.0.6</itextpdf.version>
    </properties>
    <!-- ä¾èµ–声明 -->
@@ -263,6 +268,69 @@
                <artifactId>performance-server</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>cnas-require</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>cnas-manage</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>cnas-device</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>cnas-process</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <dependency>
                <groupId>com.ruoyi</groupId>
                <artifactId>cnas-personnel</artifactId>
                <version>${ruoyi.version}</version>
            </dependency>
            <!-- poi-tl:Word æŠ¥è¡¨æ¨¡æ¿å¡«å…… -->
            <dependency>
                <groupId>com.deepoove</groupId>
                <artifactId>poi-tl</artifactId>
                <version>${poi.tl.version}</version>
            </dependency>
            <!-- fastjson v1 API å…¼å®¹åŒ…(由 fastjson2 æä¾› com.alibaba.fastjson.*) -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.compat.version}</version>
            </dependency>
            <!-- ä¼ä¸šå¾®ä¿¡ -->
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-cp</artifactId>
                <version>${weixin.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.binarywang</groupId>
                <artifactId>weixin-java-common</artifactId>
                <version>${weixin.version}</version>
            </dependency>
            <!-- word è½¬ pdf -->
            <dependency>
                <groupId>com.aspose</groupId>
                <artifactId>aspose-words</artifactId>
                <version>${aspose.words.version}</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>${itextpdf.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
@@ -277,6 +345,11 @@
        <module>basic-server</module>
        <module>inspect-server</module>
        <module>performance-server</module>
        <module>cnas-require</module>
        <module>cnas-manage</module>
        <module>cnas-device</module>
        <module>cnas-process</module>
        <module>cnas-personnel</module>
    </modules>
    <packaging>pom</packaging>
ruoyi-admin/pom.xml
@@ -72,6 +72,36 @@
            <artifactId>performance-server</artifactId>
        </dependency>
        <!-- CNAS è¦æ±‚ -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>cnas-require</artifactId>
        </dependency>
        <!-- CNAS ç®¡ç† -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>cnas-manage</artifactId>
        </dependency>
        <!-- CNAS è®¾å¤‡ -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>cnas-device</artifactId>
        </dependency>
        <!-- CNAS è¿‡ç¨‹ -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>cnas-process</artifactId>
        </dependency>
        <!-- CNAS äººå‘˜ -->
        <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>cnas-personnel</artifactId>
        </dependency>
    </dependencies>
    <build>
ruoyi-common/pom.xml
@@ -148,6 +148,22 @@
            <artifactId>commons-text</artifactId>
        </dependency>
        <!-- fastjson v1 API å…¼å®¹åŒ…(IfsApiUtils ç­‰ä½¿ç”¨ com.alibaba.fastjson.*) -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <!-- ä¼ä¸šå¾®ä¿¡ï¼ˆWxCpUtils ä½¿ç”¨ï¼‰ -->
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-cp</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.binarywang</groupId>
            <artifactId>weixin-java-common</artifactId>
        </dependency>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
ruoyi-common/src/main/java/com/ruoyi/common/annotation/PersonalScope.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.*;
/**
 * ä»…看我权限
 *
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PersonalScope {
    /**
     * æƒé™æ ‡è¯†åç§°
     * @return
     */
    String permsName();
    /**
     * å¯¹è±¡åç§°
     * @return
     */
    Class objectName();
    /**
     * å‚数名称
     * @return
     */
    String paramName();
}
ruoyi-common/src/main/java/com/ruoyi/common/config/IfsProperties.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,46 @@
package com.ruoyi.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 * @Author zhuo
 * @Date 2024/9/29
 */
@Configuration
@ConfigurationProperties(prefix = "ifs")
@Data
public class IfsProperties {
    /**
     * åŸŸ
     */
    private String contract;
    /**
     * ç§˜é’¥-get
     */
    private String contractKeyGet;
    /**
     * ç§˜é’¥-post
     */
    private String contractKeyPost;
    /**
     * 80
     */
    private String custorder;
    /**
     * 8008
     */
    private String custorderPort;
    /**
     * 8081
     */
    private String erpServices;
}
ruoyi-common/src/main/java/com/ruoyi/common/config/PersonnelProperties.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,39 @@
package com.ruoyi.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 * äººäº‹ç³»ç»Ÿapi
 *
 * @Author zhuo
 * @Date 2025/3/16
 */
@Configuration
@ConfigurationProperties(prefix = "personnel")
@Data
public class PersonnelProperties {
    /**
     * æ­£å¼åœ°å€
     * */
    private String code;
    /**
     * è£…备人事正式库
     * */
    private String appId;
    private String appSecret;
    private String companies;
    private String simple;
    /**
     * äººå‘˜å¯†ç èŽ·å–
     * */
    private String password;
    private String department;
    private String person;
}
ruoyi-common/src/main/java/com/ruoyi/common/config/WechatProperty.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.ruoyi.common.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
 */
@Configuration
@ConfigurationProperties(prefix = "wechat")
@Data
public class WechatProperty {
    /**
     * è£…备电缆:报检通知url
     */
    private String examiningUrl;
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/DeviceImpowerConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package com.ruoyi.common.constant;
/**
 * @Author zhuo
 * @Date 2025/4/18
 */
public class DeviceImpowerConstants {
    /**
     * è€åŒ–室维护内容
     */
    public static final String AGING_MAINTENANCE_CONTENT = "aging_maintenance_content";
    /**
     * ç”µæ€§èƒ½å®žéªŒå®¤ç»´æŠ¤å†…容
     */
    public static final String ELECTRICAL_MAINTENANCE_CONTENT = "electrical_maintenance_content";
    /**
     * çŽ¯å¢ƒå®žéªŒå®¤ç»´æŠ¤å†…å®¹
     */
    public static final String ENVIRONMENTAL_MAINTENANCE_CONTENT = "environmental_maintenance_content";
    /**
     * ç‡ƒçƒ§å®žéªŒå®¤ç»´æŠ¤å†…容
     */
    public static final String BURN_MAINTENANCE_CONTENT = "burn_maintenance_content";
    /**
     * æ··ç‚¼å®žéªŒå®¤ç»´æŠ¤å†…容
     */
    public static final String MIXING_MAINTENANCE_CONTENT = "mixing_maintenance_content";
    /**
     * æ£€æµ‹ä¸­å¿ƒç”µæ€§èƒ½å®žéªŒå®¤ç»´æŠ¤å†…容
     */
    public static final String CENTER_ELECTRICAL_MAINTENANCE_CONTENT = "center_electrical_maintenance_content";
    /**
     * æ’温二维护内容
     */
    public static final String TEMPERATURE2_MAINTENANCE_CONTENT = "temperature2_maintenance_content";
    /**
     * æ’温一维护内容
     */
    public static final String TEMPERATURE1_MAINTENANCE_CONTENT = "temperature1_maintenance_content";
    /**
     * åŒ–学实验室维护内容
     */
    public static final String CHEMISTRY_MAINTENANCE_CONTENT = "chemistry_maintenance_content";
    /**
     * åˆ¶æ ·å®¤ç»´æŠ¤å†…容
     */
    public static final String SAMPLE_MAINTENANCE_CONTENT = "sample_maintenance_content";
    /**
     * ä½Žæ¸©å®žéªŒå®¤ç»´æŠ¤å†…容
     */
    public static final String HYPOTHERMIA_MAINTENANCE_CONTENT = "hypothermia_maintenance_content";
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/DictDataConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package com.ruoyi.common.constant;
import lombok.Data;
/**
 * å­—典类型
 *
 * @Author zhuo
 * @Date 2025/2/25
 */
public class DictDataConstants {
    // æ£€éªŒç±»åž‹(原材料)
    public static final String CHECK_TYPE = "check_type";
    // æ£€éªŒç±»åž‹(成品)
    public static final String CHECK_TYPE1 = "check_type1";
    // æ¥æ ·æ–¹å¼
    public static final String FORM_TYPE = "form_type";
    // æ ·å“çŠ¶æ€
    public static final String SAMPLE_STATUS_LIST = "sample_status_list";
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/InsOrderTypeConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
package com.ruoyi.common.constant;
/**
 * æ£€éªŒç±»åž‹
 *
 * @Author zhuo
 * @Date 2024/8/11
 */
public class InsOrderTypeConstants {
    // æ£€éªŒç±»åž‹
    public static final String SPOT_CHECK = "抽检";
    // å§”托检验
    public static final String CUSTOMER_ORDERED = "Customer-ordered test";
    // è¿›åŽ‚æ£€éªŒ
    public static final String ENTER_THE_FACTORY = "进厂检验";
    // å­£åº¦æ£€éªŒ
    public static final String QUARTERLY_TEST = "Quarterly inspection";
}
ruoyi-common/src/main/java/com/ruoyi/common/constant/MenuJumpPathConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.common.constant;
/**
 * èœå•调准路径
 *
 * @Author zhuo
 * @Date 2025/3/14
 */
public class MenuJumpPathConstants {
    /**
     * æŠ¥å‘Šç¼–制
     */
    public static final String REPORT_PREPARATION = "ReportPreparation";
    /**
     * æ£€éªŒä»»åŠ¡å¤æ ¸
     */
    public static final String INSPECTION_REVIEW = "InspectionReview";
    /**
     * è´¨é‡ç›‘控
     */
    public static final String QUALITY_MONITOR = "EnsureResultsValidity";
    /**
     * è´¨é‡ç›‘督
     */
    public static final String QUALITY_SUPERVISE = "QualityControlPlan";
    /**
     * äººå‘˜
     */
    public static final String DEVICE = "Device";
    /**
     * è®¾å¤‡
     */
    public static final String PERSONNEL = "PersonnelInfo";
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/Custom.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.ruoyi.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName("custom")
public class Custom implements Serializable {
    @Schema(description = "主键")
    @TableId(type = IdType.AUTO)
    private Long id;
    @Schema(description = "客户名称")
    private String company;
    @Schema(description = "单位地址")
    private String address;
    @Schema(description = "联系人")
    private String contact;
    @Schema(description = "工厂域")
    private String code;
    @Schema(description = "客户编号")
    private String code2;
    @TableField(fill = FieldFill.INSERT)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    @Schema(description = "创建日期")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    @Schema(description = "创建用户")
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @Schema(description = "更新用户")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @Schema(description = "客户单位EN")
    private String companyEn;
    @Schema(description = "单位地址EN")
    private String addressEn;
    @Schema(description = "加急额度")
    private Integer num;
    @Schema(description = "单位电话")
    private String phone;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/DepartmentDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.ruoyi.common.core.domain.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DepartmentDto {
    private Integer id;
    private String name;
    private Integer userId;
    private Integer fatherId;
    private List<DepartmentDto> children;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/DepartmentLims.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package com.ruoyi.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
/**
 * éƒ¨é—¨æ˜Žç»†
 * @TableName department_lims
 */
@TableName(value ="department_lims")
@Data
public class DepartmentLims implements Serializable {
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    @Schema(description = "名称")
    private String name;
    @Schema(description = "父级id")
    private Integer fatherId;
    @TableField(fill = FieldFill.INSERT)
    private Integer createUser;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Integer updateUser;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @TableField(exist = false)
    private List<DepartmentLims> children;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/InformationNotification.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.ruoyi.common.core.domain.entity;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
 * <p>
 * æ¶ˆæ¯é€šçŸ¥
 * </p>
 *
 * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
 * @since 2024-04-23 02:14:30
 */
@Getter
@Setter
@TableName("information_notification")
@Schema(description = "消息通知")
public class InformationNotification implements Serializable {
    private static final long serialVersionUID = 1L;
    @Schema(description = "主键ID")
    @TableId(type = IdType.AUTO)
    private Integer id;
    @Schema(description = "创建人")
    private String createUser;
    @Schema(description = "更新时间")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    @Schema(description = "创建时间/发送时间")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @Schema(description = "待办、接收、审核、批准、预警提醒、通知公告")
    private String messageType;
    @Schema(description = "主题")
    private String theme;
    @Schema(description = "内容")
    private String content;
    @Schema(description = "发送人Id")
    private Integer senderId;
    @Schema(description = "收件人")
    private Integer consigneeId;
    @Schema(description = "查看状态:已读,未读")
    private Boolean viewStatus;
    @Schema(description = "消息状态(拒绝、接收)(根据消息类型展示)")
    private Boolean messageStatus;
    @Schema(description = "跳转路径")
    private String jumpPath;
    @Schema(description = "跳转Id")
    private String jumpId;
}
ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/InformationNotificationDto.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,10 @@
package com.ruoyi.common.core.domain.entity;
import lombok.Data;
@Data
public class InformationNotificationDto extends InformationNotification{
    private String senderUser;
    private String consigneeUser;
}
ruoyi-common/src/main/java/com/ruoyi/common/enums/OrderType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.ruoyi.common.enums;
import org.apache.commons.lang3.StringUtils;
public enum OrderType {
    RAW("原材料","01raw"),
    WG("外购成品","02wg");
    private String label,value;
    public String getLabel() {
        return label;
    }
    public String getValue() {
        return value;
    }
    OrderType(String label, String value) {
        this.label = label;
        this.value = value;
    }
    public static boolean validateValue(String value){
        boolean flag = false;
        for (OrderType orderType : OrderType.values()) {
            if(StringUtils.isNotBlank(value)&&StringUtils.equals(orderType.getValue(),value)){
                flag = true;
            }
        }
        return flag;
    }
    public static String getLabelByValue(String value){
        for (OrderType orderType : OrderType.values()) {
            if(validateValue(value)&&StringUtils.equals(orderType.getValue(), value)){
                return orderType.getLabel();
            }
        }
        return "";
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/ApplicationContextHolder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.ruoyi.common.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
 * @Author: zhangxy
 * @Date: 2021-05-24 16:29
 */
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        applicationContext = ctx;
    }
    /**
     * Get application context from everywhere
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    /**
     * Get bean by class
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }
    /**
     * Get bean by class name
     *
     * @param name
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
        return (T) applicationContext.getBean(name);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateImageUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package com.ruoyi.common.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
/**
 * @Author zhuo
 * @Date 2024/9/28
 */
public class DateImageUtil {
    /**
     * ç”Ÿæˆ å½“前日期的画布
     * @return
     */
    public static InputStream createDateImage(LocalDateTime date) {
        int width = 80;
        int height = 20;
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd");
        if (date == null) {
            date = LocalDateTime.now();
        }
        String s = date.format(formatter);
        Font font = new Font("Serif", Font.BOLD, 10);
        // åˆ›å»ºä¸€ä¸ªç”»å¸ƒï¼ˆèƒŒæ™¯é€æ˜Žï¼‰
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        // èŽ·å–ç”»å¸ƒçš„ç”»ç¬”
        Graphics2D g2 = (Graphics2D) bi.getGraphics();
        // å¼€å§‹ç»˜å›¾
        g2.setComposite(AlphaComposite.Src); // ç¡®ä¿ç»˜å›¾æ—¶æ˜¯é€æ˜ŽèƒŒæ™¯
        g2.setBackground(new Color(0, 0, 0, 0)); // èƒŒæ™¯è‰²ä¸ºé€æ˜Ž
        g2.clearRect(0, 0, width, height);
        g2.setPaint(new Color(0, 0, 0)); // è®¾ç½®ç»˜åˆ¶é¢œè‰²
        FontRenderContext context = g2.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(s, context);
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = -bounds.getY();
        double baseY = y + ascent;
        g2.drawString(s, (int) x, (int) baseY);
        g2.dispose(); // é‡Šæ”¾ç”»ç¬”资源
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(bi, "png", os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return new ByteArrayInputStream(os.toByteArray());
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/FileSaveUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,178 @@
package com.ruoyi.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import jakarta.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;
/**
 * ä¿å­˜æ–‡ä»¶å·¥å…·
 */
@Slf4j
@Component
public class FileSaveUtil {
    // å–yml中的路径 + /
    private static String FILE_PATH;
    private static String WORD_URL_PATH;
    private static String[] ALLOWED;
    @Value("${file.path}")
    private String file;
    @Value("${wordUrl}")
    private String wordUrl;
    @Value("${file.allowed}")
    private String[] allowed;
    @PostConstruct
    public void getFile() {
        FILE_PATH = this.file;
    }
    @PostConstruct
    public void getWordUrl(){
        WORD_URL_PATH = this.wordUrl;
    }
    @PostConstruct
    public void getAllowed(){
        ALLOWED = this.allowed;
    }
    /**
     * å­˜å‚¨æ–‡ä»¶ä¸»å‡½æ•°
     * @param file æ–‡ä»¶äºŒè¿›åˆ¶æµ
     * @return è¿”回文件名称用于存储数据库
     */
    public static String StoreFile(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        // ç”Ÿæˆéšæœºåç§°ï¼šæ—¶é—´_随机6位数字
        String FileName = System.currentTimeMillis() + "_" + getNumber(6);
        String suffix = null;
        if (originalFilename != null) {
            suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
            // å¦‚果后缀名不通过抛出异常
            if (!isFileAllowed(suffix)){
                throw new RuntimeException(suffix);
            }
        }
        // åç§°æ‹¼æŽ¥
        String fileName = FileName + suffix;
        // è¿›è¡Œå­˜å‚¨
        try {
            storeFileWithFileName(file.getBytes(), fileName);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return fileName;
    }
    public static Boolean DeleteFile(String fileName) {
        if (ObjectUtils.isEmpty(fileName)) {
            return false;
        }
        return FileSystemUtils.deleteRecursively(new File(FILE_PATH + "/" + fileName));
    }
    /**
     * å­˜å‚¨æ–‡ä»¶å‡½æ•°
     * @param content æ–‡ä»¶äºŒè¿›åˆ¶æµ
     * @param fileName æ–‡ä»¶åç§°
     */
    private static void storeFileWithFileName(byte[] content, String fileName) {
        // å­˜å‚¨è·¯å¾„
        String path = FILE_PATH + File.separatorChar;
        // ç›®å½•不存在则创建
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        // å¼€å§‹å­˜å‚¨
        try (FileOutputStream os = new FileOutputStream(path + fileName);
             ByteArrayInputStream is = new ByteArrayInputStream(content)) {
             is.transferTo(os);
        } catch (IOException e) {
            throw new RuntimeException("文件存储格式异常");
        }
    }
    /**
     * åˆ¤æ–­æ–‡ä»¶æ˜¯å¦è¢«å…è®¸ä¸Šä¼ 
     *
     * @param fileName æ–‡ä»¶å
     * @return å…è®¸true, å¦åˆ™false
     */
    private static boolean isFileAllowed(String fileName) {
        // èŽ·å–åŽç¼€å
        String suffixName = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();
        for (String allow : ALLOWED) {
            if (allow.equals(suffixName)) {
                return true;
            }
        }
        return false;
    }
    /**
     * ä¿å­˜æ–‡ä»¶åˆ°word文件夹里
     * @param file
     * @return
     */
    public static String uploadWordFile(MultipartFile file) {
        String urlString;
        String pathName;
        String path;
        try {
            String contentType = file.getContentType();
            if (contentType != null && contentType.startsWith("image/")) {
                // æ˜¯å›¾ç‰‡
                path = FILE_PATH;
            } else {
                // æ˜¯æ–‡ä»¶
                path = WORD_URL_PATH;
            }
            File realpath = new File(path);
            if (!realpath.exists()) {
                realpath.mkdirs();
            }
            pathName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMddHHmmss")) + "-" + file.getOriginalFilename();
            urlString = realpath + "/" + pathName;
            file.transferTo(new File(urlString));
            return pathName;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * èŽ·å–éšæœºæ•°å­—
     * @param n ä½æ•°
     * @return è¿”回随机值
     */
    public static String getNumber(int n) {
        char[] chars = "1234567890".toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            char c = chars[new Random().nextInt(chars.length)];
            sb.append(c);
        }
        return sb.toString();
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/GZipUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
package com.ruoyi.common.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
 * åŽ‹ç¼©è§£åŽ‹å·¥å…·ç±»
 */
public class GZipUtil {
    /**
     * åŽ‹ç¼©
     * @param str
     * @return
     */
    public static String compress(String str) {
        if (str == null || str.trim().length() == 0) {
            return null;
        }
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             GZIPOutputStream gzip = new GZIPOutputStream(out)) {
            gzip.write(str.getBytes("utf-8"));
            gzip.close();
            return new String(out.toByteArray(), "iso-8859-1");
        } catch (Exception e) {
            throw new RuntimeException("数据压缩失败");
        }
    }
    /**
     * è§£åŽ‹
     * @param str
     * @return
     */
    public static String uncompress(String str) {
        if (str == null || str.trim().length() == 0) {
            return null;
        }
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
             ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes("iso-8859-1"))){
            GZIPInputStream ungzip = new GZIPInputStream(in);
            byte[] buffer = new byte[1024];
            int n;
            while ((n = ungzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            return new String(out.toByteArray(), "utf-8");
        } catch (Exception e) {
            throw new RuntimeException("数据解压失败");
        }
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/LimsDateUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
package com.ruoyi.common.utils;
import cn.hutool.core.date.DateUtil;
import java.time.LocalDateTime;
/**
 * @Author zhuo
 * @Date 2024/9/28
 */
public class LimsDateUtil {
    /**
     * æ—¥æœŸæ ¼å¼åˆ°26号月份加一
     * @param localDateTime
     * @return
     */
    public static String resetDate(LocalDateTime localDateTime) {
        // èŽ·å–å½“å‰æ—¥
        int dayOfMonth = localDateTime.getDayOfMonth();
        // åˆ¤æ–­æ˜¯å¦æ˜¯26日及以上
        if (dayOfMonth >= 26) {
            // æœˆä»½åŠ 1
            localDateTime = localDateTime.plusMonths(1);
        }
        // æ ¼å¼åŒ–为"yyMM"格式
        String formattedDate = DateUtil.format(localDateTime, "yyMM");
        return formattedDate;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/Md5Util.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,68 @@
package com.ruoyi.common.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
 * @author cxf
 */
public class Md5Util {
    /**
     * é»˜è®¤çš„密码字符串组合,用来将字节转换成 16 è¿›åˆ¶è¡¨ç¤ºçš„字符
     */
    protected static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
    protected static MessageDigest messagedigest = null;
    static {
        try {
            messagedigest = MessageDigest.getInstance("MD5");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }
    public static String getFileMd5String(File file) throws IOException {
        InputStream fis;
        fis = new FileInputStream(file);
        byte[] buffer = new byte[1024];
        int numRead = 0;
        while ((numRead = fis.read(buffer)) > 0) {
            messagedigest.update(buffer, 0, numRead);
        }
        fis.close();
        return bufferToHex(messagedigest.digest());
    }
    public static String getStringMd5(String str) {
        byte[] buffer = str.getBytes();
        messagedigest.update(buffer);
        return bufferToHex(messagedigest.digest());
    }
    public static String bufferToHex(byte bytes[]) {
        return bufferToHex(bytes, 0, bytes.length);
    }
    private static String bufferToHex(byte bytes[], int m, int n) {
        StringBuffer stringbuffer = new StringBuffer(2 * n);
        int k = m + n;
        for (int l = m; l < k; l++) {
            appendHexPair(bytes[l], stringbuffer);
        }
        return stringbuffer.toString();
    }
    private static void appendHexPair(byte bt, StringBuffer stringbuffer) {
        // å–字节中高 4 ä½çš„æ•°å­—转换
        char c0 = hexDigits[(bt & 0xf0) >> 4];
        // ä¸ºé€»è¾‘右移,将符号位一起右移,此处未发现两种符号有何不同
        // å–字节中低 4 ä½çš„æ•°å­—转换
        char c1 = hexDigits[bt & 0xf];
        stringbuffer.append(c0);
        stringbuffer.append(c1);
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/MyUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.ruoyi.common.utils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
@Component
public class MyUtil<T> {
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/SignatureImageUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package com.ruoyi.common.utils;
import org.springframework.core.io.ClassPathResource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
/**
 * @Author zhuo
 * @Date 2025/5/7
 */
public class SignatureImageUtil {
    /**
     * æ ¹æ®ä¸­æ–‡å¯¼å‡ºç­¾åå›¾ç‰‡
     * @param text
     * @return
     * @throws IOException
     * @throws FontFormatException
     */
    public static InputStream saveImageToFile(String text){
        // èŽ·å–å­—ä½“åº“
        Font font = null;
        try (InputStream is = new ClassPathResource("/ttf/signature.ttf").getInputStream()) {
            font = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(50f);
        } catch (FontFormatException | IOException e) {
            throw new RuntimeException(e);
        }
        int width = 100; // å›¾ç‰‡çš„宽度
        int height = 50; // å›¾ç‰‡çš„高度
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = image.createGraphics();
        g2d.setFont(font);
        // è®¾ç½®æ–‡å­—颜色为黑色
        g2d.setColor(Color.black);
        // è®¾ç½®æ–‡å­—在图片中的位置
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(text, context);
        double x = (width - bounds.getWidth()) / 2;
        double y = (height - bounds.getHeight()) / 2;
        double ascent = -bounds.getY();
        double baseY = y + ascent;
        g2d.drawString(text, (int) x, (int) baseY);
        g2d.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return new ByteArrayInputStream(os.toByteArray());
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/WxCpUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,165 @@
package com.ruoyi.common.utils;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import java.io.*;
import java.net.MalformedURLException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.List;
/**
 * @Author: chenxiangfeng
 * @Date: 2021/7/20 10:35
 */
public class WxCpUtils {
    public static final String CORP_ID = "wwa423654b975441ac";
    public static final String CORP_SECRET = "snXq8qwA5tGu0YN1PlSDQqr6u9x3A0c_jQDmt8CN8Vs";
    public static final Integer AGENT_ID = 1000515;
    /**
     * @param user      ä¾‹ï¼šZT-033268|ZT-028629,多个中间用|隔开
     * @param content   ä¼ æ–‡æœ¬å†…容
     * @param imageFile å›¾ç‰‡
     * @throws Exception
     */
    public static void inform(String user, String content, File imageFile) throws Exception {
        WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
        // æ³¨å†Œçš„企业信息
        config.setCorpId(CORP_ID);
        config.setCorpSecret(CORP_SECRET);
        WxCpServiceImpl wxCpService = new WxCpServiceImpl();
        wxCpService.setWxCpConfigStorage(config);
        WxCpMessage message;
        WxCpMessageSendResult result;
        // å‘送文本
        if (StringUtils.isNotBlank(content)) {
            message = WxCpMessage.TEXT()
                    .content(content)
                    // ç”¨æˆ·id
                    .toUser(user)
                    // åº”用id
                    .agentId(AGENT_ID)
                    .build();
            result = wxCpService.getMessageService().send(message);
        }
        // å‘送文件
        if (imageFile != null) {
            // èŽ·å–æ–‡ä»¶id
            WxMediaUploadResult imgResult = wxCpService.getMediaService().upload("file", imageFile);
            message = WxCpMessage.IMAGE()
                    .mediaId(imgResult.getMediaId())
                    // ç”¨æˆ·id
                    .toUser(user)
                    // åº”用id
                    .agentId(AGENT_ID)
                    .build();
            result = wxCpService.getMessageService().send(message);
        }
    }
    /**
     * æŽ¨é€ç¾¤æ¶ˆæ¯
     *
     * @param webHookList ä¼ä¸šå¾®ä¿¡æœºå™¨äººåœ°å€
     * @param file        å›¾ç‰‡
     * @throws Exception
     */
    public static void informWebHook(List<String> webHookList, File file) throws Exception {
        JSONObject json = new JSONObject();
        json.putOpt("msgtype", "image");
        JSONObject image = new JSONObject();
        image.putOpt("base64", getBase64(file));
        image.putOpt("md5", getMd5(file));
        json.putOpt("image", image);
        webHookList.stream().forEach(webHook -> {
            String result = HttpRequest.post(webHook)
                    .header("Content-Type", "application/json")
                    .body(json.toString())
                    .execute().body();
        });
    }
    /**
     * æŽ¨é€ç¾¤æ¶ˆæ¯
     *
     * @param webHook ä¼ä¸šå¾®ä¿¡æœºå™¨äººåœ°å€
     * @param content æ•°æ®
     * @throws Exception
     */
    public static String informWebHook(String webHook, String content) {
        return informWebHook(webHook, content,"text");
    }
    /**
     * æŽ¨é€ç¾¤æ¶ˆæ¯
     *
     * @param webHook ä¼ä¸šå¾®ä¿¡æœºå™¨äººåœ°å€
     * @param content æ•°æ®
     * @param msgType æ¶ˆæ¯ç±»åž‹
     * @throws Exception
     */
    public static String informWebHook(String webHook, String content,String msgType) {
        JSONObject jsonObject = new JSONObject()
                .accumulate("msgtype", msgType)
                .accumulate(msgType, new JSONObject()
                        .accumulate("content", content));
        return HttpRequest.post(webHook).header("Content-Type", "application/json").body(jsonObject.toString()).execute().body();
    }
    public static String getMd5(File file) {
        String name = "";
        try {
            InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
            byte[] bytes = new byte[1024];
            int len = 0;
            MessageDigest messagedigest = MessageDigest.getInstance("MD5");
            while ((len = inputStream.read(bytes)) > 0) {
                messagedigest.update(bytes, 0, len);
            }
            name = Md5Util.bufferToHex(messagedigest.digest());
            inputStream.close();
        } catch (MalformedURLException e) {
        } catch (IOException e) {
        } catch (NoSuchAlgorithmException e) {
        }
        return name;
    }
    public static String getBase64(File file) {
        FileInputStream inputStream = null;
        String base64Str = "";
        try {
            inputStream = new FileInputStream(file);
            Base64.Encoder encoder = Base64.getEncoder();
            int available = inputStream.available();
            byte[] bytes = new byte[available];
            inputStream.read(bytes);
            base64Str = encoder.encodeToString(bytes);
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return base64Str;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/api/IfsApiUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,161 @@
package com.ruoyi.common.utils.api;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.domain.Result;
import com.ruoyi.common.config.IfsProperties;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
 * @Author zhuo
 * @Date 2024/9/29
 */
@Slf4j
@AllArgsConstructor
@Component
public class IfsApiUtils {
    private IfsProperties ifsProperties;
    /**
     * æŸ¥è¯¢é‡‡è´­è®¢å•未检验
     */
    public List<Map<String, Object>> getInventory(String inAttr) {
        if (isDisabled()) {
            return java.util.Collections.emptyList();
        }
        String procedureName = "QUERY_POL_RECEIPT_STD";
        JSONObject stockMap = getJsonObject(procedureName, inAttr);
        String body = "";
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map map = objectMapper.readValue(body, Map.class);
            List<Map<String, Object>> maps = objectMapper.readValue(JSONUtil.toJsonStr(map.get("LIST_INFO")), new TypeReference<List<Map<String, Object>>>() {
            });
            log.info("获取采购订单-->>" + maps);
            return maps;
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    /**
     * ç™»è®°é‡‡è´­æ£€éªŒç»“æžœSTD
     */
    public Result getProcurementResults(String inAttr) {
        return getResult("REGIST_INSPECTION_RESULTS_STD", inAttr, ifsProperties.getCustorder(), "登记采购检验结果-->");
    }
    /**
     * åŽŸææ–™æ£€éªŒ-检验后移库
     *
     * @param inAttr
     * @return
     */
    public Result moveReceipt(String inAttr) {
        return getResult("MOVE_RECEIPT_STD", inAttr, ifsProperties.getCustorder(), "检验后移库-->");
    }
    /**
     * åŽŸææ–™æ£€éªŒ-采购接收更改批号
     *
     * @param inAttr
     * @return
     */
    public Result updateMoveReceiptLot(String inAttr) {
        return getResult("MODIFY_PURCH_RECEIPT_LOT_STD", inAttr, ifsProperties.getCustorder(), "修改采购订单批次号-->");
    }
    /**
     * åº“存物料批次属性新增修改接口
     *
     * @param inAttr
     * @return
     */
    public Result importPartLotAttr(String inAttr) {
        return getResult("IMPORT_PART_LOT_ATTR_STD", inAttr, ifsProperties.getCustorder(), "库存物料批次属性新增修改接口-->");
    }
    /**
     * æŸ¥è¯¢åº“存数据
     *
     * @param inAttr
     * @return
     */
    public Result getIfsStock(String inAttr) {
        if (isDisabled()) {
            return Result.success(java.util.Collections.singletonMap("LIST_INFO", java.util.Collections.emptyList()));
        }
        return getResult("QUERY_INVENTORY_INFO_STD", inAttr, ifsProperties.getCustorderPort(), "查询库存信息-->");
    }
    /**
     * é€šç”¨æŽ¥å£
     * @param procedureName æ–¹æ³•名
     * @param inAttr  ä¼ å‚
     * @param url åœ°å€
     * @param image æ¶ˆæ¯
     * @return
     */
    private Result<?> getResult(String procedureName, String inAttr, String url, String image) {
        if (isDisabled()) {
            return Result.success();
        }
        JSONObject stockMap = new JSONObject();
        stockMap.put("procedureName", procedureName);
        stockMap.put("contract", ifsProperties.getContract());
        stockMap.put("contractKey", ifsProperties.getContractKeyPost());
        stockMap.put("userId", "lims_user");
        stockMap.put("inAttr", inAttr);
        String body = "";
        log.info(image + body);
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            Map map = objectMapper.readValue(body, Map.class);
            String successFlag = map.get("SuccessFlag").toString();
            if (Integer.valueOf(successFlag) == 1) {
                return Result.success(map);
            } else {
                return Result.fail(map.get("ErrorMsg").toString());
            }
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            return Result.fail(e.getMessage());
        }
    }
    /**
     * èŽ·å–æ·»åŠ è¯·æ±‚ä¿¡æ¯
     * @param procedureName      ç»“构名称
     * @param inAttr             è¯·æ±‚参数
     * @return
     */
    private JSONObject getJsonObject(String procedureName, String inAttr) {
        JSONObject stockMap = new JSONObject();
        stockMap.put("procedureName", procedureName);
        stockMap.put("contract", ifsProperties.getContract());
        stockMap.put("contractKey", ifsProperties.getContractKeyPost());
        stockMap.put("userId", "lims_user");
        stockMap.put("inAttr", inAttr);
        return stockMap;
    }
    private boolean isDisabled() {
        return true;
    }
}
ruoyi-common/src/main/java/com/ruoyi/common/utils/http/ParameterEscaperUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,92 @@
package com.ruoyi.common.utils.http;
import java.util.HashMap;
import java.util.Map;
/**
 * è¯·æ±‚参数特殊字符转义工具类
 * ç”¨äºŽå¤„理HTTP请求参数中的特殊字符,防止XSS攻击和参数解析错误
 */
public class ParameterEscaperUtil {
    // ç‰¹æ®Šå­—符转义映射表
    private static final Map<Character, String> ESCAPE_MAP;
    // è½¬ä¹‰å­—符反转映射表
    private static final Map<String, Character> UNESCAPE_MAP;
    static {
        // åˆå§‹åŒ–转义映射
        ESCAPE_MAP = new HashMap<>();
        ESCAPE_MAP.put('&', "&amp;");
        ESCAPE_MAP.put('<', "&lt;");
        ESCAPE_MAP.put('>', "&gt;");
        ESCAPE_MAP.put('"', "&quot;");
        ESCAPE_MAP.put('\'', "&#39;");
        ESCAPE_MAP.put('/', "&#47;");
        ESCAPE_MAP.put('\\', "&#92;");
        ESCAPE_MAP.put(' ', "%20");
        ESCAPE_MAP.put('?', "%3F");
        ESCAPE_MAP.put('=', "%3D");
        ESCAPE_MAP.put('+', "%2B");
        ESCAPE_MAP.put('%', "%25");
        ESCAPE_MAP.put('#', "%23");
        ESCAPE_MAP.put(':', "%3A");
        ESCAPE_MAP.put(';', "%3B");
        // åˆå§‹åŒ–反转义映射
        UNESCAPE_MAP = new HashMap<>();
        for (Map.Entry<Character, String> entry : ESCAPE_MAP.entrySet()) {
            UNESCAPE_MAP.put(entry.getValue(), entry.getKey());
        }
    }
    /**
     * è½¬ä¹‰è¯·æ±‚参数中的特殊字符
     * @param input åŽŸå§‹è¾“å…¥å­—ç¬¦ä¸²
     * @return è½¬ä¹‰åŽçš„字符串
     */
    public static String escape(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        StringBuilder sb = new StringBuilder();
        for (char c : input.toCharArray()) {
            // å¦‚果是需要转义的字符,则使用转义后的字符串,否则直接添加
            String escaped = ESCAPE_MAP.get(c);
            sb.append(escaped != null ? escaped : c);
        }
        return sb.toString();
    }
    /**
     * åè½¬ä¹‰è¯·æ±‚参数中的特殊字符
     * @param input è½¬ä¹‰åŽçš„字符串
     * @return åŽŸå§‹å­—ç¬¦ä¸²
     */
    public static String unescape(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        StringBuilder sb = new StringBuilder();
        int i = 0;
        while (i < input.length()) {
            boolean found = false;
            // æ£€æŸ¥æ˜¯å¦æ˜¯è½¬ä¹‰åºåˆ—
            for (String escapeSeq : UNESCAPE_MAP.keySet()) {
                if (input.startsWith(escapeSeq, i)) {
                    sb.append(UNESCAPE_MAP.get(escapeSeq));
                    i += escapeSeq.length();
                    found = true;
                    break;
                }
            }
            if (!found) {
                sb.append(input.charAt(i));
                i++;
            }
        }
        return sb.toString();
    }
}
ruoyi-common/src/main/resources/ttf/signature.ttf
Binary files differ
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/SysRoleVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package com.ruoyi.system.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
 * @Author zhuo
 * @Date 2025/2/20
 */
@Data
public class SysRoleVo {
    @Schema(description = "权限标识")
    private String perms;
    @Schema(description = "菜单名称")
    private String menuName;
    @Schema(description = "是否仅看我, 0: å¦, 1:是")
    private Integer isRersonal;
}
ruoyi-system/src/main/java/com/ruoyi/system/domain/vo/UserVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.ruoyi.system.domain.vo;
import com.ruoyi.common.core.domain.entity.User;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
public class UserVo extends User {
    @Schema(description = "部门id")
    private Long departId;
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/CustomMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ruoyi.common.core.domain.entity.Custom;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Mapper
public interface CustomMapper extends BaseMapper<Custom> {
    IPage<Custom> selectCustomPageList(IPage<Custom> page, @Param("ew") QueryWrapper<Custom> ew);
    int delCustomById(Integer id);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/DepartmentLimsMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.common.core.domain.entity.DepartmentDto;
import com.ruoyi.common.core.domain.entity.DepartmentLims;
import java.util.List;
/**
* @author z1292
* @description é’ˆå¯¹è¡¨ã€department_lims(部门明细)】的数据库操作Mapper
* @createDate 2024-05-22 14:08:17
* @Entity com.yuanchu.mom.pojo.DepartmentLims
*/
public interface DepartmentLimsMapper extends BaseMapper<DepartmentLims> {
    //获取部门树
    List<DepartmentDto> selectDepartment();
    //根据部门id,查询他的所有子类id
    List<Integer> selectSonById(Integer id);
}
ruoyi-system/src/main/java/com/ruoyi/system/mapper/InformationNotificationMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,31 @@
package com.ruoyi.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.core.domain.entity.InformationNotificationDto;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * æ¶ˆæ¯é€šçŸ¥ Mapper æŽ¥å£
 * </p>
 *
 * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
 * @since 2024-04-23 02:14:30
 */
public interface InformationNotificationMapper extends BaseMapper<InformationNotification> {
    IPage<InformationNotificationDto> getPage(Page page, String messageType, Integer userId);
    /**
     * æ¶ˆæ¯é€šçŸ¥-滚动查询
     *
     * @param userId
     * @return
     */
    IPage<InformationNotificationDto> msgRoll(Page page,@Param("userId") Integer userId);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/CustomService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.ruoyi.system.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.entity.Custom;
import java.util.List;
import java.util.Map;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€user(用户id)】的数据库操作Service
* @createDate 2024å¹´3月7日09:21:59
*/
public interface CustomService extends IService<Custom> {
    IPage<Custom> selectCustomPageList(IPage<Custom> page, Custom custom);
    int delCustomById(Long id);
    int addCustom(Custom custom);
    int upCustom(Custom custom);
    List<Custom> selectCustomEnum();
    Custom getCustomId(String company);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/InformationNotificationService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.ruoyi.system.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.core.domain.entity.InformationNotificationDto;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * æ¶ˆæ¯é€šçŸ¥ æœåŠ¡ç±»
 * </p>
 *
 * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
 * @since 2024-04-23 02:14:30
 */
public interface InformationNotificationService extends IService<InformationNotification> {
    IPage<InformationNotificationDto> getPage(Page page, String messageType);
    void markAllInformationReadOrDeleteAllReadMessages(Boolean isMarkAllInformationRead);
    Boolean checkForUnreadData();
    void triggerModificationStatusToRead(Integer id);
    int addInformationNotification(InformationNotification informationNotification);
    Map<String, Object> getNumberFourTypesMessagesHomePage();
    /**
     * æ¶ˆæ¯é€šçŸ¥-滚动查询
     *
     * @return
     */
    IPage<InformationNotificationDto> msgRoll(Page page);
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/CustomServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,62 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.Custom;
import com.ruoyi.common.utils.QueryWrappers;
import com.ruoyi.system.mapper.CustomMapper;
import com.ruoyi.system.service.CustomService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Administrator
* @description é’ˆå¯¹è¡¨ã€power(用户id)】的数据库操作Service实现
* @createDate 2023-12-27 02:37:38
*/
@Service
@AllArgsConstructor
public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom>
    implements CustomService {
    private CustomMapper customMapper;
    @Override
    public IPage<Custom> selectCustomPageList(IPage<Custom> page, Custom custom) {
        return customMapper.selectCustomPageList(page, QueryWrappers.queryWrappers(custom));
    }
    @Override
    public int delCustomById(Long id) {
        return customMapper.deleteById(id);
    }
    @Override
    public int addCustom(Custom custom) {
        return customMapper.insert(custom);
    }
    @Override
    public int upCustom(Custom custom) {
        return customMapper.updateById(custom);
    }
    @Override
    public List<Custom> selectCustomEnum() {
        return customMapper.selectList(Wrappers.<Custom>lambdaQuery().select(Custom::getId,Custom::getCompany));
    }
    @Override
    public Custom getCustomId(String company) {
        return customMapper.selectOne(Wrappers.<Custom>lambdaQuery().eq(Custom::getCompany, company).last("limit 1"));
    }
}
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/InformationNotificationServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,109 @@
package com.ruoyi.system.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.InformationNotification;
import com.ruoyi.common.core.domain.entity.InformationNotificationDto;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.InformationNotificationMapper;
import com.ruoyi.system.service.InformationNotificationService;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import java.time.LocalDate;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * æ¶ˆæ¯é€šçŸ¥ æœåŠ¡å®žçŽ°ç±»
 * </p>
 *
 * @author æ±Ÿè‹éµ·é›ç½‘络科技有限公司
 * @since 2024-04-23 02:14:30
 */
@Service
public class InformationNotificationServiceImpl extends ServiceImpl<InformationNotificationMapper, InformationNotification> implements InformationNotificationService {
    @Override
    public IPage<InformationNotificationDto> getPage(Page page, String messageType) {
        return baseMapper.getPage(page, messageType, SecurityUtils.getUserId().intValue());
    }
    @Override
    public void markAllInformationReadOrDeleteAllReadMessages(Boolean isMarkAllInformationRead) {
        if (isMarkAllInformationRead) {
            baseMapper.update(new InformationNotification(), Wrappers.<InformationNotification>lambdaUpdate()
                    .set(InformationNotification::getViewStatus, true)
                    .eq(InformationNotification::getConsigneeId, SecurityUtils.getUserId().intValue()));
        } else {
            baseMapper.delete(Wrappers.<InformationNotification>lambdaUpdate()
                    .eq(InformationNotification::getConsigneeId, SecurityUtils.getUserId().intValue())
                    .eq(InformationNotification::getViewStatus, true));
        }
    }
    @Override
    public Boolean checkForUnreadData() {
        Map<String, Integer> map1 = null;
        try {
            List<InformationNotification> informationNotifications = baseMapper.selectList(
                    Wrappers.<InformationNotification>lambdaQuery()
                            .eq(InformationNotification::getConsigneeId, SecurityUtils.getUserId().intValue())
                            .eq(InformationNotification::getViewStatus, false)
                            .last("limit 1"));
            return !informationNotifications.isEmpty();
        } catch (Exception e) {
        }
        return false;
    }
    @Override
    public void triggerModificationStatusToRead(Integer id) {
        baseMapper.update(new InformationNotification(), Wrappers.<InformationNotification>lambdaUpdate()
                .eq(InformationNotification::getId, id)
                .set(InformationNotification::getViewStatus, true));
    }
    @Override
    public int addInformationNotification(InformationNotification informationNotification) {
        informationNotification.setViewStatus(false);
        return baseMapper.insert(informationNotification);
    }
    @Override
    public Map<String, Object> getNumberFourTypesMessagesHomePage() {
        Map<String, Object> map = new HashMap<>();
        int userId = SecurityUtils.getUserId().intValue();
        Long totalNumberOfMessages = baseMapper.selectCount(Wrappers.<InformationNotification>lambdaQuery()
                .eq(InformationNotification::getConsigneeId, userId));
        Long totalNumberOfReadMessages = baseMapper.selectCount(Wrappers.<InformationNotification>lambdaQuery()
                .eq(InformationNotification::getConsigneeId, userId)
                .eq(InformationNotification::getViewStatus, true));
        LocalDate today = LocalDate.now();
        LocalDate sevenDaysAgo = today.minusDays(7);
        Long totalNumberOfMessagesInThePastSevenDays = baseMapper.selectCount(Wrappers.<InformationNotification>lambdaQuery()
                .eq(InformationNotification::getConsigneeId, userId)
                .between(InformationNotification::getCreateTime, today, sevenDaysAgo));
        long remainingToDo = totalNumberOfMessages - totalNumberOfReadMessages;
        map.put("totalNumberOfMessages", totalNumberOfMessages);
        map.put("remainingToDo", remainingToDo);
        map.put("totalNumberOfReadMessages", totalNumberOfReadMessages);
        map.put("totalNumberOfMessagesInThePastSevenDays", totalNumberOfMessagesInThePastSevenDays);
        return map;
    }
    /**
     * æ¶ˆæ¯é€šçŸ¥-滚动查询
     *
     * @return
     */
    @Override
    public IPage<InformationNotificationDto> msgRoll(Page page) {
        return baseMapper.msgRoll(page,SecurityUtils.getUserId().intValue());
    }
}
ruoyi-system/src/main/resources/mapper/system/CustomMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.ruoyi.system.mapper.CustomMapper">
    <update id="delCustomById">
        update user set is_custom = 0
        where id = #{id}
    </update>
    <select id="selectCustomPageList" resultType="com.ruoyi.common.core.domain.entity.Custom">
        select * from custom
        <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
            ${ew.customSqlSegment}
        </if>
    </select>
</mapper>
ruoyi-system/src/main/resources/mapper/system/DepartmentLimsMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.DepartmentLimsMapper">
    <select id="selectDepartment" resultType="com.ruoyi.common.core.domain.entity.DepartmentDto">
        SELECT id, name, father_id
        FROM department_lims
    </select>
    <select id="selectSonById" resultType="java.lang.Integer">
        SELECT au.id
        FROM (SELECT * FROM department_lims WHERE father_id IS NOT NULL) au,
             (SELECT @father_id := #{id}) pd
        WHERE FIND_IN_SET(father_id, @father_id) > 0
                  AND @father_id := concat(@father_id, ',', id)
        UNION
        SELECT id
        FROM department_lims
        WHERE id = #{id}
        ORDER BY id
    </select>
</mapper>
ruoyi-system/src/main/resources/mapper/system/InformationNotificationMapper.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.system.mapper.InformationNotificationMapper">
    <select id="getPage" resultType="com.ruoyi.common.core.domain.entity.InformationNotificationDto">
        select i.*, u.name senderUser, u2.name consigneeUser
        from information_notification i
                 left join user u on i.sender_id = u.id
                 left join user u2 on u2.id = i.consignee_id
        where i.consignee_id = #{userId}
        <if test="messageType != '' and messageType != null">
            and i.message_type = #{messageType}
        </if>
        order by i.create_time desc
    </select>
    <select id="msgRoll" resultType="com.ruoyi.common.core.domain.entity.InformationNotificationDto">
        select i.*, u.name senderUser, u2.name consigneeUser
        from information_notification i
        left join user u on i.sender_id = u.id
        left join user u2 on u2.id = i.consignee_id
        where i.consignee_id = #{userId}
        and i.view_status = false
        order by i.create_time desc
    </select>
</mapper>