办学质量监测教学评价系统
ageer
2025-04-14 731352fd04a6e8b483a8490fe1a833439302591c
pom.xml
@@ -14,26 +14,26 @@
    <properties>
        <revision>1.0.0</revision>
        <spring-boot.version>3.0.6</spring-boot.version>
        <spring-boot.version>3.4.4</spring-boot.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>17</java.version>
        <mysql.version>8.0.33</mysql.version>
        <spring-boot.mybatis>3.0.1</spring-boot.mybatis>
        <mybatis.version>3.5.16</mybatis.version>
        <springdoc.version>2.1.0</springdoc.version>
        <therapi-javadoc.version>0.15.0</therapi-javadoc.version>
        <poi.version>5.2.3</poi.version>
        <easyexcel.version>3.2.1</easyexcel.version>
        <velocity.version>2.3</velocity.version>
        <satoken.version>1.34.0</satoken.version>
        <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
        <mybatis-plus.version>3.5.11</mybatis-plus.version>
        <p6spy.version>3.9.1</p6spy.version>
        <hutool.version>5.8.18</hutool.version>
        <hutool.version>5.8.35</hutool.version>
        <okhttp.version>4.10.0</okhttp.version>
        <dynamic-ds.version>4.3.1</dynamic-ds.version>
        <spring-boot-admin.version>3.0.3</spring-boot-admin.version>
        <redisson.version>3.20.1</redisson.version>
        <lock4j.version>2.2.4</lock4j.version>
        <dynamic-ds.version>3.6.1</dynamic-ds.version>
        <alibaba-ttl.version>2.14.2</alibaba-ttl.version>
        <xxl-job.version>2.4.0</xxl-job.version>
        <mapstruct-plus.version>1.2.1</mapstruct-plus.version>
@@ -42,10 +42,6 @@
        <bouncycastle.version>1.72</bouncycastle.version>
        <!-- ç¦»çº¿IP地址定位库 -->
        <ip2region.version>2.7.0</ip2region.version>
        <!-- ä¸´æ—¶ä¿®å¤ snakeyaml æ¼æ´ž -->
        <snakeyaml.version>1.33</snakeyaml.version>
        <!-- OSS é…ç½® -->
        <aws-java-sdk-s3.version>1.12.400</aws-java-sdk-s3.version>
        <!-- SMS é…ç½® -->
@@ -202,22 +198,22 @@
                <version>${satoken.version}</version>
            </dependency>
            <!-- dynamic-datasource å¤šæ•°æ®æº-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
                <version>${dynamic-ds.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${spring-boot.mybatis}</version>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-jsqlparser</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
@@ -225,6 +221,13 @@
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-annotation</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <!-- dynamic-datasource å¤šæ•°æ®æº-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
                <version>${dynamic-ds.version}</version>
            </dependency>
            <!-- sql性能分析插件 -->
@@ -275,13 +278,6 @@
                <groupId>com.alibaba</groupId>
                <artifactId>transmittable-thread-local</artifactId>
                <version>${alibaba-ttl.version}</version>
            </dependency>
            <!-- ä¸´æ—¶ä¿®å¤ snakeyaml æ¼æ´ž -->
            <dependency>
                <groupId>org.yaml</groupId>
                <artifactId>snakeyaml</artifactId>
                <version>${snakeyaml.version}</version>
            </dependency>
            <!-- åŠ å¯†åŒ…å¼•å…¥ -->
@@ -341,11 +337,11 @@
                <version>${revision}</version>
            </dependency>
            <dependency>
                <groupId>org.ruoyi</groupId>
                <artifactId>ruoyi-demo</artifactId>
                <version>${revision}</version>
            </dependency>
<!--            <dependency>-->
<!--                <groupId>org.ruoyi</groupId>-->
<!--                <artifactId>ruoyi-demo</artifactId>-->
<!--                <version>${revision}</version>-->
<!--            </dependency>-->
        </dependencies>
    </dependencyManagement>
@@ -354,7 +350,8 @@
        <module>ruoyi-common</module>
        <module>ruoyi-modules</module>
        <module>ruoyi-modules-api</module>
        <module>ruoyi-modules/ruoyi-mcp-server</module>
        <module>ruoyi-admin</module>
        <module>ruoyi-extend</module>
    </modules>
    <packaging>pom</packaging>
ruoyi-admin/pom.xml
@@ -42,10 +42,11 @@
            <artifactId>mssql-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-common-doc</artifactId>
        </dependency>
        <!--  demo模块  -->
<!--        <dependency>-->
<!--            <groupId>org.ruoyi</groupId>-->
<!--            <artifactId>ruoyi-demo</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.ruoyi</groupId>
@@ -54,38 +55,7 @@
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-fusion</artifactId>
        </dependency>
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-knowledge</artifactId>
        </dependency>
        <!--  demo模块  -->
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-demo</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- æ·»åŠ thumbnailator依赖 -->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.11</version>
        </dependency>
        <dependency>
            <groupId>io.github.ollama4j</groupId>
            <artifactId>ollama4j</artifactId>
            <version>1.0.79</version>
            <scope>compile</scope>
            <artifactId>ruoyi-chat</artifactId>
        </dependency>
    </dependencies>
ruoyi-admin/src/main/java/org/ruoyi/controller/AuthController.java
@@ -14,18 +14,17 @@
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.common.tenant.helper.TenantHelper;
import org.ruoyi.system.domain.bo.SysTenantBo;
import org.ruoyi.system.domain.vo.LoginTenantVo;
import org.ruoyi.system.domain.vo.SysTenantVo;
import org.ruoyi.system.domain.vo.TenantListVo;
import org.ruoyi.system.service.ISysTenantService;
import org.ruoyi.system.service.SysLoginService;
import org.ruoyi.system.service.SysRegisterService;
import org.ruoyi.system.domain.vo.LoginVo;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.ruoyi.system.domain.bo.SysTenantBo;
import org.ruoyi.system.domain.vo.LoginTenantVo;
import org.ruoyi.system.domain.vo.LoginVo;
import org.ruoyi.system.domain.vo.SysTenantVo;
import org.ruoyi.system.domain.vo.TenantListVo;
import org.ruoyi.system.service.ISysTenantService;
import org.ruoyi.system.service.SysLoginService;
import org.ruoyi.system.service.SysRegisterService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
ruoyi-admin/src/main/java/org/ruoyi/controller/IndexController.java
@@ -4,6 +4,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * é¦–页
@@ -11,8 +12,7 @@
 * @author Lion Li
 */
@SaIgnore
@RequiredArgsConstructor
@Controller
@RestController
public class IndexController {
    /**
@@ -20,17 +20,9 @@
     */
    @GetMapping("/")
    public String index() {
        return "index.html";
        return "RuoYi AI启动成功!";
    }
    @GetMapping("/success")
    public String success(){
        return "paySuccess.html";
    }
    @GetMapping("/cancel")
    public String cancel(){
        return "cancel";
    }
}
ruoyi-admin/src/main/resources/application-dev.yml
@@ -60,9 +60,6 @@
    # password: 123456
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10S
    # æ˜¯å¦å¼€å¯ssl
    ssl: false
redisson:
  # redis key前缀
  keyPrefix:
@@ -97,22 +94,3 @@
  # è…¾è®¯ä¸“用
  sdkAppId:
spring:
  ai:
    openai:
      api-key: sk-xX
      base-url: https://api.pandarobot.chat
    ollama:
      base-url: http://localhost:11434
      init:
        pull-model-strategy: always
        timeout: 60s
        max-retries: 1
    mcp:
      client:
        enabled: true
        name: call-mcp-server
        sse:
          connections:
            server1:
              url: http://127.0.0.1:8080
ruoyi-admin/src/main/resources/application.yml
@@ -49,8 +49,10 @@
# æ—¥å¿—配置
logging:
  level:
    org.ruoyi: @logging.level@
    org.dromara: @logging.level@
    org.springframework: warn
    org.mybatis.spring.mapper: error
    org.apache.fury: warn
  config: classpath:logback-plus.xml
# ç”¨æˆ·é…ç½®
@@ -318,5 +320,16 @@
        token:   ''
        aesKey: ''
spring:
  ai:
    ollama:
      base-url: http://localhost:11434
    mcp:
      client:
        enabled: true
        name: call-mcp-server
        sse:
          connections:
            server1:
              url: http://127.0.0.1:6040
ruoyi-admin/src/main/resources/static/.gitignore
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/.nojekyll
ruoyi-admin/src/main/resources/static/CNAME
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/README.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/_coverpage.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/_footer.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/_navbar.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/_sidebar.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/add_group.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/blacklist.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/column.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/contribution.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/demo_system.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/pr.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/user_register.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/common/video.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/index.html
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/_sidebar.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/common_func.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/component_use.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/content_copy.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/dev_norm.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/dict_use.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/exception_handling.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/icon_use.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/page_cache.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/param_use.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/permissions_use.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/request_process.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/devdoc/router_use.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/plus-ui/home.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/_sidebar.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/api_encrypt.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/bean_null.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/deploy_vue.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/domestic_databases.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/dubbo_ip.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/https_config.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/identify_fail.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/import_excel.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/jar_run_fail.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/jce_cannot.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/kinfe4j.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/login_step.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/lombok.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/nacos_naming_instance_metadata.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/nacos_read_fail.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/only_one_subscriber.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/parse_exception.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/permission_denied.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/read_metadata.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/sentinel_404.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/st_not_support.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/swagger.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/synchronous_update.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/use_druid.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/questions/use_tomcat.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/_sidebar.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/changlog.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/elk.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/es.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/kafka.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/maxkey.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/nacos.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/prometheus_grafana.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/rabbitmq.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/rocketmq.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/shardingproxy.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/extend-function/skywalking.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/architecture_diagram.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/collaboration.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/doc.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/i18n.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/inner_authentication.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/new_module.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/update_package_name.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/association/update_url.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/client.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/code_generate.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/export.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/import.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/oss.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/page.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/param_check.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/permissions.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/permissions_control.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/router_release.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/social.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/tenant.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/basic/user.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/explain/about_join.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/explain/key.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/explain/test.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/explain/transaction.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/api_encrypt.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/dynamic_datasource.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/encrypt.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/idempotent.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/mail.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/sensitive.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/sms.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/sse.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/translation.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/extend/websocket.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/framework/tree.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/home.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/1.Xinit.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/deploy.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/extend_project.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/idea_environment.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/power_job_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/snail_job_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-cloud-plus/quickstart/worker_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/_sidebar.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/changlog.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/architecture_diagram.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/association/doc.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/association/i18n.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/association/new_module.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/association/update_package_name.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/association/update_url.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/client.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/code_generate.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/export.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/import.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/interface_release.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/oss.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/page.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/param_check.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/permissions.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/permissions_control.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/social.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/tenant.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/basic/user.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/explain/about_join.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/explain/key.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/explain/test.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/explain/transaction.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/api_encrypt.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/dynamic_datasource.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/encrypt.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/idempotent.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/mail.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/maxkey.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/sensitive.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/skywalking.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/sms.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/sse.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/topiam.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/translation.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/extend/websocket.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/framework/tree.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/home.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/4.Xinit.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/5.Xnew.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/admin_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/deploy.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/extend_project.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/idea_environment.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/power_job_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/snail_job_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/worker_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/ruoyi-vue-plus/quickstart/xxl_job_init.md
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/css/vue.css
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/image/favicon.ico
Binary files differ
ruoyi-admin/src/main/resources/static/static/image/logo.png
Binary files differ
ruoyi-admin/src/main/resources/static/static/image/ruoyicloudplus.png
Binary files differ
ruoyi-admin/src/main/resources/static/static/image/ruoyivueplus.png
Binary files differ
ruoyi-admin/src/main/resources/static/static/js/docsify-copy-code.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/docsify-footer.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/docsify-pagination.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/docsify-scroll-to-top.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/docsify.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/emoji.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/prism-bash.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/prism-typescript.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/search.min.js
ÎļþÒÑɾ³ý
ruoyi-admin/src/main/resources/static/static/js/zoom-image.min.js
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-core/pom.xml
@@ -109,16 +109,19 @@
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>${okhttp.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp-sse</artifactId>
            <version>${okhttp.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>logging-interceptor</artifactId>
            <version>${okhttp.version}</version>
        </dependency>
    </dependencies>
ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/constant/RegexConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package org.ruoyi.common.core.constant;
import cn.hutool.core.lang.RegexPool;
/**
 * å¸¸ç”¨æ­£åˆ™è¡¨è¾¾å¼å­—符串
 * <p>
 * å¸¸ç”¨æ­£åˆ™è¡¨è¾¾å¼é›†åˆï¼Œæ›´å¤šæ­£åˆ™è§: https://any86.github.io/any-rule/
 *
 * @author Feng
 */
public interface RegexConstants extends RegexPool {
    /**
     * å­—典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
     */
    String DICTIONARY_TYPE = "^[a-z][a-z0-9_]*$";
    /**
     * æƒé™æ ‡è¯†å¿…须符合以下格式:
     * 1. æ ‡å‡†æ ¼å¼ï¼šxxx:yyy:zzz
     * - ç¬¬ä¸€éƒ¨åˆ†ï¼ˆxxx):只能包含字母、数字和下划线(_),不能使用 `*`
     * - ç¬¬äºŒéƒ¨åˆ†ï¼ˆyyy):可以包含字母、数字、下划线(_)和 `*`
     * - ç¬¬ä¸‰éƒ¨åˆ†ï¼ˆzzz):可以包含字母、数字、下划线(_)和 `*`
     * 2. å…è®¸ç©ºå­—符串(""),表示没有权限标识
     */
    String PERMISSION_STRING = "^$|^[a-zA-Z0-9_]+:[a-zA-Z0-9_*]+:[a-zA-Z0-9_*]+$";
    /**
     * èº«ä»½è¯å·ç ï¼ˆåŽ6位)
     */
    String ID_CARD_LAST_6 = "^(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$";
    /**
     * QQ号码
     */
    String QQ_NUMBER = "^[1-9][0-9]\\d{4,9}$";
    /**
     * é‚®æ”¿ç¼–码
     */
    String POSTAL_CODE = "^[1-9]\\d{5}$";
    /**
     * æ³¨å†Œè´¦å·
     */
    String ACCOUNT = "^[a-zA-Z][a-zA-Z0-9_]{4,15}$";
    /**
     * å¯†ç ï¼šåŒ…含至少8个字符,包括大写字母、小写字母、数字和特殊字符
     */
    String PASSWORD = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$";
    /**
     * é€šç”¨çŠ¶æ€ï¼ˆ0表示正常,1表示停用)
     */
    String STATUS = "^[01]$";
}
ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/constant/SystemConstants.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,80 @@
package org.ruoyi.common.core.constant;
/**
 * ç³»ç»Ÿå¸¸é‡ä¿¡æ¯
 *
 * @author Lion Li
 */
public interface SystemConstants {
    /**
     * æ­£å¸¸çŠ¶æ€
     */
    String NORMAL = "0";
    /**
     * å¼‚常状态
     */
    String DISABLE = "1";
    /**
     * æ˜¯å¦ä¸ºç³»ç»Ÿé»˜è®¤ï¼ˆæ˜¯ï¼‰
     */
    String YES = "Y";
    /**
     * æ˜¯å¦ä¸ºç³»ç»Ÿé»˜è®¤ï¼ˆå¦ï¼‰
     */
    String NO = "N";
    /**
     * æ˜¯å¦èœå•外链(是)
     */
    String YES_FRAME = "0";
    /**
     * æ˜¯å¦èœå•外链(否)
     */
    String NO_FRAME = "1";
    /**
     * èœå•类型(目录)
     */
    String TYPE_DIR = "M";
    /**
     * èœå•类型(菜单)
     */
    String TYPE_MENU = "C";
    /**
     * èœå•类型(按钮)
     */
    String TYPE_BUTTON = "F";
    /**
     * Layout组件标识
     */
    String LAYOUT = "Layout";
    /**
     * ParentView组件标识
     */
    String PARENT_VIEW = "ParentView";
    /**
     * InnerLink组件标识
     */
    String INNER_LINK = "InnerLink";
    /**
     * è¶…级管理员ID
     */
    Long SUPER_ADMIN_ID = 1L;
    /**
     * æ ¹éƒ¨é—¨ç¥–级列表
     */
    String ROOT_DEPT_ANCESTORS = "0";
}
ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/factory/RegexPatternPoolFactory.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package org.ruoyi.common.core.factory;
import cn.hutool.core.lang.PatternPool;
import org.ruoyi.common.core.constant.RegexConstants;
import java.util.regex.Pattern;
/**
 * æ­£åˆ™è¡¨è¾¾å¼æ¨¡å¼æ± å·¥åŽ‚
 * <p>初始化的时候将正则表达式加入缓存池当中</p>
 * <p>提高正则表达式的性能,避免重复编译相同的正则表达式</p>
 *
 * @author 21001
 */
public class RegexPatternPoolFactory extends PatternPool {
    /**
     * å­—典类型必须以字母开头,且只能为(小写字母,数字,下滑线)
     */
    public static final Pattern DICTIONARY_TYPE = get(RegexConstants.DICTIONARY_TYPE);
    /**
     * èº«ä»½è¯å·ç ï¼ˆåŽ6位)
     */
    public static final Pattern ID_CARD_LAST_6 = get(RegexConstants.ID_CARD_LAST_6);
    /**
     * QQ号码
     */
    public static final Pattern QQ_NUMBER = get(RegexConstants.QQ_NUMBER);
    /**
     * é‚®æ”¿ç¼–码
     */
    public static final Pattern POSTAL_CODE = get(RegexConstants.POSTAL_CODE);
    /**
     * æ³¨å†Œè´¦å·
     */
    public static final Pattern ACCOUNT = get(RegexConstants.ACCOUNT);
    /**
     * å¯†ç ï¼šåŒ…含至少8个字符,包括大写字母、小写字母、数字和特殊字符
     */
    public static final Pattern PASSWORD = get(RegexConstants.PASSWORD);
    /**
     * é€šç”¨çŠ¶æ€ï¼ˆ0表示正常,1表示停用)
     */
    public static final Pattern STATUS = get(RegexConstants.STATUS);
}
ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/factory/YmlPropertySourceFactory.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
package org.ruoyi.common.core.factory;
import org.ruoyi.common.core.utils.StringUtils;
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import java.io.IOException;
/**
 * yml é…ç½®æºå·¥åŽ‚
 *
 * @author Lion Li
 */
public class YmlPropertySourceFactory extends DefaultPropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        String sourceName = resource.getResource().getFilename();
        if (StringUtils.isNotBlank(sourceName) && StringUtils.endsWithAny(sourceName, ".yml", ".yaml")) {
            YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
            factory.setResources(resource.getResource());
            factory.afterPropertiesSet();
            return new PropertiesPropertySource(sourceName, factory.getObject());
        }
        return super.createPropertySource(name, resource);
    }
}
ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/ObjectUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,60 @@
package org.ruoyi.common.core.utils;
import cn.hutool.core.util.ObjectUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import java.util.function.Function;
/**
 * å¯¹è±¡å·¥å…·ç±»
 *
 * @author ç§‹è¾žæœªå¯’
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ObjectUtils extends ObjectUtil {
    /**
     * å¦‚果对象不为空,则获取对象中的某个字段 ObjectUtils.notNullGetter(user, User::getName);
     *
     * @param obj å¯¹è±¡
     * @param func èŽ·å–æ–¹æ³•
     * @return å¯¹è±¡å­—段
     */
    public static <T, E> E notNullGetter(T obj, Function<T, E> func) {
        if (isNotNull(obj) && isNotNull(func)) {
            return func.apply(obj);
        }
        return null;
    }
    /**
     * å¦‚果对象不为空,则获取对象中的某个字段,否则返回默认值
     *
     * @param obj          å¯¹è±¡
     * @param func         èŽ·å–æ–¹æ³•
     * @param defaultValue é»˜è®¤å€¼
     * @return å¯¹è±¡å­—段
     */
    public static <T, E> E notNullGetter(T obj, Function<T, E> func, E defaultValue) {
        if (isNotNull(obj) && isNotNull(func)) {
            return func.apply(obj);
        }
        return defaultValue;
    }
    /**
     * å¦‚果值不为空,则返回值,否则返回默认值
     *
     * @param obj          å¯¹è±¡
     * @param defaultValue é»˜è®¤å€¼
     * @return å¯¹è±¡å­—段
     */
    public static <T> T notNull(T obj, T defaultValue) {
        if (isNotNull(obj)) {
            return obj;
        }
        return defaultValue;
    }
}
ruoyi-common/ruoyi-common-core/src/main/java/org/ruoyi/common/core/utils/SpringUtils.java
@@ -1,9 +1,10 @@
package org.ruoyi.common.core.utils;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.thread.Threading;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
@@ -48,7 +49,7 @@
     */
    @SuppressWarnings("unchecked")
    public static <T> T getAopProxy(T invoker) {
        return (T) AopContext.currentProxy();
        return (T) getBean(invoker.getClass());
    }
@@ -59,4 +60,8 @@
        return getApplicationContext();
    }
    public static boolean isVirtual() {
        return Threading.VIRTUAL.isActive(getBean(Environment.class));
    }
}
ruoyi-common/ruoyi-common-encrypt/pom.xml
@@ -24,11 +24,6 @@
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15to18</artifactId>
        </dependency>
@@ -38,6 +33,23 @@
            <artifactId>hutool-crypto</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
            <optional>true</optional>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis-spring</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
ruoyi-common/ruoyi-common-live/pom.xml
@@ -33,7 +33,7 @@
        <brotli4j.version>1.13.0</brotli4j.version>
        <jackson-databind.version>2.16.0</jackson-databind.version>
        <hutool-all.version>5.8.24</hutool-all.version>
        <hutool-all.version>5.8.35</hutool-all.version>
        <netty-all.version>4.1.104.Final</netty-all.version>
        <logback-classic.version>1.4.12</logback-classic.version>
        <lombok.version>1.18.30</lombok.version>
ruoyi-common/ruoyi-common-mybatis/pom.xml
@@ -6,7 +6,6 @@
        <groupId>org.ruoyi</groupId>
        <artifactId>ruoyi-common</artifactId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <modelVersion>4.0.0</modelVersion>
@@ -30,12 +29,17 @@
        <!-- dynamic-datasource å¤šæ•°æ®æº-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-jsqlparser</artifactId>
        </dependency>
        <!-- sql性能分析插件 -->
ruoyi-common/ruoyi-common-mybatis/src/main/java/com/baomidou/dynamic/datasource/processor/jakarta/DsJakartaHeaderProcessor.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/com/baomidou/dynamic/datasource/processor/jakarta/DsJakartaSessionProcessor.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/annotation/DataColumn.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package org.ruoyi.annotation;
import java.lang.annotation.*;
/**
 * æ•°æ®æƒé™æ³¨è§£ï¼Œç”¨äºŽæ ‡è®°æ•°æ®æƒé™çš„占位符关键字和替换值
 * <p>
 * ä¸€ä¸ªæ³¨è§£åªèƒ½å¯¹åº”一个模板
 * </p>
 *
 * @author Lion Li
 * @version 3.5.0
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataColumn {
    /**
     * æ•°æ®æƒé™æ¨¡æ¿çš„占位符关键字,默认为 "deptName"
     *
     * @return å ä½ç¬¦å…³é”®å­—数组
     */
    String[] key() default "deptName";
    /**
     * æ•°æ®æƒé™æ¨¡æ¿çš„占位符替换值,默认为 "dept_id"
     *
     * @return å ä½ç¬¦æ›¿æ¢å€¼æ•°ç»„
     */
    String[] value() default "dept_id";
    /**
     * æƒé™æ ‡è¯†ç¬¦ ç”¨äºŽé€šè¿‡èœå•权限标识符来获取数据权限
     * æ‹¥æœ‰æ­¤æ ‡è¯†ç¬¦çš„角色 å°†ä¸ä¼šæ‹¼æŽ¥æ­¤è§’色的数据过滤sql
     *
     * @return æƒé™æ ‡è¯†ç¬¦
     */
    String permission() default "";
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/annotation/DataPermission.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package org.ruoyi.annotation;
import java.lang.annotation.*;
/**
 * æ•°æ®æƒé™ç»„注解,用于标记数据权限配置数组
 *
 * @author Lion Li
 * @version 3.5.0
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataPermission {
    /**
     * æ•°æ®æƒé™é…ç½®æ•°ç»„,用于指定数据权限的占位符关键字和替换值
     *
     * @return æ•°æ®æƒé™é…ç½®æ•°ç»„
     */
    DataColumn[] value();
    /**
     * æƒé™æ‹¼æŽ¥æ ‡è¯†ç¬¦(用于指定连接语句的sql符号)
     * å¦‚不填 é»˜è®¤ select ç”¨ OR å…¶ä»–语句用 AND
     * å†…容 OR æˆ–者 AND
     */
    String joinStr() default "";
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/aspect/DataPermissionAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,50 @@
package org.ruoyi.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.helper.DataPermissionHelper;
/**
 * æ•°æ®æƒé™å¤„理
 *
 * @author Lion Li
 */
@Slf4j
@Aspect
public class DataPermissionAspect {
    /**
     * å¤„理请求前执行
     */
    @Before(value = "@annotation(dataPermission)")
    public void doBefore(JoinPoint joinPoint, DataPermission dataPermission) {
        DataPermissionHelper.setPermission(dataPermission);
    }
    /**
     * å¤„理完请求后执行
     *
     * @param joinPoint åˆ‡ç‚¹
     */
    @AfterReturning(pointcut = "@annotation(dataPermission)")
    public void doAfterReturning(JoinPoint joinPoint, DataPermission dataPermission) {
        DataPermissionHelper.removePermission();
    }
    /**
     * æ‹¦æˆªå¼‚常操作
     *
     * @param joinPoint åˆ‡ç‚¹
     * @param e         å¼‚常
     */
    @AfterThrowing(value = "@annotation(dataPermission)", throwing = "e")
    public void doAfterThrowing(JoinPoint joinPoint, DataPermission dataPermission, Exception e) {
        DataPermissionHelper.removePermission();
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/annotation/DataColumn.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/annotation/DataPermission.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/config/MybatisPlusConfig.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/core/domain/BaseEntity.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/core/mapper/BaseMapperPlus.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/core/page/PageQuery.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/core/page/TableDataInfo.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/enums/DataBaseType.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/enums/DataScopeType.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/handler/InjectionMetaObjectHandler.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/handler/MybatisExceptionHandler.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/handler/PlusDataPermissionHandler.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/helper/DataBaseHelper.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/helper/DataPermissionHelper.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/interceptor/PlusDataPermissionInterceptor.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/jakarta/DsJakartaHeaderProcessor.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/common/mybatis/jakarta/DsJakartaSessionProcessor.java
ÎļþÒÑɾ³ý
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/config/MybatisPlusConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,138 @@
package org.ruoyi.config;
import cn.hutool.core.net.NetUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.handlers.PostInitTableInfoHandler;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import org.ruoyi.aspect.DataPermissionAspect;
import org.ruoyi.common.core.factory.YmlPropertySourceFactory;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.handler.InjectionMetaObjectHandler;
import org.ruoyi.handler.MybatisExceptionHandler;
import org.ruoyi.handler.PlusPostInitTableInfoHandler;
import org.ruoyi.interceptor.PlusDataPermissionInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.BeansException;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
 * mybatis-plus配置类(下方注释有插件介绍)
 *
 * @author Lion Li
 */
@EnableTransactionManagement(proxyTargetClass = true)
@MapperScan("${mybatis-plus.mapperPackage}")
@PropertySource(value = "classpath:common-mybatis.yml", factory = YmlPropertySourceFactory.class)
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // å¤šç§Ÿæˆ·æ’ä»¶ å¿…须放到第一位
        try {
            TenantLineInnerInterceptor tenant = SpringUtils.getBean(TenantLineInnerInterceptor.class);
            interceptor.addInnerInterceptor(tenant);
        } catch (BeansException ignore) {
        }
        // æ•°æ®æƒé™å¤„理
        interceptor.addInnerInterceptor(dataPermissionInterceptor());
        // åˆ†é¡µæ’ä»¶
        interceptor.addInnerInterceptor(paginationInnerInterceptor());
        // ä¹è§‚锁插件
        interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
        return interceptor;
    }
    /**
     * æ•°æ®æƒé™æ‹¦æˆªå™¨
     */
    public PlusDataPermissionInterceptor dataPermissionInterceptor() {
        return new PlusDataPermissionInterceptor(SpringUtils.getProperty("mybatis-plus.mapperPackage"));
    }
    /**
     * æ•°æ®æƒé™åˆ‡é¢å¤„理器
     */
    @Bean
    public DataPermissionAspect dataPermissionAspect() {
        return new DataPermissionAspect();
    }
    /**
     * åˆ†é¡µæ’件,自动识别数据库类型
     */
    public PaginationInnerInterceptor paginationInnerInterceptor() {
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
        // åˆ†é¡µåˆç†åŒ–
        paginationInnerInterceptor.setOverflow(true);
        return paginationInnerInterceptor;
    }
    /**
     * ä¹è§‚锁插件
     */
    public OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor() {
        return new OptimisticLockerInnerInterceptor();
    }
    /**
     * å…ƒå¯¹è±¡å­—段填充控制器
     */
    @Bean
    public MetaObjectHandler metaObjectHandler() {
        return new InjectionMetaObjectHandler();
    }
    /**
     * ä½¿ç”¨ç½‘卡信息绑定雪花生成器
     * é˜²æ­¢é›†ç¾¤é›ªèбID重复
     */
    @Bean
    public IdentifierGenerator idGenerator() {
        return new DefaultIdentifierGenerator(NetUtil.getLocalhost());
    }
    /**
     * å¼‚常处理器
     */
    @Bean
    public MybatisExceptionHandler mybatisExceptionHandler() {
        return new MybatisExceptionHandler();
    }
    /**
     * åˆå§‹åŒ–表对象处理器
     */
    @Bean
    public PostInitTableInfoHandler postInitTableInfoHandler() {
        return new PlusPostInitTableInfoHandler();
    }
    /**
     * PaginationInnerInterceptor åˆ†é¡µæ’件,自动识别数据库类型
     * https://baomidou.com/pages/97710a/
     * OptimisticLockerInnerInterceptor ä¹è§‚锁插件
     * https://baomidou.com/pages/0d93c0/
     * MetaObjectHandler å…ƒå¯¹è±¡å­—段填充控制器
     * https://baomidou.com/pages/4c6bcf/
     * ISqlInjector sql注入器
     * https://baomidou.com/pages/42ea4a/
     * BlockAttackInnerInterceptor å¦‚果是对全表的删除或更新操作,就会终止该操作
     * https://baomidou.com/pages/f9a237/
     * IllegalSQLInnerInterceptor sql性能规范插件(垃圾SQL拦截)
     * IdentifierGenerator è‡ªå®šä¹‰ä¸»é”®ç­–ç•¥
     * https://baomidou.com/pages/568eb2/
     * TenantLineInnerInterceptor å¤šç§Ÿæˆ·æ’ä»¶
     * https://baomidou.com/pages/aef2f2/
     * DynamicTableNameInnerInterceptor åŠ¨æ€è¡¨åæ’ä»¶
     * https://baomidou.com/pages/2a45ff/
     */
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/domain/BaseEntity.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
package org.ruoyi.core.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * Entity基类
 *
 * @author Lion Li
 */
@Data
public class BaseEntity implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     * æœç´¢å€¼
     */
    @JsonIgnore
    @TableField(exist = false)
    private String searchValue;
    /**
     * åˆ›å»ºéƒ¨é—¨
     */
    @TableField(fill = FieldFill.INSERT)
    private Long createDept;
    /**
     * åˆ›å»ºè€…
     */
    @TableField(fill = FieldFill.INSERT)
    private Long createBy;
    /**
     * åˆ›å»ºæ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;
    /**
     * æ›´æ–°è€…
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Long updateBy;
    /**
     * æ›´æ–°æ—¶é—´
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
    /**
     * è¯·æ±‚参数
     */
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @TableField(exist = false)
    private Map<String, Object> params = new HashMap<>();
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/mapper/BaseMapperPlus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,335 @@
package org.ruoyi.core.mapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.reflect.GenericTypeUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
/**
 * è‡ªå®šä¹‰ Mapper æŽ¥å£, å®žçް è‡ªå®šä¹‰æ‰©å±•
 *
 * @param <T> table æ³›åž‹
 * @param <V> vo æ³›åž‹
 * @author Lion Li
 * @since 2021-05-13
 */
@SuppressWarnings("unchecked")
public interface BaseMapperPlus<T, V> extends BaseMapper<T> {
    Log log = LogFactory.getLog(BaseMapperPlus.class);
    /**
     * èŽ·å–å½“å‰å®žä¾‹å¯¹è±¡å…³è”çš„æ³›åž‹ç±»åž‹ V çš„ Class å¯¹è±¡
     *
     * @return è¿”回当前实例对象关联的泛型类型 V çš„ Class å¯¹è±¡
     */
    default Class<V> currentVoClass() {
        return (Class<V>) GenericTypeUtils.resolveTypeArguments(this.getClass(), BaseMapperPlus.class)[1];
    }
    /**
     * èŽ·å–å½“å‰å®žä¾‹å¯¹è±¡å…³è”çš„æ³›åž‹ç±»åž‹ T çš„ Class å¯¹è±¡
     *
     * @return è¿”回当前实例对象关联的泛型类型 T çš„ Class å¯¹è±¡
     */
    default Class<T> currentModelClass() {
        return (Class<T>) GenericTypeUtils.resolveTypeArguments(this.getClass(), BaseMapperPlus.class)[0];
    }
    /**
     * ä½¿ç”¨é»˜è®¤çš„æŸ¥è¯¢æ¡ä»¶æŸ¥è¯¢å¹¶è¿”回结果列表
     *
     * @return è¿”回查询结果的列表
     */
    default List<T> selectList() {
        return this.selectList(new QueryWrapper<>());
    }
    /**
     * æ‰¹é‡æ’入实体对象集合
     *
     * @param entityList å®žä½“对象集合
     * @return æ’入操作是否成功的布尔值
     */
    default boolean insertBatch(Collection<T> entityList) {
        return Db.saveBatch(entityList);
    }
    /**
     * æ‰¹é‡æ ¹æ®ID更新实体对象集合
     *
     * @param entityList å®žä½“对象集合
     * @return æ›´æ–°æ“ä½œæ˜¯å¦æˆåŠŸçš„å¸ƒå°”å€¼
     */
    default boolean updateBatchById(Collection<T> entityList) {
        return Db.updateBatchById(entityList);
    }
    /**
     * æ‰¹é‡æ’入或更新实体对象集合
     *
     * @param entityList å®žä½“对象集合
     * @return æ’入或更新操作是否成功的布尔值
     */
    default boolean insertOrUpdateBatch(Collection<T> entityList) {
        return Db.saveOrUpdateBatch(entityList);
    }
    /**
     * æ‰¹é‡æ’入实体对象集合并指定批处理大小
     *
     * @param entityList å®žä½“对象集合
     * @param batchSize  æ‰¹å¤„理大小
     * @return æ’入操作是否成功的布尔值
     */
    default boolean insertBatch(Collection<T> entityList, int batchSize) {
        return Db.saveBatch(entityList, batchSize);
    }
    /**
     * æ‰¹é‡æ ¹æ®ID更新实体对象集合并指定批处理大小
     *
     * @param entityList å®žä½“对象集合
     * @param batchSize  æ‰¹å¤„理大小
     * @return æ›´æ–°æ“ä½œæ˜¯å¦æˆåŠŸçš„å¸ƒå°”å€¼
     */
    default boolean updateBatchById(Collection<T> entityList, int batchSize) {
        return Db.updateBatchById(entityList, batchSize);
    }
    /**
     * æ‰¹é‡æ’入或更新实体对象集合并指定批处理大小
     *
     * @param entityList å®žä½“对象集合
     * @param batchSize  æ‰¹å¤„理大小
     * @return æ’入或更新操作是否成功的布尔值
     */
    default boolean insertOrUpdateBatch(Collection<T> entityList, int batchSize) {
        return Db.saveOrUpdateBatch(entityList, batchSize);
    }
    /**
     * æ ¹æ®ID查询单个VO对象
     *
     * @param id ä¸»é”®ID
     * @return æŸ¥è¯¢åˆ°çš„单个VO对象
     */
    default V selectVoById(Serializable id) {
        return selectVoById(id, this.currentVoClass());
    }
    /**
     * æ ¹æ®ID查询单个VO对象并将其转换为指定的VOç±»
     *
     * @param id      ä¸»é”®ID
     * @param voClass è¦è½¬æ¢çš„VO类的Class对象
     * @param <C>     VO类的类型
     * @return æŸ¥è¯¢åˆ°çš„单个VO对象,经过转换为指定的VO类后返回
     */
    default <C> C selectVoById(Serializable id, Class<C> voClass) {
        T obj = this.selectById(id);
        if (ObjectUtil.isNull(obj)) {
            return null;
        }
        return MapstructUtils.convert(obj, voClass);
    }
    /**
     * æ ¹æ®ID集合批量查询VO对象列表
     *
     * @param idList ä¸»é”®ID集合
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表
     */
    default List<V> selectVoByIds(Collection<? extends Serializable> idList) {
        return selectVoByIds(idList, this.currentVoClass());
    }
    /**
     * æ ¹æ®ID集合批量查询实体对象列表,并将其转换为指定的VO对象列表
     *
     * @param idList  ä¸»é”®ID集合
     * @param voClass è¦è½¬æ¢çš„VO类的Class对象
     * @param <C>     VO类的类型
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表,经过转换为指定的VO类后返回
     */
    default <C> List<C> selectVoByIds(Collection<? extends Serializable> idList, Class<C> voClass) {
        List<T> list = this.selectByIds(idList);
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }
        return MapstructUtils.convert(list, voClass);
    }
    /**
     * æ ¹æ®æŸ¥è¯¢æ¡ä»¶Map查询VO对象列表
     *
     * @param map æŸ¥è¯¢æ¡ä»¶Map
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表
     */
    default List<V> selectVoByMap(Map<String, Object> map) {
        return selectVoByMap(map, this.currentVoClass());
    }
    /**
     * æ ¹æ®æŸ¥è¯¢æ¡ä»¶Map查询实体对象列表,并将其转换为指定的VO对象列表
     *
     * @param map     æŸ¥è¯¢æ¡ä»¶Map
     * @param voClass è¦è½¬æ¢çš„VO类的Class对象
     * @param <C>     VO类的类型
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表,经过转换为指定的VO类后返回
     */
    default <C> List<C> selectVoByMap(Map<String, Object> map, Class<C> voClass) {
        List<T> list = this.selectByMap(map);
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }
        return MapstructUtils.convert(list, voClass);
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢å•个VO对象
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @return æŸ¥è¯¢åˆ°çš„单个VO对象
     */
    default V selectVoOne(Wrapper<T> wrapper) {
        return selectVoOne(wrapper, this.currentVoClass());
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢å•个VO对象,并根据需要决定是否抛出异常
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @param throwEx æ˜¯å¦æŠ›å‡ºå¼‚常的标志
     * @return æŸ¥è¯¢åˆ°çš„单个VO对象
     */
    default V selectVoOne(Wrapper<T> wrapper, boolean throwEx) {
        return selectVoOne(wrapper, this.currentVoClass(), throwEx);
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢å•个VO对象,并指定返回的VO对象的类型
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @param voClass è¿”回的VO对象的Class对象
     * @param <C>     è¿”回的VO对象的类型
     * @return æŸ¥è¯¢åˆ°çš„单个VO对象,经过类型转换为指定的VO类后返回
     */
    default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass) {
        return selectVoOne(wrapper, voClass, true);
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢å•个实体对象,并将其转换为指定的VO对象
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @param voClass è¦è½¬æ¢çš„VO类的Class对象
     * @param throwEx æ˜¯å¦æŠ›å‡ºå¼‚常的标志
     * @param <C>     VO类的类型
     * @return æŸ¥è¯¢åˆ°çš„单个VO对象,经过转换为指定的VO类后返回
     */
    default <C> C selectVoOne(Wrapper<T> wrapper, Class<C> voClass, boolean throwEx) {
        T obj = this.selectOne(wrapper, throwEx);
        if (ObjectUtil.isNull(obj)) {
            return null;
        }
        return MapstructUtils.convert(obj, voClass);
    }
    /**
     * æŸ¥è¯¢æ‰€æœ‰VO对象列表
     *
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表
     */
    default List<V> selectVoList() {
        return selectVoList(new QueryWrapper<>(), this.currentVoClass());
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢VO对象列表
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表
     */
    default List<V> selectVoList(Wrapper<T> wrapper) {
        return selectVoList(wrapper, this.currentVoClass());
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢å®žä½“对象列表,并将其转换为指定的VO对象列表
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @param voClass è¦è½¬æ¢çš„VO类的Class对象
     * @param <C>     VO类的类型
     * @return æŸ¥è¯¢åˆ°çš„VO对象列表,经过转换为指定的VO类后返回
     */
    default <C> List<C> selectVoList(Wrapper<T> wrapper, Class<C> voClass) {
        List<T> list = this.selectList(wrapper);
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }
        return MapstructUtils.convert(list, voClass);
    }
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢VO对象列表
     *
     * @param page    åˆ†é¡µä¿¡æ¯
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @return æŸ¥è¯¢åˆ°çš„VO对象分页列表
     */
    default <P extends IPage<V>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper) {
        return selectVoPage(page, wrapper, this.currentVoClass());
    }
    /**
     * æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢å®žä½“对象列表,并将其转换为指定的VO对象分页列表
     *
     * @param page    åˆ†é¡µä¿¡æ¯
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @param voClass è¦è½¬æ¢çš„VO类的Class对象
     * @param <C>     VO类的类型
     * @param <P>     VO对象分页列表的类型
     * @return æŸ¥è¯¢åˆ°çš„VO对象分页列表,经过转换为指定的VO类后返回
     */
    default <C, P extends IPage<C>> P selectVoPage(IPage<T> page, Wrapper<T> wrapper, Class<C> voClass) {
        // æ ¹æ®æ¡ä»¶åˆ†é¡µæŸ¥è¯¢å®žä½“对象列表
        List<T> list = this.selectList(page, wrapper);
        // åˆ›å»ºä¸€ä¸ªæ–°çš„VO对象分页列表,并设置分页信息
        IPage<C> voPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        if (CollUtil.isEmpty(list)) {
            return (P) voPage;
        }
        voPage.setRecords(MapstructUtils.convert(list, voClass));
        return (P) voPage;
    }
    /**
     * æ ¹æ®æ¡ä»¶æŸ¥è¯¢ç¬¦åˆæ¡ä»¶çš„对象,并将其转换为指定类型的对象列表
     *
     * @param wrapper æŸ¥è¯¢æ¡ä»¶Wrapper
     * @param mapper  è½¬æ¢å‡½æ•°ï¼Œç”¨äºŽå°†æŸ¥è¯¢åˆ°çš„对象转换为指定类型的对象
     * @param <C>     è¦è½¬æ¢çš„对象的类型
     * @return æŸ¥è¯¢åˆ°çš„符合条件的对象列表,经过转换为指定类型的对象后返回
     */
    default <C> List<C> selectObjs(Wrapper<T> wrapper, Function<? super Object, C> mapper) {
        return StreamUtils.toList(this.selectObjs(wrapper), mapper);
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/page/PageQuery.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
package org.ruoyi.core.page;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.sql.SqlUtil;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
 * åˆ†é¡µæŸ¥è¯¢å®žä½“ç±»
 *
 * @author Lion Li
 */
@Data
public class PageQuery implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     * åˆ†é¡µå¤§å°
     */
    private Integer pageSize;
    /**
     * å½“前页数
     */
    private Integer pageNum;
    /**
     * æŽ’序列
     */
    private String orderByColumn;
    /**
     * æŽ’序的方向desc或者asc
     */
    private String isAsc;
    /**
     * å½“前记录起始索引 é»˜è®¤å€¼
     */
    public static final int DEFAULT_PAGE_NUM = 1;
    /**
     * æ¯é¡µæ˜¾ç¤ºè®°å½•æ•° é»˜è®¤å€¼ é»˜è®¤æŸ¥å…¨éƒ¨
     */
    public static final int DEFAULT_PAGE_SIZE = Integer.MAX_VALUE;
    /**
     * æž„建分页对象
     */
    public <T> Page<T> build() {
        Integer pageNum = ObjectUtil.defaultIfNull(getPageNum(), DEFAULT_PAGE_NUM);
        Integer pageSize = ObjectUtil.defaultIfNull(getPageSize(), DEFAULT_PAGE_SIZE);
        if (pageNum <= 0) {
            pageNum = DEFAULT_PAGE_NUM;
        }
        Page<T> page = new Page<>(pageNum, pageSize);
        List<OrderItem> orderItems = buildOrderItem();
        if (CollUtil.isNotEmpty(orderItems)) {
            page.addOrder(orderItems);
        }
        return page;
    }
    /**
     * æž„建排序
     *
     * æ”¯æŒçš„用法如下:
     * {isAsc:"asc",orderByColumn:"id"} order by id asc
     * {isAsc:"asc",orderByColumn:"id,createTime"} order by id asc,create_time asc
     * {isAsc:"desc",orderByColumn:"id,createTime"} order by id desc,create_time desc
     * {isAsc:"asc,desc",orderByColumn:"id,createTime"} order by id asc,create_time desc
     */
    private List<OrderItem> buildOrderItem() {
        if (StringUtils.isBlank(orderByColumn) || StringUtils.isBlank(isAsc)) {
            return null;
        }
        String orderBy = SqlUtil.escapeOrderBySql(orderByColumn);
        orderBy = StringUtils.toUnderScoreCase(orderBy);
        // å…¼å®¹å‰ç«¯æŽ’序类型
        isAsc = StringUtils.replaceEach(isAsc, new String[]{"ascending", "descending"}, new String[]{"asc", "desc"});
        String[] orderByArr = orderBy.split(StringUtils.SEPARATOR);
        String[] isAscArr = isAsc.split(StringUtils.SEPARATOR);
        if (isAscArr.length != 1 && isAscArr.length != orderByArr.length) {
            throw new ServiceException("排序参数有误");
        }
        List<OrderItem> list = new ArrayList<>();
        // æ¯ä¸ªå­—段各自排序
        for (int i = 0; i < orderByArr.length; i++) {
            String orderByStr = orderByArr[i];
            String isAscStr = isAscArr.length == 1 ? isAscArr[0] : isAscArr[i];
            if ("asc".equals(isAscStr)) {
                list.add(OrderItem.asc(orderByStr));
            } else if ("desc".equals(isAscStr)) {
                list.add(OrderItem.desc(orderByStr));
            } else {
                throw new ServiceException("排序参数有误");
            }
        }
        return list;
    }
    @JsonIgnore
    public Integer getFirstNum() {
        return (pageNum - 1) * pageSize;
    }
    public PageQuery(Integer pageSize, Integer pageNum) {
        this.pageSize = pageSize;
        this.pageNum = pageNum;
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/core/page/TableDataInfo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,91 @@
package org.ruoyi.core.page;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
/**
 * è¡¨æ ¼åˆ†é¡µæ•°æ®å¯¹è±¡
 *
 * @author Lion Li
 */
@Data
@NoArgsConstructor
public class TableDataInfo<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;
    /**
     * æ€»è®°å½•æ•°
     */
    private long total;
    /**
     * åˆ—表数据
     */
    private List<T> rows;
    /**
     * æ¶ˆæ¯çŠ¶æ€ç 
     */
    private int code;
    /**
     * æ¶ˆæ¯å†…容
     */
    private String msg;
    /**
     * åˆ†é¡µ
     *
     * @param list  åˆ—表数据
     * @param total æ€»è®°å½•æ•°
     */
    public TableDataInfo(List<T> list, long total) {
        this.rows = list;
        this.total = total;
        this.code = HttpStatus.HTTP_OK;
        this.msg = "查询成功";
    }
    /**
     * æ ¹æ®åˆ†é¡µå¯¹è±¡æž„建表格分页数据对象
     */
    public static <T> TableDataInfo<T> build(IPage<T> page) {
        TableDataInfo<T> rspData = new TableDataInfo<>();
        rspData.setCode(HttpStatus.HTTP_OK);
        rspData.setMsg("查询成功");
        rspData.setRows(page.getRecords());
        rspData.setTotal(page.getTotal());
        return rspData;
    }
    /**
     * æ ¹æ®æ•°æ®åˆ—表构建表格分页数据对象
     */
    public static <T> TableDataInfo<T> build(List<T> list) {
        TableDataInfo<T> rspData = new TableDataInfo<>();
        rspData.setCode(HttpStatus.HTTP_OK);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(list.size());
        return rspData;
    }
    /**
     * æž„建表格分页数据对象
     */
    public static <T> TableDataInfo<T> build() {
        TableDataInfo<T> rspData = new TableDataInfo<>();
        rspData.setCode(HttpStatus.HTTP_OK);
        rspData.setMsg("查询成功");
        return rspData;
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/enums/DataBaseType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package org.ruoyi.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.ruoyi.common.core.utils.StringUtils;
/**
 * æ•°æ®åº“类型
 *
 * @author Lion Li
 */
@Getter
@AllArgsConstructor
public enum DataBaseType {
    /**
     * MySQL
     */
    MY_SQL("MySQL"),
    /**
     * Oracle
     */
    ORACLE("Oracle"),
    /**
     * PostgreSQL
     */
    POSTGRE_SQL("PostgreSQL"),
    /**
     * SQL Server
     */
    SQL_SERVER("Microsoft SQL Server");
    /**
     * æ•°æ®åº“类型
     */
    private final String type;
    /**
     * æ ¹æ®æ•°æ®åº“产品名称查找对应的数据库类型
     *
     * @param databaseProductName æ•°æ®åº“产品名称
     * @return å¯¹åº”的数据库类型枚举值,如果未找到则返回 null
     */
    public static DataBaseType find(String databaseProductName) {
        if (StringUtils.isBlank(databaseProductName)) {
            return null;
        }
        for (DataBaseType type : values()) {
            if (type.getType().equals(databaseProductName)) {
                return type;
            }
        }
        return null;
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/enums/DataScopeType.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
package org.ruoyi.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.helper.DataPermissionHelper;
/**
 * æ•°æ®æƒé™ç±»åž‹æžšä¸¾
 * <p>
 * æ”¯æŒä½¿ç”¨ SpEL æ¨¡æ¿è¡¨è¾¾å¼å®šä¹‰ SQL æŸ¥è¯¢æ¡ä»¶
 * å†…置数据:
 * - {@code user}: å½“前登录用户信息,参考 {@link LoginUser}
 * å†…置服务:
 * - {@code sdss}: ç³»ç»Ÿæ•°æ®æƒé™æœåŠ¡ï¼Œå‚è€ƒ ISysDataScopeService
 * å¦‚需扩展数据,可以通过 {@link DataPermissionHelper} è¿›è¡Œæ“ä½œ
 * å¦‚需扩展服务,可以通过 ISysDataScopeService è‡ªè¡Œç¼–写
 * </p>
 *
 * @author Lion Li
 * @version 3.5.0
 */
@Getter
@AllArgsConstructor
public enum DataScopeType {
    /**
     * å…¨éƒ¨æ•°æ®æƒé™
     */
    ALL("1", "", ""),
    /**
     * è‡ªå®šæ•°æ®æƒé™
     */
    CUSTOM("2", " #{#deptName} IN ( #{@sdss.getRoleCustom( #user.roleId )} ) ", " 1 = 0 "),
    /**
     * éƒ¨é—¨æ•°æ®æƒé™
     */
    DEPT("3", " #{#deptName} = #{#user.deptId} ", " 1 = 0 "),
    /**
     * éƒ¨é—¨åŠä»¥ä¸‹æ•°æ®æƒé™
     */
    DEPT_AND_CHILD("4", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} )", " 1 = 0 "),
    /**
     * ä»…本人数据权限
     */
    SELF("5", " #{#userName} = #{#user.userId} ", " 1 = 0 "),
    /**
     * éƒ¨é—¨åŠä»¥ä¸‹æˆ–本人数据权限
     */
    DEPT_AND_CHILD_OR_SELF("6", " #{#deptName} IN ( #{@sdss.getDeptAndChild( #user.deptId )} ) OR #{#userName} = #{#user.userId} ", " 1 = 0 ");
    private final String code;
    /**
     * SpEL æ¨¡æ¿è¡¨è¾¾å¼ï¼Œç”¨äºŽæž„建 SQL æŸ¥è¯¢æ¡ä»¶
     */
    private final String sqlTemplate;
    /**
     * å¦‚果不满足 {@code sqlTemplate} çš„æ¡ä»¶ï¼Œåˆ™ä½¿ç”¨æ­¤é»˜è®¤ SQL è¡¨è¾¾å¼
     */
    private final String elseSql;
    /**
     * æ ¹æ®æžšä¸¾ä»£ç æŸ¥æ‰¾å¯¹åº”的枚举值
     *
     * @param code æžšä¸¾ä»£ç 
     * @return å¯¹åº”的枚举值,如果未找到则返回 null
     */
    public static DataScopeType findCode(String code) {
        if (StringUtils.isBlank(code)) {
            return null;
        }
        for (DataScopeType type : values()) {
            if (type.getCode().equals(code)) {
                return type;
            }
        }
        return null;
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/InjectionMetaObjectHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,103 @@
package org.ruoyi.handler;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpStatus;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.ObjectUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.core.domain.BaseEntity;
import java.util.Date;
/**
 * MP注入处理器
 *
 * @author Lion Li
 * @date 2021/4/25
 */
@Slf4j
public class InjectionMetaObjectHandler implements MetaObjectHandler {
    /**
     * æ’入填充方法,用于在插入数据时自动填充实体对象中的创建时间、更新时间、创建人、更新人等信息
     *
     * @param metaObject å…ƒå¯¹è±¡ï¼Œç”¨äºŽèŽ·å–åŽŸå§‹å¯¹è±¡å¹¶è¿›è¡Œå¡«å……
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        try {
            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity baseEntity) {
                // èŽ·å–å½“å‰æ—¶é—´ä½œä¸ºåˆ›å»ºæ—¶é—´å’Œæ›´æ–°æ—¶é—´ï¼Œå¦‚æžœåˆ›å»ºæ—¶é—´ä¸ä¸ºç©ºï¼Œåˆ™ä½¿ç”¨åˆ›å»ºæ—¶é—´ï¼Œå¦åˆ™ä½¿ç”¨å½“å‰æ—¶é—´
                Date current = ObjectUtils.notNull(baseEntity.getCreateTime(), new Date());
                baseEntity.setCreateTime(current);
                baseEntity.setUpdateTime(current);
                // å¦‚果创建人为空,则填充当前登录用户的信息
                if (ObjectUtil.isNull(baseEntity.getCreateBy())) {
                    LoginUser loginUser = getLoginUser();
                    if (ObjectUtil.isNotNull(loginUser)) {
                        Long userId = loginUser.getUserId();
                        // å¡«å……创建人、更新人和创建部门信息
                        baseEntity.setCreateBy(userId);
                        baseEntity.setUpdateBy(userId);
                        baseEntity.setCreateDept(ObjectUtils.notNull(baseEntity.getCreateDept(), loginUser.getDeptId()));
                    }
                }
            } else {
                Date date = new Date();
                this.strictInsertFill(metaObject, "createTime", Date.class, date);
                this.strictInsertFill(metaObject, "updateTime", Date.class, date);
            }
        } catch (Exception e) {
            throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
        }
    }
    /**
     * æ›´æ–°å¡«å……方法,用于在更新数据时自动填充实体对象中的更新时间和更新人信息
     *
     * @param metaObject å…ƒå¯¹è±¡ï¼Œç”¨äºŽèŽ·å–åŽŸå§‹å¯¹è±¡å¹¶è¿›è¡Œå¡«å……
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        try {
            if (ObjectUtil.isNotNull(metaObject) && metaObject.getOriginalObject() instanceof BaseEntity baseEntity) {
                // èŽ·å–å½“å‰æ—¶é—´ä½œä¸ºæ›´æ–°æ—¶é—´ï¼Œæ— è®ºåŽŸå§‹å¯¹è±¡ä¸­çš„æ›´æ–°æ—¶é—´æ˜¯å¦ä¸ºç©ºéƒ½å¡«å……
                Date current = new Date();
                baseEntity.setUpdateTime(current);
                // èŽ·å–å½“å‰ç™»å½•ç”¨æˆ·çš„ID,并填充更新人信息
                Long userId = LoginHelper.getUserId();
                if (ObjectUtil.isNotNull(userId)) {
                    baseEntity.setUpdateBy(userId);
                }
            } else {
                this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
            }
        } catch (Exception e) {
            throw new ServiceException("自动注入异常 => " + e.getMessage(), HttpStatus.HTTP_UNAUTHORIZED);
        }
    }
    /**
     * èŽ·å–å½“å‰ç™»å½•ç”¨æˆ·ä¿¡æ¯
     *
     * @return å½“前登录用户的信息,如果用户未登录则返回 null
     */
    private LoginUser getLoginUser() {
        LoginUser loginUser;
        try {
            loginUser = LoginHelper.getLoginUser();
        } catch (Exception e) {
            log.warn("自动注入警告 => ç”¨æˆ·æœªç™»å½•");
            return null;
        }
        return loginUser;
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/MybatisExceptionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,47 @@
package org.ruoyi.handler;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.utils.StringUtils;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
 * Mybatis异常处理器
 *
 * @author Lion Li
 */
@Slf4j
@RestControllerAdvice
public class MybatisExceptionHandler {
    /**
     * ä¸»é”®æˆ–UNIQUE索引,数据重复异常
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public R<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',数据库中已存在记录'{}'", requestURI, e.getMessage());
        return R.fail("数据库中已存在该记录,请联系管理员确认");
    }
    /**
     * Mybatis系统异常 é€šç”¨å¤„理
     */
    @ExceptionHandler(MyBatisSystemException.class)
    public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String message = e.getMessage();
        if (StringUtils.contains("CannotFindDataSourceException", message)) {
            log.error("请求地址'{}', æœªæ‰¾åˆ°æ•°æ®æº", requestURI);
            return R.fail("未找到数据源,请联系管理员确认");
        }
        log.error("请求地址'{}', Mybatis系统异常", requestURI, e);
        return R.fail(message);
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/PlusDataPermissionHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,359 @@
package org.ruoyi.handler;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import org.apache.ibatis.io.Resources;
import org.ruoyi.annotation.DataColumn;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.common.core.domain.dto.RoleDTO;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.enums.DataScopeType;
import org.ruoyi.helper.DataPermissionHelper;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.expression.*;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.util.ClassUtils;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
 * æ•°æ®æƒé™è¿‡æ»¤
 *
 * @author Lion Li
 * @version 3.5.0
 */
@Slf4j
public class PlusDataPermissionHandler {
    /**
     * ç±»åç§°ä¸Žæ³¨è§£çš„æ˜ å°„关系缓存(由于aop无法拦截mybatis接口类上的注解 åªèƒ½é€šè¿‡å¯åŠ¨é¢„æ‰«æçš„æ–¹å¼è¿›è¡Œ)
     */
    private final Map<String, DataPermission> dataPermissionCacheMap = new ConcurrentHashMap<>();
    /**
     * spel è§£æžå™¨
     */
    private final ExpressionParser parser = new SpelExpressionParser();
    private final ParserContext parserContext = new TemplateParserContext();
    /**
     * bean解析器 ç”¨äºŽå¤„理 spel è¡¨è¾¾å¼ä¸­å¯¹ bean çš„调用
     */
    private final BeanResolver beanResolver = new BeanFactoryResolver(SpringUtils.getBeanFactory());
    /**
     * æž„造方法,扫描指定包下的 Mapper ç±»å¹¶åˆå§‹åŒ–缓存
     *
     * @param mapperPackage Mapper ç±»æ‰€åœ¨çš„包路径
     */
    public PlusDataPermissionHandler(String mapperPackage) {
        scanMapperClasses(mapperPackage);
    }
    /**
     * èŽ·å–æ•°æ®è¿‡æ»¤æ¡ä»¶çš„ SQL ç‰‡æ®µ
     *
     * @param where             åŽŸå§‹çš„æŸ¥è¯¢æ¡ä»¶è¡¨è¾¾å¼
     * @param mappedStatementId Mapper æ–¹æ³•çš„ ID
     * @param isSelect          æ˜¯å¦ä¸ºæŸ¥è¯¢è¯­å¥
     * @return æ•°æ®è¿‡æ»¤æ¡ä»¶çš„ SQL ç‰‡æ®µ
     */
    public Expression getSqlSegment(Expression where, String mappedStatementId, boolean isSelect) {
        try {
            // èŽ·å–æ•°æ®æƒé™é…ç½®
            DataPermission dataPermission = getDataPermission(mappedStatementId);
            // èŽ·å–å½“å‰ç™»å½•ç”¨æˆ·ä¿¡æ¯
            LoginUser currentUser = DataPermissionHelper.getVariable("user");
            if (ObjectUtil.isNull(currentUser)) {
                currentUser = LoginHelper.getLoginUser();
                DataPermissionHelper.setVariable("user", currentUser);
            }
            // å¦‚果是超级管理员或租户管理员,则不过滤数据
            if (LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin()) {
                return where;
            }
            // æž„造数据过滤条件的 SQL ç‰‡æ®µ
            String dataFilterSql = buildDataFilter(dataPermission, isSelect);
            if (StringUtils.isBlank(dataFilterSql)) {
                return where;
            }
            Expression expression = CCJSqlParserUtil.parseExpression(dataFilterSql);
            // æ•°æ®æƒé™ä½¿ç”¨å•独的括号 é˜²æ­¢ä¸Žå…¶ä»–条件冲突
            ParenthesedExpressionList<Expression> parenthesis = new ParenthesedExpressionList<>(expression);
            if (ObjectUtil.isNotNull(where)) {
                return new AndExpression(where, parenthesis);
            } else {
                return parenthesis;
            }
        } catch (JSQLParserException e) {
            throw new ServiceException("数据权限解析异常 => " + e.getMessage());
        } finally {
            DataPermissionHelper.removePermission();
        }
    }
    /**
     * æž„建数据过滤条件的 SQL è¯­å¥
     *
     * @param dataPermission æ•°æ®æƒé™æ³¨è§£
     * @param isSelect       æ ‡å¿—当前操作是否为查询操作,查询操作和更新或删除操作在处理过滤条件时会有不同的处理方式
     * @return æž„建的数据过滤条件的 SQL è¯­å¥
     * @throws ServiceException å¦‚果角色的数据范围异常或者 key ä¸Ž value çš„长度不匹配,则抛出 ServiceException å¼‚常
     */
    private String buildDataFilter(DataPermission dataPermission, boolean isSelect) {
        // æ›´æ–°æˆ–删除需满足所有条件
        String joinStr = isSelect ? " OR " : " AND ";
        if (StringUtils.isNotBlank(dataPermission.joinStr())) {
            joinStr = " " + dataPermission.joinStr() + " ";
        }
        LoginUser user = DataPermissionHelper.getVariable("user");
        Object defaultValue = "-1";
        NullSafeStandardEvaluationContext context = new NullSafeStandardEvaluationContext(defaultValue);
        context.addPropertyAccessor(new NullSafePropertyAccessor(context.getPropertyAccessors().get(0), defaultValue));
        context.setBeanResolver(beanResolver);
        DataPermissionHelper.getContext().forEach(context::setVariable);
        Set<String> conditions = new HashSet<>();
        // ä¼˜å…ˆè®¾ç½®å˜é‡
        List<String> keys = new ArrayList<>();
        Map<DataColumn, Boolean> ignoreMap = new HashMap<>();
        for (DataColumn dataColumn : dataPermission.value()) {
            if (dataColumn.key().length != dataColumn.value().length) {
                throw new ServiceException("角色数据范围异常 => key与value长度不匹配");
            }
            // åŒ…含权限标识符 è¿™ç›´æŽ¥è·³è¿‡
            if (StringUtils.isNotBlank(dataColumn.permission()) &&
                CollUtil.contains(user.getMenuPermission(), dataColumn.permission())
            ) {
                ignoreMap.put(dataColumn, Boolean.TRUE);
                continue;
            }
            // è®¾ç½®æ³¨è§£å˜é‡ key ä¸ºè¡¨è¾¾å¼å˜é‡ value ä¸ºå˜é‡å€¼
            for (int i = 0; i < dataColumn.key().length; i++) {
                context.setVariable(dataColumn.key()[i], dataColumn.value()[i]);
            }
            keys.addAll(Arrays.stream(dataColumn.key()).map(key -> "#" + key).toList());
        }
        for (RoleDTO role : user.getRoles()) {
            user.setRoleId(role.getRoleId());
            // èŽ·å–è§’è‰²æƒé™æ³›åž‹
            DataScopeType type = DataScopeType.findCode(role.getDataScope());
            if (ObjectUtil.isNull(type)) {
                throw new ServiceException("角色数据范围异常 => " + role.getDataScope());
            }
            // å…¨éƒ¨æ•°æ®æƒé™ç›´æŽ¥è¿”回
            if (type == DataScopeType.ALL) {
                return StringUtils.EMPTY;
            }
            boolean isSuccess = false;
            for (DataColumn dataColumn : dataPermission.value()) {
                // åŒ…含权限标识符 è¿™ç›´æŽ¥è·³è¿‡
                if (ignoreMap.containsKey(dataColumn)) {
                    // ä¿®å¤å¤šè§’色与权限标识符共用问题 https://gitee.com/dromara/RuoYi-Vue-Plus/issues/IB4CS4
                    conditions.add(joinStr + " 1 = 1 ");
                    isSuccess = true;
                    continue;
                }
                // ä¸åŒ…含 key å˜é‡ åˆ™ä¸å¤„理
                if (!StringUtils.containsAny(type.getSqlTemplate(), keys.toArray(String[]::new))) {
                    continue;
                }
                // å½“前注解不满足模板 ä¸å¤„理
                if (!StringUtils.containsAny(type.getSqlTemplate(), dataColumn.key())) {
                    continue;
                }
                // å¿½ç•¥æ•°æ®æƒé™ é˜²æ­¢spel表达式内有其他sql查询导致死循环调用
                String sql = DataPermissionHelper.ignore(() ->
                    parser.parseExpression(type.getSqlTemplate(), parserContext).getValue(context, String.class)
                );
                // è§£æžsql模板并填充
                conditions.add(joinStr + sql);
                isSuccess = true;
            }
            // æœªå¤„理成功则填充兜底方案
            if (!isSuccess && StringUtils.isNotBlank(type.getElseSql())) {
                conditions.add(joinStr + type.getElseSql());
            }
        }
        if (CollUtil.isNotEmpty(conditions)) {
            String sql = StreamUtils.join(conditions, Function.identity(), "");
            return sql.substring(joinStr.length());
        }
        return StringUtils.EMPTY;
    }
    /**
     * æ‰«ææŒ‡å®šåŒ…下的 Mapper ç±»ï¼Œå¹¶æŸ¥æ‰¾å…¶ä¸­å¸¦æœ‰ç‰¹å®šæ³¨è§£çš„æ–¹æ³•或类
     *
     * @param mapperPackage Mapper ç±»æ‰€åœ¨çš„包路径
     */
    private void scanMapperClasses(String mapperPackage) {
        // åˆ›å»ºèµ„源解析器和元数据读取工厂
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
        // å°† Mapper åŒ…路径按分隔符拆分为数组
        String[] packagePatternArray = StringUtils.splitPreserveAllTokens(mapperPackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
        String classpath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX;
        try {
            for (String packagePattern : packagePatternArray) {
                // å°†åŒ…路径转换为资源路径
                String path = ClassUtils.convertClassNameToResourcePath(packagePattern);
                // èŽ·å–æŒ‡å®šè·¯å¾„ä¸‹çš„æ‰€æœ‰ .class æ–‡ä»¶èµ„源
                Resource[] resources = resolver.getResources(classpath + path + "/*.class");
                for (Resource resource : resources) {
                    // èŽ·å–èµ„æºçš„ç±»å…ƒæ•°æ®
                    ClassMetadata classMetadata = factory.getMetadataReader(resource).getClassMetadata();
                    // èŽ·å–èµ„æºå¯¹åº”çš„ç±»å¯¹è±¡
                    Class<?> clazz = Resources.classForName(classMetadata.getClassName());
                    // æŸ¥æ‰¾ç±»ä¸­çš„特定注解
                    findAnnotation(clazz);
                }
            }
        } catch (Exception e) {
            log.error("初始化数据安全缓存时出错:{}", e.getMessage());
        }
    }
    /**
     * åœ¨æŒ‡å®šçš„类中查找特定的注解 DataPermission,并将带有这个注解的方法或类存储到 dataPermissionCacheMap ä¸­
     *
     * @param clazz è¦æŸ¥æ‰¾çš„ç±»
     */
    private void findAnnotation(Class<?> clazz) {
        DataPermission dataPermission;
        for (Method method : clazz.getMethods()) {
            if (method.isDefault() || method.isVarArgs()) {
                continue;
            }
            String mappedStatementId = clazz.getName() + "." + method.getName();
            if (AnnotationUtil.hasAnnotation(method, DataPermission.class)) {
                dataPermission = AnnotationUtil.getAnnotation(method, DataPermission.class);
                dataPermissionCacheMap.put(mappedStatementId, dataPermission);
            }
        }
        if (AnnotationUtil.hasAnnotation(clazz, DataPermission.class)) {
            dataPermission = AnnotationUtil.getAnnotation(clazz, DataPermission.class);
            dataPermissionCacheMap.put(clazz.getName(), dataPermission);
        }
    }
    /**
     * æ ¹æ®æ˜ å°„语句 ID æˆ–类名获取对应的 DataPermission æ³¨è§£å¯¹è±¡
     *
     * @param mapperId æ˜ å°„语句 ID
     * @return DataPermission æ³¨è§£å¯¹è±¡ï¼Œå¦‚果不存在则返回 null
     */
    public DataPermission getDataPermission(String mapperId) {
        // æ£€æŸ¥ä¸Šä¸‹æ–‡ä¸­æ˜¯å¦åŒ…含映射语句 ID å¯¹åº”çš„ DataPermission æ³¨è§£å¯¹è±¡
        if (DataPermissionHelper.getPermission() != null) {
            return DataPermissionHelper.getPermission();
        }
        // æ£€æŸ¥ç¼“存中是否包含映射语句 ID å¯¹åº”çš„ DataPermission æ³¨è§£å¯¹è±¡
        if (dataPermissionCacheMap.containsKey(mapperId)) {
            return dataPermissionCacheMap.get(mapperId);
        }
        // å¦‚果缓存中不包含映射语句 ID å¯¹åº”çš„ DataPermission æ³¨è§£å¯¹è±¡ï¼Œåˆ™å°è¯•使用类名作为键查找
        String clazzName = mapperId.substring(0, mapperId.lastIndexOf("."));
        if (dataPermissionCacheMap.containsKey(clazzName)) {
            return dataPermissionCacheMap.get(clazzName);
        }
        return null;
    }
    /**
     * æ£€æŸ¥ç»™å®šçš„æ˜ å°„语句 ID æ˜¯å¦æœ‰æ•ˆï¼Œå³æ˜¯å¦èƒ½å¤Ÿæ‰¾åˆ°å¯¹åº”çš„ DataPermission æ³¨è§£å¯¹è±¡
     *
     * @param mapperId æ˜ å°„语句 ID
     * @return å¦‚果找到对应的 DataPermission æ³¨è§£å¯¹è±¡ï¼Œåˆ™è¿”回 false;否则返回 true
     */
    public boolean invalid(String mapperId) {
        return getDataPermission(mapperId) == null;
    }
    /**
     * å¯¹æ‰€æœ‰null变量找不到的变量返回默认值
     */
    @AllArgsConstructor
    private static class NullSafeStandardEvaluationContext extends StandardEvaluationContext {
        private final Object defaultValue;
        @Override
        public Object lookupVariable(String name) {
            Object obj = super.lookupVariable(name);
            // å¦‚果读取到的值是 null,则返回默认值
            if (obj == null) {
                return defaultValue;
            }
            return obj;
        }
    }
    /**
     * å¯¹æ‰€æœ‰null变量找不到的变量返回默认值 å§”托模式 å°†ä¸éœ€è¦å¤„理的方法委托给原处理器
     */
    @AllArgsConstructor
    private static class NullSafePropertyAccessor implements PropertyAccessor {
        private final PropertyAccessor delegate;
        private final Object defaultValue;
        @Override
        public Class<?>[] getSpecificTargetClasses() {
            return delegate.getSpecificTargetClasses();
        }
        @Override
        public boolean canRead(EvaluationContext context, Object target, String name) throws AccessException {
            return delegate.canRead(context, target, name);
        }
        @Override
        public TypedValue read(EvaluationContext context, Object target, String name) throws AccessException {
            TypedValue value = delegate.read(context, target, name);
            // å¦‚果读取到的值是 null,则返回默认值
            if (value.getValue() == null) {
                return new TypedValue(defaultValue);
            }
            return value;
        }
        @Override
        public boolean canWrite(EvaluationContext context, Object target, String name) throws AccessException {
            return delegate.canWrite(context, target, name);
        }
        @Override
        public void write(EvaluationContext context, Object target, String name, Object newValue) throws AccessException {
            delegate.write(context, target, name, newValue);
        }
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/handler/PlusPostInitTableInfoHandler.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package org.ruoyi.handler;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.handlers.PostInitTableInfoHandler;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.session.Configuration;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.reflect.ReflectUtils;
/**
 * ä¿®æ”¹è¡¨ä¿¡æ¯åˆå§‹åŒ–方式
 * ç›®å‰ç”¨äºŽå…¨å±€ä¿®æ”¹æ˜¯å¦ä½¿ç”¨é€»è¾‘删除
 *
 * @author Lion Li
 */
public class PlusPostInitTableInfoHandler implements PostInitTableInfoHandler {
    @Override
    public void postTableInfo(TableInfo tableInfo, Configuration configuration) {
        String flag = SpringUtils.getProperty("mybatis-plus.enableLogicDelete", "true");
        // åªæœ‰å…³é—­æ—¶ ç»Ÿä¸€è®¾ç½®false ä¸ºtrue时mp自动判断不处理
        if (!Convert.toBool(flag)) {
            ReflectUtils.setFieldValue(tableInfo, "withLogicDelete", false);
        }
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataBaseHelper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,82 @@
package org.ruoyi.helper;
import cn.hutool.core.convert.Convert;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.enums.DataBaseType;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
 * æ•°æ®åº“助手
 *
 * @author Lion Li
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class DataBaseHelper {
    private static final DynamicRoutingDataSource DS = SpringUtils.getBean(DynamicRoutingDataSource.class);
    /**
     * èŽ·å–å½“å‰æ•°æ®åº“ç±»åž‹
     */
    public static DataBaseType getDataBaseType() {
        DataSource dataSource = DS.determineDataSource();
        try (Connection conn = dataSource.getConnection()) {
            DatabaseMetaData metaData = conn.getMetaData();
            String databaseProductName = metaData.getDatabaseProductName();
            return DataBaseType.find(databaseProductName);
        } catch (SQLException e) {
            throw new ServiceException(e.getMessage());
        }
    }
    public static boolean isMySql() {
        return DataBaseType.MY_SQL == getDataBaseType();
    }
    public static boolean isOracle() {
        return DataBaseType.ORACLE == getDataBaseType();
    }
    public static boolean isPostgerSql() {
        return DataBaseType.POSTGRE_SQL == getDataBaseType();
    }
    public static boolean isSqlServer() {
        return DataBaseType.SQL_SERVER == getDataBaseType();
    }
    public static String findInSet(Object var1, String var2) {
        DataBaseType dataBasyType = getDataBaseType();
        String var = Convert.toStr(var1);
        if (dataBasyType == DataBaseType.SQL_SERVER) {
            // charindex(',100,' , ',0,100,101,') <> 0
            return "charindex(',%s,' , ','+%s+',') <> 0".formatted(var, var2);
        } else if (dataBasyType == DataBaseType.POSTGRE_SQL) {
            // (select strpos(',0,100,101,' , ',100,')) <> 0
            return "(select strpos(','||%s||',' , ',%s,')) <> 0".formatted(var2, var);
        } else if (dataBasyType == DataBaseType.ORACLE) {
            // instr(',0,100,101,' , ',100,') <> 0
            return "instr(','||%s||',' , ',%s,') <> 0".formatted(var2, var);
        }
        // find_in_set(100 , '0,100,101')
        return "find_in_set('%s' , %s) <> 0".formatted(var, var2);
    }
    /**
     * èŽ·å–å½“å‰åŠ è½½çš„æ•°æ®åº“å
     */
    public static List<String> getDataSourceNameList() {
        return new ArrayList<>(DS.getDataSources().keySet());
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/helper/DataPermissionHelper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,176 @@
package org.ruoyi.helper;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.context.model.SaStorage;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.common.core.utils.reflect.ReflectUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
import java.util.function.Supplier;
/**
 * æ•°æ®æƒé™åŠ©æ‰‹
 *
 * @author Lion Li
 * @version 3.5.0
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@SuppressWarnings("unchecked cast")
public class DataPermissionHelper {
    private static final String DATA_PERMISSION_KEY = "data:permission";
    private static final ThreadLocal<Stack<Integer>> REENTRANT_IGNORE = ThreadLocal.withInitial(Stack::new);
    private static final ThreadLocal<DataPermission> PERMISSION_CACHE = new ThreadLocal<>();
    /**
     * èŽ·å–å½“å‰æ‰§è¡Œmapper权限注解
     *
     * @return è¿”回当前执行mapper权限注解
     */
    public static DataPermission getPermission() {
        return PERMISSION_CACHE.get();
    }
    /**
     * è®¾ç½®å½“前执行mapper权限注解
     *
     * @param dataPermission   æ•°æ®æƒé™æ³¨è§£
     */
    public static void setPermission(DataPermission dataPermission) {
        PERMISSION_CACHE.set(dataPermission);
    }
    /**
     * åˆ é™¤å½“前执行mapper权限注解
     */
    public static void removePermission() {
        PERMISSION_CACHE.remove();
    }
    /**
     * ä»Žä¸Šä¸‹æ–‡ä¸­èŽ·å–æŒ‡å®šé”®çš„å˜é‡å€¼ï¼Œå¹¶å°†å…¶è½¬æ¢ä¸ºæŒ‡å®šçš„ç±»åž‹
     *
     * @param key å˜é‡çš„é”®
     * @param <T> å˜é‡å€¼çš„类型
     * @return æŒ‡å®šé”®çš„变量值,如果不存在则返回 null
     */
    public static <T> T getVariable(String key) {
        Map<String, Object> context = getContext();
        return (T) context.get(key);
    }
    /**
     * å‘上下文中设置指定键的变量值
     *
     * @param key   è¦è®¾ç½®çš„变量的键
     * @param value è¦è®¾ç½®çš„变量值
     */
    public static void setVariable(String key, Object value) {
        Map<String, Object> context = getContext();
        context.put(key, value);
    }
    /**
     * èŽ·å–æ•°æ®æƒé™ä¸Šä¸‹æ–‡
     *
     * @return å­˜å‚¨åœ¨SaStorage中的Map对象,用于存储数据权限相关的上下文信息
     * @throws NullPointerException å¦‚果数据权限上下文类型异常,则抛出NullPointerException
     */
    public static Map<String, Object> getContext() {
        SaStorage saStorage = SaHolder.getStorage();
        Object attribute = saStorage.get(DATA_PERMISSION_KEY);
        if (ObjectUtil.isNull(attribute)) {
            saStorage.set(DATA_PERMISSION_KEY, new HashMap<>());
            attribute = saStorage.get(DATA_PERMISSION_KEY);
        }
        if (attribute instanceof Map map) {
            return map;
        }
        throw new NullPointerException("data permission context type exception");
    }
    private static IgnoreStrategy getIgnoreStrategy() {
        Object ignoreStrategyLocal = ReflectUtils.getStaticFieldValue(ReflectUtils.getField(InterceptorIgnoreHelper.class, "IGNORE_STRATEGY_LOCAL"));
        if (ignoreStrategyLocal instanceof ThreadLocal<?> IGNORE_STRATEGY_LOCAL) {
            if (IGNORE_STRATEGY_LOCAL.get() instanceof IgnoreStrategy ignoreStrategy) {
                return ignoreStrategy;
            }
        }
        return null;
    }
    /**
     * å¼€å¯å¿½ç•¥æ•°æ®æƒé™(开启后需手动调用 {@link #disableIgnore()} å…³é—­)
     */
    public static void enableIgnore() {
        IgnoreStrategy ignoreStrategy = getIgnoreStrategy();
        if (ObjectUtil.isNull(ignoreStrategy)) {
            InterceptorIgnoreHelper.handle(IgnoreStrategy.builder().dataPermission(true).build());
        } else {
            ignoreStrategy.setDataPermission(true);
        }
        Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
        reentrantStack.push(reentrantStack.size() + 1);
    }
    /**
     * å…³é—­å¿½ç•¥æ•°æ®æƒé™
     */
    public static void disableIgnore() {
        IgnoreStrategy ignoreStrategy = getIgnoreStrategy();
        if (ObjectUtil.isNotNull(ignoreStrategy)) {
            boolean noOtherIgnoreStrategy = !Boolean.TRUE.equals(ignoreStrategy.getDynamicTableName())
                && !Boolean.TRUE.equals(ignoreStrategy.getBlockAttack())
                && !Boolean.TRUE.equals(ignoreStrategy.getIllegalSql())
                && !Boolean.TRUE.equals(ignoreStrategy.getTenantLine())
                && CollectionUtil.isEmpty(ignoreStrategy.getOthers());
            Stack<Integer> reentrantStack = REENTRANT_IGNORE.get();
            boolean empty = reentrantStack.isEmpty() || reentrantStack.pop() == 1;
            if (noOtherIgnoreStrategy && empty) {
                InterceptorIgnoreHelper.clearIgnoreStrategy();
            } else if (empty) {
                ignoreStrategy.setDataPermission(false);
            }
        }
    }
    /**
     * åœ¨å¿½ç•¥æ•°æ®æƒé™ä¸­æ‰§è¡Œ
     *
     * @param handle å¤„理执行方法
     */
    public static void ignore(Runnable handle) {
        enableIgnore();
        try {
            handle.run();
        } finally {
            disableIgnore();
        }
    }
    /**
     * åœ¨å¿½ç•¥æ•°æ®æƒé™ä¸­æ‰§è¡Œ
     *
     * @param handle å¤„理执行方法
     */
    public static <T> T ignore(Supplier<T> handle) {
        enableIgnore();
        try {
            return handle.get();
        } finally {
            disableIgnore();
        }
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/ruoyi/interceptor/PlusDataPermissionInterceptor.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,181 @@
package org.ruoyi.interceptor;
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.handler.MultiDataPermissionHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.BaseMultiTableInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SetOperationList;
import net.sf.jsqlparser.statement.update.Update;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.ruoyi.handler.PlusDataPermissionHandler;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
 * æ•°æ®æƒé™æ‹¦æˆªå™¨
 *
 * @author Lion Li
 * @version 3.5.0
 */
@Slf4j
public class PlusDataPermissionInterceptor extends BaseMultiTableInnerInterceptor implements InnerInterceptor {
    private final PlusDataPermissionHandler dataPermissionHandler;
    /**
     * æž„造函数,初始化 PlusDataPermissionHandler å®žä¾‹
     *
     * @param mapperPackage æ‰«æçš„æ˜ å°„器包
     */
    public PlusDataPermissionInterceptor(String mapperPackage) {
        this.dataPermissionHandler = new PlusDataPermissionHandler(mapperPackage);
    }
    /**
     * åœ¨æ‰§è¡ŒæŸ¥è¯¢ä¹‹å‰ï¼Œæ£€æŸ¥å¹¶å¤„理数据权限相关逻辑
     *
     * @param executor      MyBatis æ‰§è¡Œå™¨å¯¹è±¡
     * @param ms            æ˜ å°„语句对象
     * @param parameter     æ–¹æ³•参数
     * @param rowBounds     åˆ†é¡µå¯¹è±¡
     * @param resultHandler ç»“果处理器
     * @param boundSql      ç»‘定的 SQL å¯¹è±¡
     * @throws SQLException å¦‚果发生 SQL å¼‚常
     */
    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        // æ£€æŸ¥æ˜¯å¦éœ€è¦å¿½ç•¥æ•°æ®æƒé™å¤„理
        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
            return;
        }
        // æ£€æŸ¥æ˜¯å¦ç¼ºå°‘有效的数据权限注解
        if (dataPermissionHandler.invalid(ms.getId())) {
            return;
        }
        // è§£æž sql åˆ†é…å¯¹åº”方法
        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
        mpBs.sql(parserSingle(mpBs.sql(), ms.getId()));
    }
    /**
     * åœ¨å‡†å¤‡ SQL è¯­å¥ä¹‹å‰ï¼Œæ£€æŸ¥å¹¶å¤„理更新和删除操作的数据权限相关逻辑
     *
     * @param sh                 MyBatis StatementHandler å¯¹è±¡
     * @param connection         æ•°æ®åº“连接对象
     * @param transactionTimeout äº‹åŠ¡è¶…æ—¶æ—¶é—´
     */
    @Override
    public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
        PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
        MappedStatement ms = mpSh.mappedStatement();
        // èŽ·å– SQL å‘½ä»¤ç±»åž‹ï¼ˆå¢žã€åˆ ã€æ”¹ã€æŸ¥ï¼‰
        SqlCommandType sct = ms.getSqlCommandType();
        // åªå¤„理更新和删除操作的 SQL è¯­å¥
        if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE) {
            if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
                return;
            }
            // æ£€æŸ¥æ˜¯å¦ç¼ºå°‘有效的数据权限注解
            if (dataPermissionHandler.invalid(ms.getId())) {
                return;
            }
            PluginUtils.MPBoundSql mpBs = mpSh.mPBoundSql();
            mpBs.sql(parserMulti(mpBs.sql(), ms.getId()));
        }
    }
    /**
     * å¤„理 SELECT æŸ¥è¯¢è¯­å¥ä¸­çš„ WHERE æ¡ä»¶
     *
     * @param select SELECT æŸ¥è¯¢å¯¹è±¡
     * @param index  æŸ¥è¯¢è¯­å¥çš„索引
     * @param sql    æŸ¥è¯¢è¯­å¥
     * @param obj    WHERE æ¡ä»¶å‚æ•°
     */
    @Override
    protected void processSelect(Select select, int index, String sql, Object obj) {
        if (select instanceof PlainSelect) {
            this.setWhere((PlainSelect) select, (String) obj);
        } else if (select instanceof SetOperationList setOperationList) {
            List<Select> selectBodyList = setOperationList.getSelects();
            selectBodyList.forEach(s -> this.setWhere((PlainSelect) s, (String) obj));
        }
    }
    /**
     * å¤„理 UPDATE è¯­å¥ä¸­çš„ WHERE æ¡ä»¶
     *
     * @param update UPDATE æŸ¥è¯¢å¯¹è±¡
     * @param index  æŸ¥è¯¢è¯­å¥çš„索引
     * @param sql    æŸ¥è¯¢è¯­å¥
     * @param obj    WHERE æ¡ä»¶å‚æ•°
     */
    @Override
    protected void processUpdate(Update update, int index, String sql, Object obj) {
        Expression sqlSegment = dataPermissionHandler.getSqlSegment(update.getWhere(), (String) obj, false);
        if (null != sqlSegment) {
            update.setWhere(sqlSegment);
        }
    }
    /**
     * å¤„理 DELETE è¯­å¥ä¸­çš„ WHERE æ¡ä»¶
     *
     * @param delete DELETE æŸ¥è¯¢å¯¹è±¡
     * @param index  æŸ¥è¯¢è¯­å¥çš„索引
     * @param sql    æŸ¥è¯¢è¯­å¥
     * @param obj    WHERE æ¡ä»¶å‚æ•°
     */
    @Override
    protected void processDelete(Delete delete, int index, String sql, Object obj) {
        Expression sqlSegment = dataPermissionHandler.getSqlSegment(delete.getWhere(), (String) obj, false);
        if (null != sqlSegment) {
            delete.setWhere(sqlSegment);
        }
    }
    /**
     * è®¾ç½® SELECT è¯­å¥çš„ WHERE æ¡ä»¶
     *
     * @param plainSelect       SELECT æŸ¥è¯¢å¯¹è±¡
     * @param mappedStatementId æ˜ å°„语句的 ID
     */
    protected void setWhere(PlainSelect plainSelect, String mappedStatementId) {
        Expression sqlSegment = dataPermissionHandler.getSqlSegment(plainSelect.getWhere(), mappedStatementId, true);
        if (null != sqlSegment) {
            plainSelect.setWhere(sqlSegment);
        }
    }
    /**
     * æž„建表达式,用于处理表的数据权限
     *
     * @param table        è¡¨å¯¹è±¡
     * @param where        WHERE æ¡ä»¶è¡¨è¾¾å¼
     * @param whereSegment WHERE æ¡ä»¶ç‰‡æ®µ
     * @return æž„建的表达式
     */
    @Override
    public Expression buildTableExpression(Table table, Expression where, String whereSegment) {
        // åªæœ‰æ–°ç‰ˆæ•°æ®æƒé™å¤„理器才会执行到这里
        final MultiDataPermissionHandler handler = (MultiDataPermissionHandler) dataPermissionHandler;
        return handler.getSqlSegment(table, where, whereSegment);
    }
}
ruoyi-common/ruoyi-common-mybatis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1 @@
org.ruoyi.common.mybatis.config.MybatisPlusConfig
org.ruoyi.config.MybatisPlusConfig
ruoyi-common/ruoyi-common-mybatis/src/main/resources/common-mybatis.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
# å†…置配置 ä¸å…è®¸ä¿®æ”¹ å¦‚需修改请在 nacos ä¸Šå†™ç›¸åŒé…ç½®è¦†ç›–
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
  # å¯åŠ¨æ—¶æ˜¯å¦æ£€æŸ¥ MyBatis XML æ–‡ä»¶çš„存在,默认不检查
  checkConfigLocation: false
  configuration:
    # è‡ªåŠ¨é©¼å³°å‘½åè§„åˆ™ï¼ˆcamel case)映射
    mapUnderscoreToCamelCase: true
    # MyBatis è‡ªåŠ¨æ˜ å°„ç­–ç•¥
    # NONE:不启用 PARTIAL:只对非嵌套 resultMap è‡ªåŠ¨æ˜ å°„ FULL:对所有 resultMap è‡ªåŠ¨æ˜ å°„
    autoMappingBehavior: FULL
    # MyBatis è‡ªåŠ¨æ˜ å°„æ—¶æœªçŸ¥åˆ—æˆ–æœªçŸ¥å±žæ€§å¤„ç†ç­–
    # NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
    autoMappingUnknownColumnBehavior: NONE
    # æ›´è¯¦ç»†çš„æ—¥å¿—输出 ä¼šæœ‰æ€§èƒ½æŸè€— org.apache.ibatis.logging.stdout.StdOutImpl
    # å…³é—­æ—¥å¿—记录 (可单纯使用 p6spy åˆ†æž) org.apache.ibatis.logging.nologging.NoLoggingImpl
    # é»˜è®¤æ—¥å¿—输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
    logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
  global-config:
    # æ˜¯å¦æ‰“印 Logo banner
    banner: true
    dbConfig:
      # ä¸»é”®ç±»åž‹
      # AUTO è‡ªå¢ž NONE ç©º INPUT ç”¨æˆ·è¾“å…¥ ASSIGN_ID é›ªèб ASSIGN_UUID å”¯ä¸€ UUID
      idType: ASSIGN_ID
      # é€»è¾‘已删除值(可按需求随意修改)
      logicDeleteValue: 1
      # é€»è¾‘未删除值
      logicNotDeleteValue: 0
      insertStrategy: NOT_NULL
      updateStrategy: NOT_NULL
      whereStrategy: NOT_NULL
ruoyi-common/ruoyi-common-mybatis/src/main/resources/spy.properties
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
# p6spy æ€§èƒ½åˆ†æžæ’件配置文件
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
# è‡ªå®šä¹‰æ—¥å¿—打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# ä½¿ç”¨æ—¥å¿—系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# å–消JDBC URL前缀
useprefix=true
# é…ç½®è®°å½• Log ä¾‹å¤–,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# æ—¥æœŸæ ¼å¼
dateformat=yyyy-MM-dd HH:mm:ss
# SQL语句打印时间格式
databaseDialectTimestampFormat=yyyy-MM-dd HH:mm:ss
# æ˜¯å¦è¿‡æ»¤ Log
filter=true
# è¿‡æ»¤ Log æ—¶æ‰€æŽ’除的 sql å…³é”®å­—,以逗号分隔
exclude=
ruoyi-common/ruoyi-common-satoken/src/main/java/org/ruoyi/common/satoken/utils/LoginHelper.java
@@ -166,4 +166,16 @@
        return isTenantAdmin(getLoginUser().getRolePermission());
    }
    /**
     * æ£€æŸ¥å½“前用户是否已登录
     *
     * @return ç»“æžœ
     */
    public static boolean isLogin() {
        try {
            return getLoginUser() != null;
        } catch (Exception e) {
            return false;
        }
    }
}
ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/config/TenantConfig.java
@@ -6,7 +6,7 @@
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import org.ruoyi.common.core.utils.reflect.ReflectUtils;
import org.ruoyi.common.mybatis.config.MybatisPlusConfig;
import org.ruoyi.common.redis.config.RedisConfig;
import org.ruoyi.common.redis.config.properties.RedissonProperties;
import org.ruoyi.common.tenant.core.TenantSaTokenDao;
@@ -17,6 +17,7 @@
import org.redisson.config.ClusterServersConfig;
import org.redisson.config.SingleServerConfig;
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
import org.ruoyi.config.MybatisPlusConfig;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/core/TenantEntity.java
@@ -2,7 +2,8 @@
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
/**
 * ç§Ÿæˆ·åŸºç±»
ruoyi-common/ruoyi-common-tenant/src/main/java/org/ruoyi/common/tenant/helper/TenantHelper.java
@@ -95,6 +95,27 @@
    }
    /**
     * è®¾ç½®åŠ¨æ€ç§Ÿæˆ·(一直有效 éœ€è¦æ‰‹åŠ¨æ¸…ç†)
     * <p>
     * å¦‚果为未登录状态下 é‚£ä¹ˆåªåœ¨å½“前线程内生效
     *
     * @param tenantId ç§Ÿæˆ·id
     * @param global   æ˜¯å¦å…¨å±€ç”Ÿæ•ˆ
     */
    public static void setDynamic(String tenantId, boolean global) {
        if (!isEnable()) {
            return;
        }
        if (!LoginHelper.isLogin() || !global) {
            TEMP_DYNAMIC_TENANT.set(tenantId);
            return;
        }
        String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId();
        RedisUtils.setCacheObject(cacheKey, tenantId);
        SaHolder.getStorage().set(cacheKey, tenantId);
    }
    /**
     * èŽ·å–åŠ¨æ€ç§Ÿæˆ·(一直有效 éœ€è¦æ‰‹åŠ¨æ¸…ç†)
     * <p>
     * å¦‚果为非web环境 é‚£ä¹ˆåªåœ¨å½“前线程内生效
@@ -137,4 +158,18 @@
        return tenantId;
    }
    /**
     * åœ¨åŠ¨æ€ç§Ÿæˆ·ä¸­æ‰§è¡Œ
     *
     * @param handle å¤„理执行方法
     */
    public static void dynamic(String tenantId, Runnable handle) {
        setDynamic(tenantId);
        try {
            handle.run();
        } finally {
            clearDynamic();
        }
    }
}
ruoyi-extend/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
<?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">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>ruoyi-ai</artifactId>
        <groupId>org.ruoyi</groupId>
        <version>${revision}</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>ruoyi-extend</artifactId>
    <packaging>pom</packaging>
    <modules>
        <module>ruoyi-mcp-server</module>
    </modules>
</project>
ruoyi-extend/ruoyi-mcp-server/pom.xml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
<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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.ruoyi</groupId>
        <artifactId>ruoyi-ai</artifactId>
        <version>${revision}</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <artifactId>ruoyi-mcp-server</artifactId>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.0.0-M6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-system-api</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.ruoyi</groupId>
                    <artifactId>ruoyi-common-translation</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcp/McpServerApplication.java
ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcp/config/McpServerConfig.java
ruoyi-extend/ruoyi-mcp-server/src/main/java/org/ruoyi/mcp/service/McpCustomService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package org.ruoyi.mcp.service;
import lombok.RequiredArgsConstructor;
import org.ruoyi.system.domain.vo.SysUserVo;
import org.ruoyi.system.mapper.SysUserMapper;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;
/**
 * @author ageer
 */
@Service
@RequiredArgsConstructor
public class McpCustomService {
   private final SysUserMapper userMapper;
   public record User(String userName, Double userBalance) {
   }
   @Tool(description = "根据用户名称查询用户信息")
   public User getUserBalance(String username) {
      SysUserVo sysUserVo = userMapper.selectUserByUserName(username);
      return new User(sysUserVo.getUserName(),sysUserVo.getUserBalance());
   }
}
ruoyi-extend/ruoyi-mcp-server/src/main/resources/application-dev.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
--- # ç›‘控中心配置
spring.boot.admin.client:
  # å¢žåŠ å®¢æˆ·ç«¯å¼€å…³
  enabled: false
  url: http://localhost:9090/admin
  instance:
    service-host-type: IP
  username: ruoyi
  password: 123456
--- # æ•°æ®æºé…ç½®
spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    # åŠ¨æ€æ•°æ®æºæ–‡æ¡£ https://www.kancloud.cn/tracy5546/dynamic-datasource/content
    dynamic:
      # æ€§èƒ½åˆ†æžæ’ä»¶(有性能损耗 ä¸å»ºè®®ç”Ÿäº§çŽ¯å¢ƒä½¿ç”¨)
      p6spy: true
      # è®¾ç½®é»˜è®¤çš„æ•°æ®æºæˆ–者数据源组,默认值即为 master
      primary: master
      # ä¸¥æ ¼æ¨¡å¼ åŒ¹é…ä¸åˆ°æ•°æ®æºåˆ™æŠ¥é”™
      strict: true
      datasource:
        # ä¸»åº“数据源
        master:
          type: ${spring.datasource.type}
          driverClassName: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://43.139.70.230:3306/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
          username: ry-vue
          password: xx
      hikari:
        # æœ€å¤§è¿žæŽ¥æ± æ•°é‡
        maxPoolSize: 20
        # æœ€å°ç©ºé—²çº¿ç¨‹æ•°é‡
        minIdle: 10
        # é…ç½®èŽ·å–è¿žæŽ¥ç­‰å¾…è¶…æ—¶çš„æ—¶é—´
        connectionTimeout: 30000
        # æ ¡éªŒè¶…æ—¶æ—¶é—´
        validationTimeout: 5000
        # ç©ºé—²è¿žæŽ¥å­˜æ´»æœ€å¤§æ—¶é—´ï¼Œé»˜è®¤10分钟
        idleTimeout: 600000
        # æ­¤å±žæ€§æŽ§åˆ¶æ± ä¸­è¿žæŽ¥çš„æœ€é•¿ç”Ÿå‘½å‘¨æœŸï¼Œå€¼0表示无限生命周期,默认30分钟
        maxLifetime: 1800000
        # è¿žæŽ¥æµ‹è¯•query(配置检测连接是否有效)
        connectionTestQuery: SELECT 1
        # å¤šä¹…检查一次连接的活性
        keepaliveTime: 30000
--- # redis å•机配置(单机与集群只能开启一个另一个需要注释掉)
spring.data:
  redis:
    # åœ°å€
    host: 127.0.0.1
    # ç«¯å£ï¼Œé»˜è®¤ä¸º6379
    port: 6379
    # æ•°æ®åº“索引
    database: 0
    # å¯†ç (如没有密码请注释掉)
    # password: 123456
    # è¿žæŽ¥è¶…æ—¶æ—¶é—´
    timeout: 10S
redisson:
  # redis key前缀
  keyPrefix:
  # çº¿ç¨‹æ± æ•°é‡
  threads: 4
  # Netty线程池数量
  nettyThreads: 8
  # å•节点配置
  singleServerConfig:
    # å®¢æˆ·ç«¯åç§°
    clientName: ${ruoyi.name}
    # æœ€å°ç©ºé—²è¿žæŽ¥æ•°
    connectionMinimumIdleSize: 8
    # è¿žæŽ¥æ± å¤§å°
    connectionPoolSize: 32
    # è¿žæŽ¥ç©ºé—²è¶…时,单位:毫秒
    idleConnectionTimeout: 10000
    # å‘½ä»¤ç­‰å¾…超时,单位:毫秒
    timeout: 3000
    # å‘布和订阅连接池大小
    subscriptionConnectionPoolSize: 50
--- # sms çŸ­ä¿¡
sms:
  enabled: false
  # é˜¿é‡Œäº‘ dysmsapi.aliyuncs.com
  # è…¾è®¯äº‘ sms.tencentcloudapi.com
  endpoint: "dysmsapi.aliyuncs.com"
  accessKeyId: xxxxxxx
  accessKeySecret: xxxxxx
  signName: æµ‹è¯•
  # è…¾è®¯ä¸“用
  sdkAppId:
ruoyi-extend/ruoyi-mcp-server/src/main/resources/application-mcp.yml
ruoyi-extend/ruoyi-mcp-server/src/main/resources/application.yml
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,332 @@
# é¡¹ç›®ç›¸å…³é…ç½®
ruoyi:
  # åç§°
  name: "ruoyi"
  # ç‰ˆæœ¬
  version: ${revision}
  # ç‰ˆæƒå¹´ä»½
  copyrightYear: 2025
  # å®žä¾‹æ¼”示开关
  demoEnabled: true
  # èŽ·å–ip地址开关
  addressEnabled: false
captcha:
  enable: false
  # é¡µé¢ <参数设置> å¯å¼€å¯å…³é—­ éªŒè¯ç æ ¡éªŒ
  # éªŒè¯ç ç±»åž‹ math æ•°ç»„计算 char å­—符验证
  type: MATH
  # line çº¿æ®µå¹²æ‰° circle åœ†åœˆå¹²æ‰° shear æ‰­æ›²å¹²æ‰°
  category: CIRCLE
  # æ•°å­—验证码位数
  numberLength: 1
  # å­—符验证码长度
  charLength: 4
# å¼€å‘环境配置
server:
  # æœåŠ¡å™¨çš„HTTP端口,默认为8080
  port: 6040
  servlet:
    # åº”用的访问路径
    context-path: /
  # undertow é…ç½®
  undertow:
    # HTTP post内容的最大大小。当值为-1时,默认值为大小是无限的
    max-http-post-size: -1
    # ä»¥ä¸‹çš„配置会影响buffer,这些buffer会用于服务器连接的IO操作,有点类似netty的池化内存管理
    # æ¯å—buffer的空间大小,越小的空间被利用越充分
    buffer-size: 512
    # æ˜¯å¦åˆ†é…çš„直接内存
    direct-buffers: true
    threads:
      # è®¾ç½®IO线程数, å®ƒä¸»è¦æ‰§è¡Œéžé˜»å¡žçš„任务,它们会负责多个连接, é»˜è®¤è®¾ç½®æ¯ä¸ªCPU核心一个线程
      io: 8
      # é˜»å¡žä»»åŠ¡çº¿ç¨‹æ± , å½“执行类似servlet请求阻塞操作, undertow会从这个线程池中取得线程,它的值设置取决于系统的负载
      worker: 256
# ç”¨æˆ·é…ç½®
user:
  password:
    # å¯†ç æœ€å¤§é”™è¯¯æ¬¡æ•°
    maxRetryCount: 5
    # å¯†ç é”å®šæ—¶é—´ï¼ˆé»˜è®¤10分钟)
    lockTime: 10
# Spring配置
spring:
  application:
    name: ${ruoyi.name}
  # èµ„源信息
  messages:
    # å›½é™…化资源文件路径
    basename: i18n/messages
  profiles:
    active: @profiles.active@
  # æ–‡ä»¶ä¸Šä¼ 
  servlet:
    multipart:
      # å•个文件大小
      max-file-size: 50MB
      # è®¾ç½®æ€»ä¸Šä¼ çš„æ–‡ä»¶å¤§å°
      max-request-size: 200MB
  mvc:
    format:
      date-time: yyyy-MM-dd HH:mm:ss
  jackson:
    # æ—¥æœŸæ ¼å¼åŒ–
    date-format: yyyy-MM-dd HH:mm:ss
    serialization:
      # æ ¼å¼åŒ–输出
      indent_output: false
      # å¿½ç•¥æ— æ³•转换的对象
      fail_on_empty_beans: false
    deserialization:
      # å…è®¸å¯¹è±¡å¿½ç•¥json中不存在的属性
      fail_on_unknown_properties: false
# Sa-Token配置
sa-token:
  # token名称 (同时也是cookie名称)
  token-name: Authorization
  # token有效期 è®¾ä¸º7天 (必定过期) å•位: ç§’
  timeout: 604800
  # token临时有效期 (指定时间无操作就过期) å•位: ç§’
  activity-timeout: 604800
  # æ˜¯å¦å…è®¸åŒä¸€è´¦å·å¹¶å‘登录 (为true时允许一起登录, ä¸ºfalse时新登录挤掉旧登录)
  is-concurrent: true
  # åœ¨å¤šäººç™»å½•同一账号时,是否共用一个token (为true时所有登录共用一个token, ä¸ºfalse时每次登录新建一个token)
  is-share: false
  # æ˜¯å¦å°è¯•从header里读取token
  is-read-header: true
  # æ˜¯å¦å°è¯•从cookie里读取token
  is-read-cookie: false
  # token前缀
  token-prefix: "Bearer"
  # jwt秘钥
  jwt-secret-key: abcdefghijklmnopqrstuvwxyz
# security配置
security:
  # æŽ’除路径
  excludes:
    # æ”¯ä»˜å›žè°ƒ
    - /pay/returnUrl
    - /pay/notifyUrl
    # ä¸Šä¼ æ–‡ä»¶
    - /resource/oss/upload
    # é‡ç½®å¯†ç 
    - /auth/reset/password
    # èŠå¤©æŽ¥å£
    - /chat
    # é™æ€èµ„源
    - /*.html
    - /**/*.html
    - /**/*.css
    - /**/*.js
    # å…¬å…±è·¯å¾„
    - /favicon.ico
    - /error
    # swagger æ–‡æ¡£é…ç½®
    - /*/api-docs
    - /*/api-docs/**
    # actuator ç›‘控配置
    - /actuator
    - /actuator/**
# å¤šç§Ÿæˆ·é…ç½®
tenant:
  # æ˜¯å¦å¼€å¯
  enable: false
  # æŽ’除表
  excludes:
    - sys_menu
    - sys_tenant
    - sys_tenant_package
    - sys_role_dept
    - sys_role_menu
    - sys_user_post
    - sys_user_role
# MyBatisPlus配置
# https://baomidou.com/config/
mybatis-plus:
  # ä¸æ”¯æŒå¤šåŒ…, å¦‚有需要可在注解配置 æˆ– æå‡æ‰«åŒ…等级
  # ä¾‹å¦‚ com.**.**.mapper
  mapperPackage: org.ruoyi.**.mapper
  # å¯¹åº”çš„ XML æ–‡ä»¶ä½ç½®
  mapperLocations: classpath*:mapper/**/*Mapper.xml
  # å®žä½“扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: org.ruoyi.**.domain
  # å¯åŠ¨æ—¶æ˜¯å¦æ£€æŸ¥ MyBatis XML æ–‡ä»¶çš„存在,默认不检查
  checkConfigLocation: false
  configuration:
    # è‡ªåŠ¨é©¼å³°å‘½åè§„åˆ™ï¼ˆcamel case)映射
    mapUnderscoreToCamelCase: true
    # MyBatis è‡ªåŠ¨æ˜ å°„ç­–ç•¥
    # NONE:不启用 PARTIAL:只对非嵌套 resultMap è‡ªåŠ¨æ˜ å°„ FULL:对所有 resultMap è‡ªåŠ¨æ˜ å°„
    autoMappingBehavior: FULL
    # MyBatis è‡ªåŠ¨æ˜ å°„æ—¶æœªçŸ¥åˆ—æˆ–æœªçŸ¥å±žæ€§å¤„ç†ç­–
    # NONE:不做处理 WARNING:打印相关警告 FAILING:抛出异常和详细信息
    autoMappingUnknownColumnBehavior: NONE
    # æ›´è¯¦ç»†çš„æ—¥å¿—输出 ä¼šæœ‰æ€§èƒ½æŸè€— org.apache.ibatis.logging.stdout.StdOutImpl
    # å…³é—­æ—¥å¿—记录 (可单纯使用 p6spy åˆ†æž) org.apache.ibatis.logging.nologging.NoLoggingImpl
    # é»˜è®¤æ—¥å¿—输出 org.apache.ibatis.logging.slf4j.Slf4jImpl
    logImpl: org.apache.ibatis.logging.nologging.NoLoggingImpl
  global-config:
    # æ˜¯å¦æ‰“印 Logo banner
    banner: true
    dbConfig:
      # ä¸»é”®ç±»åž‹
      # AUTO è‡ªå¢ž NONE ç©º INPUT ç”¨æˆ·è¾“å…¥ ASSIGN_ID é›ªèб ASSIGN_UUID å”¯ä¸€ UUID
      idType: ASSIGN_ID
      # é€»è¾‘已删除值
      logicDeleteValue: 2
      # é€»è¾‘未删除值
      logicNotDeleteValue: 0
      # å­—段验证策略之 insert,在 insert çš„æ—¶å€™çš„字段验证策略
      # IGNORED å¿½ç•¥ NOT_NULL éžNULL NOT_EMPTY éžç©º DEFAULT é»˜è®¤ NEVER ä¸åŠ å…¥ SQL
      insertStrategy: NOT_NULL
      # å­—段验证策略之 update,在 update çš„æ—¶å€™çš„字段验证策略
      updateStrategy: NOT_NULL
      # å­—段验证策略之 select,在 select çš„æ—¶å€™çš„字段验证策略既 wrapper æ ¹æ®å†…部 entity ç”Ÿæˆçš„ where æ¡ä»¶
      where-strategy: NOT_NULL
# æ•°æ®åР坆
mybatis-encryptor:
  # æ˜¯å¦å¼€å¯åР坆
  enable: false
  # é»˜è®¤åŠ å¯†ç®—æ³•
  algorithm: BASE64
  # ç¼–码方式 BASE64/HEX。默认BASE64
  encode: BASE64
  # å®‰å…¨ç§˜é’¥ å¯¹ç§°ç®—法的秘钥 å¦‚:AES,SM4
  password:
  # å…¬ç§é’¥ éžå¯¹ç§°ç®—法的公私钥 å¦‚:SM2,RSA
  publicKey:
  privateKey:
# Swagger配置
swagger:
  info:
    # æ ‡é¢˜
    title: '标题:${ruoyi.name}多租户管理系统_接口文档'
    # æè¿°
    description: '描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...'
    # ç‰ˆæœ¬
    version: '版本号: ${ruoyi.version}'
    # ä½œè€…信息
    contact:
      name: ageerle
      email: ageerle@163.com
      url: https://gitee.com/ageerle/ruoyi-ai
  components:
    # é‰´æƒæ–¹å¼é…ç½®
    security-schemes:
      apiKey:
        type: APIKEY
        in: HEADER
        name: ${sa-token.token-name}
springdoc:
  api-docs:
    # æ˜¯å¦å¼€å¯æŽ¥å£æ–‡æ¡£
    enabled: true
  swagger-ui:
    # æŒä¹…化认证数据
    persistAuthorization: true
  #这里定义了两个分组,可定义多个,也可以不定义
  group-configs:
    - group: 1.演示模块
      packages-to-scan: org.ruoyi.demo
    - group: 2.通用模块
      packages-to-scan: org.ruoyi.web
    - group: 3.系统模块
      packages-to-scan: org.ruoyi.system
    - group: 4.代码生成模块
      packages-to-scan: org.ruoyi.generator
# é˜²æ­¢XSS攻击
xss:
  # è¿‡æ»¤å¼€å…³
  enabled: true
  # æŽ’除链接(多个用逗号分隔)
  excludes: /system/notice
  # åŒ¹é…é“¾æŽ¥
  urlPatterns: /system/*,/monitor/*,/tool/*
# å…¨å±€çº¿ç¨‹æ± ç›¸å…³é…ç½®
thread-pool:
  # æ˜¯å¦å¼€å¯çº¿ç¨‹æ± 
  enabled: false
  # é˜Ÿåˆ—最大长度
  queueCapacity: 128
  # çº¿ç¨‹æ± ç»´æŠ¤çº¿ç¨‹æ‰€å…è®¸çš„空闲时间
  keepAliveSeconds: 300
--- # åˆ†å¸ƒå¼é” lock4j å…¨å±€é…ç½®
lock4j:
  # èŽ·å–åˆ†å¸ƒå¼é”è¶…æ—¶æ—¶é—´ï¼Œé»˜è®¤ä¸º 3000 æ¯«ç§’
  acquire-timeout: 3000
  # åˆ†å¸ƒå¼é”çš„超时时间,默认为 30 ç§’
  expire: 30000
--- # Actuator ç›‘控端点的配置项
management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: ALWAYS
    logfile:
      external-file: ./logs/sys-console.log
# websocket
websocket:
  enabled: true
  # è·¯å¾„
  path: '/resource/websocket'
  # è®¾ç½®è®¿é—®æºåœ°å€
  allowedOrigins: '*'
# å¾®ä¿¡å°ç¨‹åºé…ç½®ä¿¡æ¯
wx:
  miniapp:
    configs:
      - appid: # ä½ çš„appid
        secret: # ä½ çš„secret
        token: #微信小程序消息服务器配置的token
        aesKey: #微信小程序消息服务器配置的EncodingAESKey
        msgDataFormat: JSON
  #  ä¼ä¸šå¾®ä¿¡åº”用
wechat:
  cp:
    corpId:
    appConfigs:
      - agentId:
        secret: ''
        token:   ''
        aesKey: ''
spring:
  ai:
    openai:
      api-key: sk-xX
      base-url: https://api.pandarobot.chat
    ollama:
      base-url: http://localhost:11434
      init:
        pull-model-strategy: always
        timeout: 60s
        max-retries: 1
    mcp:
      client:
        enabled: true
        name: call-mcp-server
        sse:
          connections:
            server1:
              url: http://127.0.0.1:8080
ruoyi-modules-api/ruoyi-chat-api/pom.xml
@@ -38,34 +38,41 @@
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.ai</groupId>-->
<!--            <artifactId>spring-ai-mcp</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
        </dependency>
<!--        <dependency>-->
<!--            <groupId>org.springframework.ai</groupId>-->
<!--            <artifactId>spring-ai-openai</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-ollama</artifactId>
        </dependency>
    </dependencies>
</project>
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatAgentManage.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatAppStore.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatGpts.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatMessage.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.math.BigDecimal;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatModel.java
@@ -4,7 +4,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatPackagePlan.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.math.BigDecimal;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatPayOrder.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.math.BigDecimal;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatPlugin.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatRobConfig.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatUsageToken.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatVisitorUsage.java
@@ -7,7 +7,7 @@
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
import java.io.Serializable;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/ChatVoucher.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.math.BigDecimal;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatAgentManageBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatAgentManage;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatAppStoreBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatAppStore;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatGptsBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatGpts;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatMessageBo.java
@@ -2,7 +2,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatModelBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatModel;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatPackagePlanBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatPackagePlan;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatPayOrderBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatPayOrder;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatPluginBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatPlugin;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatRobConfigBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatRobConfig;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatUsageTokenBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatUsageToken;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatVisitorUsageBo.java
@@ -7,7 +7,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.domain.ChatVisitorUsage;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/bo/ChatVoucherBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.ChatVoucher;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/CacheListInfoVo.java
ÎļþÒÑɾ³ý
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/domain/vo/CaptchaVo.java
ÎļþÒÑɾ³ý
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatAgentManageMapper.java
@@ -3,7 +3,7 @@
import org.ruoyi.domain.ChatAgentManage;
import org.ruoyi.domain.vo.ChatAgentManageVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * æ™ºèƒ½ä½“管理Mapper接口
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatAppStoreMapper.java
@@ -3,7 +3,7 @@
import org.ruoyi.domain.ChatAppStore;
import org.ruoyi.domain.vo.ChatAppStoreVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * åº”用商店Mapper接口
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatGptsMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatGpts;
import org.ruoyi.domain.vo.ChatGptsVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatMessageMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatMessage;
import org.ruoyi.domain.vo.ChatMessageVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatModelMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatModel;
import org.ruoyi.domain.vo.ChatModelVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatPackagePlanMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatPackagePlan;
import org.ruoyi.domain.vo.ChatPackagePlanVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatPayOrderMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatPayOrder;
import org.ruoyi.domain.vo.ChatPayOrderVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatPluginMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatPlugin;
import org.ruoyi.domain.vo.ChatPluginVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatRobConfigMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatRobConfig;
import org.ruoyi.domain.vo.ChatRobConfigVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatTokenMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatToken;
import org.ruoyi.domain.vo.ChatTokenVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatUsageTokenMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatUsageToken;
import org.ruoyi.domain.vo.ChatUsageTokenVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatVisitorUsageMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatVisitorUsage;
import org.ruoyi.domain.vo.ChatVisitorUsageVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/mapper/ChatVoucherMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.domain.ChatVoucher;
import org.ruoyi.domain.vo.ChatVoucherVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatAgentManageService.java
@@ -3,8 +3,8 @@
import org.ruoyi.domain.bo.ChatAgentManageBo;
import org.ruoyi.domain.vo.ChatAgentManageVo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatAppStoreService.java
@@ -3,8 +3,8 @@
import org.ruoyi.domain.bo.ChatAppStoreBo;
import org.ruoyi.domain.vo.ChatAppStoreVo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatGptsService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatGptsBo;
import org.ruoyi.domain.vo.ChatGptsVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatMessageService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatMessageBo;
import org.ruoyi.domain.vo.ChatMessageVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatModelService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatModelBo;
import org.ruoyi.domain.vo.ChatModelVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatPackagePlanService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatPackagePlanBo;
import org.ruoyi.domain.vo.ChatPackagePlanVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatPayOrderService.java
@@ -1,7 +1,7 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatPayOrderBo;
import org.ruoyi.domain.vo.ChatPayOrderVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatPluginService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatPluginBo;
import org.ruoyi.domain.vo.ChatPluginVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatUsageTokenService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatUsageTokenBo;
import org.ruoyi.domain.vo.ChatUsageTokenVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatVisitorUsageService.java
@@ -1,7 +1,7 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatVisitorUsageBo;
import org.ruoyi.domain.vo.ChatVisitorUsageVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/IChatVoucherService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.ChatVoucherBo;
import org.ruoyi.domain.vo.ChatVoucherVo;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatAgentManageServiceImpl.java
@@ -3,8 +3,8 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatAppStoreServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatGptsServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatMessageServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatModelServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatPackagePlanServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatPayOrderServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatPluginServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatTokenServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,56 @@
package org.ruoyi.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import org.ruoyi.domain.ChatToken;
import org.ruoyi.mapper.ChatTokenMapper;
import org.ruoyi.service.IChatTokenService;
import org.springframework.stereotype.Service;
/**
 * èŠå¤©æ¶ˆæ¯Service业务层处理
 *
 * @author Lion Li
 * @date 2023-11-26
 */
@RequiredArgsConstructor
@Service
public class ChatTokenServiceImpl implements IChatTokenService {
    private final ChatTokenMapper baseMapper;
    @Override
    public ChatToken queryByUserId(Long userId, String modelName) {
        return baseMapper.selectOne(
            new LambdaQueryWrapper<ChatToken>()
                .eq(ChatToken::getUserId, userId)
                .eq(ChatToken::getModelName, modelName)
                .last("limit 1")
        );
    }
    /**
     * æ¸…空用户token
     *
     */
    @Override
    public void resetToken(Long userId,String modelName) {
        ChatToken chatToken = queryByUserId(userId, modelName);
        chatToken.setToken(0);
        baseMapper.updateById(chatToken);
    }
    /**
     * å¢žåŠ ç”¨æˆ·token
     *
     */
    @Override
    public void editToken(ChatToken chatToken) {
        if(chatToken.getId() == null){
            baseMapper.insert(chatToken);
        }else {
            baseMapper.updateById(chatToken);
        }
    }
}
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatUsageTokenServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-chat-api/src/main/java/org/ruoyi/service/impl/ChatVoucherServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/KnowledgeAttach.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/KnowledgeFragment.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/KnowledgeInfo.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/bo/KnowledgeAttachBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.KnowledgeAttach;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/bo/KnowledgeFragmentBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.KnowledgeFragment;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/domain/bo/KnowledgeInfoBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.domain.KnowledgeInfo;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/mapper/KnowledgeAttachMapper.java
@@ -3,7 +3,7 @@
import org.ruoyi.domain.KnowledgeAttach;
import org.ruoyi.domain.vo.KnowledgeAttachVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * çŸ¥è¯†åº“附件Mapper接口
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/mapper/KnowledgeFragmentMapper.java
@@ -3,7 +3,7 @@
import org.ruoyi.domain.KnowledgeFragment;
import org.ruoyi.domain.vo.KnowledgeFragmentVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * çŸ¥è¯†ç‰‡æ®µMapper接口
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/mapper/KnowledgeInfoMapper.java
@@ -3,7 +3,7 @@
import org.ruoyi.domain.KnowledgeInfo;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * çŸ¥è¯†åº“Mapper接口
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/IKnowledgeAttachService.java
@@ -3,8 +3,8 @@
import org.ruoyi.domain.bo.KnowledgeAttachBo;
import org.ruoyi.domain.vo.KnowledgeAttachVo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/IKnowledgeFragmentService.java
@@ -1,8 +1,8 @@
package org.ruoyi.service;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.domain.bo.KnowledgeFragmentBo;
import org.ruoyi.domain.vo.KnowledgeFragmentVo;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/IKnowledgeInfoService.java
@@ -3,8 +3,8 @@
import org.ruoyi.domain.bo.KnowledgeInfoBo;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import java.util.Collection;
import java.util.List;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/KnowledgeAttachServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/KnowledgeFragmentServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/KnowledgeInfoServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/impl/WeaviateVectorStoreImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,402 @@
package org.ruoyi.service.impl;
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONObject;
import com.google.gson.internal.LinkedTreeMap;
import io.weaviate.client.Config;
import io.weaviate.client.WeaviateClient;
import io.weaviate.client.base.Result;
import io.weaviate.client.v1.data.model.WeaviateObject;
import io.weaviate.client.v1.data.replication.model.ConsistencyLevel;
import io.weaviate.client.v1.filters.Operator;
import io.weaviate.client.v1.filters.WhereFilter;
import io.weaviate.client.v1.graphql.model.GraphQLResponse;
import io.weaviate.client.v1.graphql.query.argument.NearTextArgument;
import io.weaviate.client.v1.graphql.query.argument.NearVectorArgument;
import io.weaviate.client.v1.graphql.query.fields.Field;
import io.weaviate.client.v1.misc.model.Meta;
import io.weaviate.client.v1.misc.model.ReplicationConfig;
import io.weaviate.client.v1.misc.model.ShardingConfig;
import io.weaviate.client.v1.misc.model.VectorIndexConfig;
import io.weaviate.client.v1.schema.model.DataType;
import io.weaviate.client.v1.schema.model.Property;
import io.weaviate.client.v1.schema.model.Schema;
import io.weaviate.client.v1.schema.model.WeaviateClass;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.ruoyi.common.core.service.ConfigService;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.service.IKnowledgeInfoService;
import org.ruoyi.service.VectorStoreService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
@Slf4j
public class WeaviateVectorStoreImpl implements VectorStoreService {
    private volatile String protocol;
    private volatile String host;
    private volatile String className;
    @Lazy
    @Resource
    private IKnowledgeInfoService knowledgeInfoService;
    @Lazy
    @Resource
    private ConfigService configService;
    @PostConstruct
    public void loadConfig() {
        this.protocol = configService.getConfigValue("weaviate", "protocol");
        this.host = configService.getConfigValue("weaviate", "host");
        this.className = configService.getConfigValue("weaviate", "classname");
    }
    public WeaviateClient getClient() {
        Config config = new Config(protocol, host);
        WeaviateClient client = new WeaviateClient(config);
        return client;
    }
    public Result<Meta> getMeta() {
        WeaviateClient client = getClient();
        Result<Meta> meta = client.misc().metaGetter().run();
        if (meta.getError() == null) {
            System.out.printf("meta.hostname: %s\n", meta.getResult().getHostname());
            System.out.printf("meta.version: %s\n", meta.getResult().getVersion());
            System.out.printf("meta.modules: %s\n", meta.getResult().getModules());
        } else {
            System.out.printf("Error: %s\n", meta.getError().getMessages());
        }
        return meta;
    }
    public Result<Schema> getSchemas() {
        WeaviateClient client = getClient();
        Result<Schema> result = client.schema().getter().run();
        if (result.hasErrors()) {
            System.out.println(result.getError());
        } else {
            System.out.println(result.getResult());
        }
        return result;
    }
    public Result<Boolean> createSchema(String kid) {
        WeaviateClient client = getClient();
        VectorIndexConfig vectorIndexConfig = VectorIndexConfig.builder()
                .distance("cosine")
                .cleanupIntervalSeconds(300)
                .efConstruction(128)
                .maxConnections(64)
                .vectorCacheMaxObjects(500000L)
                .ef(-1)
                .skip(false)
                .dynamicEfFactor(8)
                .dynamicEfMax(500)
                .dynamicEfMin(100)
                .flatSearchCutoff(40000)
                .build();
        ShardingConfig shardingConfig = ShardingConfig.builder()
                .desiredCount(3)
                .desiredVirtualCount(128)
                .function("murmur3")
                .key("_id")
                .strategy("hash")
                .virtualPerPhysical(128)
                .build();
        ReplicationConfig replicationConfig = ReplicationConfig.builder()
                .factor(1)
                .build();
        JSONObject classModuleConfigValue = new JSONObject();
        classModuleConfigValue.put("vectorizeClassName", false);
        JSONObject classModuleConfig = new JSONObject();
        classModuleConfig.put("text2vec-transformers", classModuleConfigValue);
        JSONObject propertyModuleConfigValueSkipTrue = new JSONObject();
        propertyModuleConfigValueSkipTrue.put("vectorizePropertyName", false);
        propertyModuleConfigValueSkipTrue.put("skip", true);
        JSONObject propertyModuleConfigSkipTrue = new JSONObject();
        propertyModuleConfigSkipTrue.put("text2vec-transformers", propertyModuleConfigValueSkipTrue);
        JSONObject propertyModuleConfigValueSkipFalse = new JSONObject();
        propertyModuleConfigValueSkipFalse.put("vectorizePropertyName", false);
        propertyModuleConfigValueSkipFalse.put("skip", false);
        JSONObject propertyModuleConfigSkipFalse = new JSONObject();
        propertyModuleConfigSkipFalse.put("text2vec-transformers", propertyModuleConfigValueSkipFalse);
        WeaviateClass clazz = WeaviateClass.builder()
                .className(className + kid)
                .description("local knowledge")
                .vectorIndexType("hnsw")
                .vectorizer("text2vec-transformers")
                .shardingConfig(shardingConfig)
                .vectorIndexConfig(vectorIndexConfig)
                .replicationConfig(replicationConfig)
                .moduleConfig(classModuleConfig)
                .properties(new ArrayList() {
                    {
                        add(Property.builder()
                                .dataType(new ArrayList() {
                                    {
                                        add(DataType.TEXT);
                                    }
                                })
                                .name("content")
                                .description("The content of the local knowledge,for search")
                                .moduleConfig(propertyModuleConfigSkipFalse)
                                .build());
                        add(Property.builder()
                                .dataType(new ArrayList() {
                                    {
                                        add(DataType.TEXT);
                                    }
                                })
                                .name("kid")
                                .description("The knowledge id of the local knowledge,for search")
                                .moduleConfig(propertyModuleConfigSkipTrue)
                                .build());
                        add(Property.builder()
                                .dataType(new ArrayList() {
                                    {
                                        add(DataType.TEXT);
                                    }
                                })
                                .name("docId")
                                .description("The doc id of the local knowledge,for search")
                                .moduleConfig(propertyModuleConfigSkipTrue)
                                .build());
                        add(Property.builder()
                                .dataType(new ArrayList() {
                                    {
                                        add(DataType.TEXT);
                                    }
                                })
                                .name("fid")
                                .description("The fragment id of the local knowledge,for search")
                                .moduleConfig(propertyModuleConfigSkipTrue)
                                .build());
                        add(Property.builder()
                                .dataType(new ArrayList() {
                                    {
                                        add(DataType.TEXT);
                                    }
                                })
                                .name("uuid")
                                .description("The uuid id of the local knowledge fragment(same with id properties),for search")
                                .moduleConfig(propertyModuleConfigSkipTrue)
                                .build());
                    } })
                .build();
        Result<Boolean> result = client.schema().classCreator().withClass(clazz).run();
        if (result.hasErrors()) {
            System.out.println(result.getError());
        }
        System.out.println(result.getResult());
        return result;
    }
    @Override
    public void newSchema(String kid) {
        createSchema(kid);
    }
    @Override
    public void removeByKidAndFid(String kid, String fid) {
        List<String> resultList = new ArrayList<>();
        WeaviateClient client = getClient();
        Field fieldId = Field.builder().name("uuid").build();
        WhereFilter where = WhereFilter.builder()
                .path(new String[]{"fid"})
                .operator(Operator.Equal)
                .valueString(fid)
                .build();
        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName(className + kid)
                .withFields(fieldId)
                .withWhere(where)
                .run();
        LinkedTreeMap<String, Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData();
        LinkedTreeMap<String, ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get");
        ArrayList<LinkedTreeMap> m = l.get(className + kid);
        for (LinkedTreeMap linkedTreeMap : m) {
            String uuid = linkedTreeMap.get("uuid").toString();
            resultList.add(uuid);
        }
        for (String uuid : resultList) {
            Result<Boolean> deleteResult = client.data().deleter()
                    .withID(uuid)
                    .withClassName(className + kid)
                    .withConsistencyLevel(ConsistencyLevel.ALL)  // default QUORUM
                    .run();
        }
    }
    @Override
    public void storeEmbeddings(List<String> chunkList, List<List<Double>> vectorList, String kid, String docId, List<String> fidList) {
        WeaviateClient client = getClient();
        for (int i = 0; i < Math.min(chunkList.size(), vectorList.size()); i++) {
            List<Double> vector = vectorList.get(i);
            Float[] vf = vector.stream().map(Double::floatValue).toArray(Float[]::new);
            Map<String, Object> dataSchema = new HashMap<>();
            dataSchema.put("content", chunkList.get(i));
            dataSchema.put("kid", kid);
            dataSchema.put("docId", docId);
            dataSchema.put("fid", fidList.get(i));
            String uuid = UUID.randomUUID().toString();
            dataSchema.put("uuid", uuid);
            Result<WeaviateObject> result = client.data().creator()
                    .withClassName(className + kid)
                    .withID(uuid)
                    .withVector(vf)
                    .withProperties(dataSchema)
                    .run();
        }
    }
    @Override
    public void removeByDocId(String kid, String docId) {
        List<String> resultList = new ArrayList<>();
        WeaviateClient client = getClient();
        Field fieldId = Field.builder().name("uuid").build();
        WhereFilter where = WhereFilter.builder()
                .path(new String[]{"docId"})
                .operator(Operator.Equal)
                .valueString(docId)
                .build();
        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName(className + kid)
                .withFields(fieldId)
                .withWhere(where)
                .run();
        LinkedTreeMap<String, Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData();
        LinkedTreeMap<String, ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get");
        ArrayList<LinkedTreeMap> m = l.get(className + kid);
        for (LinkedTreeMap linkedTreeMap : m) {
            String uuid = linkedTreeMap.get("uuid").toString();
            resultList.add(uuid);
        }
        for (String uuid : resultList) {
            Result<Boolean> deleteResult = client.data().deleter()
                    .withID(uuid)
                    .withClassName(className + kid)
                    .withConsistencyLevel(ConsistencyLevel.ALL)  // default QUORUM
                    .run();
        }
    }
    @Override
    public void removeByKid(String kid) {
        WeaviateClient client = getClient();
        Result<Boolean> result = client.schema().classDeleter().withClassName(className + kid).run();
        if (result.hasErrors()) {
            System.out.println("删除schema失败" + result.getError());
        } else {
            System.out.println("删除schema成功" + result.getResult());
        }
        log.info("drop schema by kid, result = {}", result);
    }
    @Override
    public List<String> nearest(List<Double> queryVector, String kid) {
        if (StringUtils.isBlank(kid)) {
            return new ArrayList<String>();
        }
        List<String> resultList = new ArrayList<>();
        Float[] vf = new Float[queryVector.size()];
        for (int j = 0; j < queryVector.size(); j++) {
            Double value = queryVector.get(j);
            vf[j] = value.floatValue();
        }
        WeaviateClient client = getClient();
        Field contentField = Field.builder().name("content").build();
        Field _additional = Field.builder()
                .name("_additional")
                .fields(new Field[]{
                        Field.builder().name("distance").build()
                }).build();
        NearVectorArgument nearVector = NearVectorArgument.builder()
                .vector(vf)
                .distance(1.6f) // certainty = 1f - distance /2f
                .build();
        KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid));
        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName(className + kid)
                .withFields(contentField, _additional)
                .withNearVector(nearVector)
                .withLimit(knowledgeInfoVo.getRetrieveLimit())
                .run();
        LinkedTreeMap<String, Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData();
        LinkedTreeMap<String, ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get");
        ArrayList<LinkedTreeMap> m = l.get(className + kid);
        for (LinkedTreeMap linkedTreeMap : m) {
            String content = linkedTreeMap.get("content").toString();
            resultList.add(content);
        }
        return resultList;
    }
    @Override
    public List<String> nearest(String query, String kid) {
        if (StringUtils.isBlank(kid)) {
            return new ArrayList<String>();
        }
        List<String> resultList = new ArrayList<>();
        WeaviateClient client = getClient();
        Field contentField = Field.builder().name("content").build();
        Field _additional = Field.builder()
                .name("_additional")
                .fields(new Field[]{
                        Field.builder().name("distance").build()
                }).build();
        NearTextArgument nearText = client.graphQL().arguments().nearTextArgBuilder()
                .concepts(new String[]{query})
                .distance(1.6f) // certainty = 1f - distance /2f
                .build();
        KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid));
        Result<GraphQLResponse> result = client.graphQL().get()
                .withClassName(className + kid)
                .withFields(contentField, _additional)
                .withNearText(nearText)
                .withLimit(knowledgeInfoVo.getRetrieveLimit())
                .run();
        LinkedTreeMap<String, Object> t = (LinkedTreeMap<String, Object>) result.getResult().getData();
        LinkedTreeMap<String, ArrayList<LinkedTreeMap>> l = (LinkedTreeMap<String, ArrayList<LinkedTreeMap>>) t.get("Get");
        ArrayList<LinkedTreeMap> m = l.get(className + kid);
        for (LinkedTreeMap linkedTreeMap : m) {
            String content = linkedTreeMap.get("content").toString();
            resultList.add(content);
        }
        return resultList;
    }
    public Result<Boolean> deleteSchema(String kid) {
        WeaviateClient client = getClient();
        Result<Boolean> result = client.schema().classDeleter().withClassName(className + kid).run();
        if (result.hasErrors()) {
            System.out.println(result.getError());
        } else {
            System.out.println(result.getResult());
        }
        return result;
    }
}
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/ChatConfig.java
@@ -7,7 +7,7 @@
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/SysDept.java
@@ -47,7 +47,7 @@
    /**
     * è´Ÿè´£äºº
     */
    private String leader;
    private Long leader;
    /**
     * è”系电话
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/SysMenu.java
@@ -6,7 +6,7 @@
import org.ruoyi.common.core.constant.Constants;
import org.ruoyi.common.core.constant.UserConstants;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/SysNoticeState.java
@@ -4,7 +4,7 @@
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/SysTenant.java
@@ -5,7 +5,7 @@
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import java.io.Serial;
import java.util.Date;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/SysTenantPackage.java
@@ -3,7 +3,7 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/ChatConfigBo.java
@@ -7,7 +7,8 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.ChatConfig;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysConfigBo.java
@@ -8,7 +8,8 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
//import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysConfig;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysDeptBo.java
@@ -9,7 +9,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysDept;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysDictDataBo.java
@@ -2,7 +2,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysDictData;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysDictTypeBo.java
@@ -9,7 +9,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysDictType;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysMenuBo.java
@@ -3,7 +3,7 @@
import com.fasterxml.jackson.annotation.JsonInclude;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysMenu;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysNoticeBo.java
@@ -9,7 +9,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.core.xss.Xss;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysNotice;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysNoticeStateBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.system.domain.SysNoticeState;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysOssBo.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.domain.bo;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysOss;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysOssConfigBo.java
@@ -2,7 +2,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysOssConfig;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysPostBo.java
@@ -8,7 +8,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysPost;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysRoleBo.java
@@ -3,7 +3,7 @@
import org.ruoyi.common.core.constant.UserConstants;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysRole;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysTenantBo.java
@@ -2,7 +2,7 @@
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysTenant;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysTenantPackageBo.java
@@ -8,7 +8,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.system.domain.SysTenantPackage;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysUserBo.java
@@ -9,7 +9,7 @@
import lombok.NoArgsConstructor;
import org.ruoyi.common.core.constant.UserConstants;
import org.ruoyi.common.core.xss.Xss;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.common.sensitive.annotation.Sensitive;
import org.ruoyi.common.sensitive.core.SensitiveStrategy;
import org.ruoyi.system.domain.SysUser;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/domain/bo/SysUserProfileBo.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.domain.bo;
import org.ruoyi.common.core.xss.Xss;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.common.sensitive.annotation.Sensitive;
import org.ruoyi.common.sensitive.core.SensitiveStrategy;
import jakarta.validation.constraints.Email;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/ChatConfigMapper.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.ChatConfig;
import org.ruoyi.system.domain.vo.ChatConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysConfigMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysConfig;
import org.ruoyi.system.domain.vo.SysConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysDeptMapper.java
@@ -3,9 +3,9 @@
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.ruoyi.common.mybatis.annotation.DataColumn;
import org.ruoyi.common.mybatis.annotation.DataPermission;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.annotation.DataColumn;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysDept;
import org.ruoyi.system.domain.vo.SysDeptVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysDictDataMapper.java
@@ -2,7 +2,7 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.ruoyi.common.core.constant.UserConstants;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysDictData;
import org.ruoyi.system.domain.vo.SysDictDataVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysDictTypeMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysDictType;
import org.ruoyi.system.domain.vo.SysDictTypeVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysLogininforMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysLogininfor;
import org.ruoyi.system.domain.vo.SysLogininforVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysMenuMapper.java
@@ -5,7 +5,7 @@
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import org.ruoyi.common.core.constant.UserConstants;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysMenu;
import org.ruoyi.system.domain.vo.SysMenuVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysNoticeMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysNotice;
import org.ruoyi.system.domain.vo.SysNoticeVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysNoticeStateMapper.java
@@ -2,7 +2,7 @@
import org.ruoyi.system.domain.SysNoticeState;
import org.ruoyi.system.domain.vo.SysNoticeStateVo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * ç”¨æˆ·é˜…读状态Mapper接口
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysOperLogMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysOperLog;
import org.ruoyi.system.domain.vo.SysOperLogVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysOssConfigMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysOssConfig;
import org.ruoyi.system.domain.vo.SysOssConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysOssMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysOss;
import org.ruoyi.system.domain.vo.SysOssVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysPostMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysPost;
import org.ruoyi.system.domain.vo.SysPostVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysRoleDeptMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysRoleDept;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysRoleMapper.java
@@ -4,9 +4,9 @@
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.ruoyi.common.mybatis.annotation.DataColumn;
import org.ruoyi.common.mybatis.annotation.DataPermission;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.annotation.DataColumn;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysRole;
import org.ruoyi.system.domain.vo.SysRoleVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysRoleMenuMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysRoleMenu;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysTenantMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysTenant;
import org.ruoyi.system.domain.vo.SysTenantVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysTenantPackageMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysTenantPackage;
import org.ruoyi.system.domain.vo.SysTenantPackageVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysUserMapper.java
@@ -4,9 +4,9 @@
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.ruoyi.common.mybatis.annotation.DataColumn;
import org.ruoyi.common.mybatis.annotation.DataPermission;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.annotation.DataColumn;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysUser;
import org.ruoyi.system.domain.bo.SysUserBo;
import org.ruoyi.system.domain.vo.SysUserVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysUserPostMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysUserPost;
/**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/mapper/SysUserRoleMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.system.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.system.domain.SysUserRole;
import java.util.List;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/IChatConfigService.java
@@ -1,8 +1,8 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.ChatConfigBo;
import org.ruoyi.system.domain.vo.ChatConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysConfigService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysConfigBo;
import org.ruoyi.system.domain.vo.SysConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysDictDataService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysDictDataBo;
import org.ruoyi.system.domain.vo.SysDictDataVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysDictTypeService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysDictTypeBo;
import org.ruoyi.system.domain.vo.SysDictDataVo;
import org.ruoyi.system.domain.vo.SysDictTypeVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysLogininforService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysLogininforBo;
import org.ruoyi.system.domain.vo.SysLogininforVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysNoticeService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysNotice;
import org.ruoyi.system.domain.bo.SysNoticeBo;
import org.ruoyi.system.domain.vo.SysNoticeVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysNoticeStateService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysNoticeStateBo;
import org.ruoyi.system.domain.vo.SysNoticeStateVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysOperLogService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysOperLogBo;
import org.ruoyi.system.domain.vo.SysOperLogVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysOssConfigService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysOssConfigBo;
import org.ruoyi.system.domain.vo.SysOssConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysOssService.java
@@ -1,8 +1,8 @@
package org.ruoyi.system.service;
import jakarta.servlet.http.HttpServletResponse;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysOssBo;
import org.ruoyi.system.domain.vo.SysOssVo;
import org.springframework.web.multipart.MultipartFile;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysPostService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysPostBo;
import org.ruoyi.system.domain.vo.SysPostVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysRoleService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysUserRole;
import org.ruoyi.system.domain.bo.SysRoleBo;
import org.ruoyi.system.domain.vo.SysRoleVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysTenantPackageService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysTenantPackageBo;
import org.ruoyi.system.domain.vo.SysTenantPackageVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysTenantService.java
@@ -1,7 +1,9 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.SysTenantBo;
import org.ruoyi.system.domain.vo.SysTenantVo;
@@ -78,5 +80,10 @@
    /**
     * åŒæ­¥ç§Ÿæˆ·å¥—餐
     */
    Boolean syncTenantPackage(String tenantId, String packageId);
    Boolean syncTenantPackage(String tenantId, Long packageId);
    /**
     * åŒæ­¥ç§Ÿæˆ·å­—å…¸
     */
    void syncTenantDict();
}
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/ISysUserService.java
@@ -1,7 +1,7 @@
package org.ruoyi.system.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysUser;
import org.ruoyi.system.domain.bo.SysUserBo;
import org.ruoyi.system.domain.vo.SysUserVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/ChatConfigServiceImpl.java
@@ -7,8 +7,8 @@
import org.ruoyi.common.core.service.ConfigService;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.ChatConfig;
import org.ruoyi.system.domain.bo.ChatConfigBo;
import org.ruoyi.system.domain.vo.ChatConfigVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysConfigServiceImpl.java
@@ -12,8 +12,8 @@
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.redis.utils.CacheUtils;
import org.ruoyi.common.tenant.helper.TenantHelper;
import org.ruoyi.system.domain.SysConfig;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDataScopeServiceImpl.java
@@ -4,7 +4,7 @@
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.mybatis.helper.DataBaseHelper;
import org.ruoyi.helper.DataBaseHelper;
import org.ruoyi.system.domain.SysDept;
import org.ruoyi.system.domain.SysRoleDept;
import org.ruoyi.system.mapper.SysDeptMapper;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDeptServiceImpl.java
@@ -16,7 +16,7 @@
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.TreeBuildUtils;
import org.ruoyi.common.mybatis.helper.DataBaseHelper;
import org.ruoyi.helper.DataBaseHelper;
import org.ruoyi.common.redis.utils.CacheUtils;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.system.domain.SysDept;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDictDataServiceImpl.java
@@ -8,8 +8,8 @@
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.redis.utils.CacheUtils;
import org.ruoyi.system.domain.SysDictData;
import org.ruoyi.system.domain.bo.SysDictDataBo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysDictTypeServiceImpl.java
@@ -15,8 +15,8 @@
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.redis.utils.CacheUtils;
import org.ruoyi.system.domain.SysDictData;
import org.ruoyi.system.domain.SysDictType;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysLogininforServiceImpl.java
@@ -10,8 +10,8 @@
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.ip.AddressUtils;
import org.ruoyi.common.log.event.LogininforEvent;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysLogininfor;
import org.ruoyi.system.domain.bo.SysLogininforBo;
import org.ruoyi.system.domain.vo.SysLogininforVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysMenuServiceImpl.java
@@ -168,12 +168,12 @@
        List<Long> parentIds = null;
        if (tenantPackage.getMenuCheckStrictly()) {
            parentIds = baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
                .select(SysMenu::getParentId)
                .in(SysMenu::getMenuId, menuIds), Convert::toLong);
                    .select(SysMenu::getParentId)
                    .in(SysMenu::getMenuId, menuIds), x -> {return Convert.toLong(x);});
        }
        return baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
            .in(SysMenu::getMenuId, menuIds)
            .notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), Convert::toLong);
                .in(SysMenu::getMenuId, menuIds)
                .notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds), x -> {return Convert.toLong(x);});
    }
    /**
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysNoticeServiceImpl.java
@@ -8,8 +8,8 @@
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.system.domain.SysNotice;
import org.ruoyi.system.domain.SysNoticeState;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysNoticeStateServiceImpl.java
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysOperLogServiceImpl.java
@@ -8,8 +8,8 @@
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.ip.AddressUtils;
import org.ruoyi.common.log.event.OperLogEvent;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysOperLog;
import org.ruoyi.system.domain.bo.SysOperLogBo;
import org.ruoyi.system.domain.vo.SysOperLogVo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysOssConfigServiceImpl.java
@@ -12,8 +12,8 @@
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.json.utils.JsonUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.oss.constant.OssConstant;
import org.ruoyi.common.redis.utils.CacheUtils;
import org.ruoyi.common.redis.utils.RedisUtils;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysOssServiceImpl.java
@@ -16,8 +16,8 @@
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.file.FileUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.oss.core.OssClient;
import org.ruoyi.common.oss.entity.UploadResult;
import org.ruoyi.common.oss.enumd.AccessPolicyType;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysPostServiceImpl.java
@@ -9,8 +9,8 @@
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysPost;
import org.ruoyi.system.domain.SysUserPost;
import org.ruoyi.system.domain.bo.SysPostBo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysRoleServiceImpl.java
@@ -17,8 +17,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.system.domain.SysRole;
import org.ruoyi.system.domain.SysRoleDept;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysTenantPackageServiceImpl.java
@@ -9,8 +9,8 @@
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.SysTenant;
import org.ruoyi.system.domain.SysTenantPackage;
import org.ruoyi.system.domain.bo.SysTenantPackageBo;
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysTenantServiceImpl.java
@@ -1,36 +1,42 @@
package org.ruoyi.system.service.impl;
import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.core.constant.CacheNames;
import org.ruoyi.common.core.constant.Constants;
import org.ruoyi.common.core.constant.SystemConstants;
import org.ruoyi.common.core.constant.TenantConstants;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.redis.utils.CacheUtils;
import org.ruoyi.common.tenant.helper.TenantHelper;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.*;
import org.ruoyi.system.domain.bo.SysTenantBo;
import org.ruoyi.system.domain.vo.SysTenantVo;
import org.ruoyi.system.mapper.*;
import org.ruoyi.system.service.ISysTenantService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.ruoyi.common.core.utils.SpringUtils;
import org.ruoyi.common.tenant.core.TenantEntity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * ç§Ÿæˆ·Service业务层处理
@@ -103,6 +109,7 @@
        lqw.eq(bo.getExpireTime() != null, SysTenant::getExpireTime, bo.getExpireTime());
        lqw.eq(bo.getAccountCount() != null, SysTenant::getAccountCount, bo.getAccountCount());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTenant::getStatus, bo.getStatus());
        lqw.orderByAsc(SysTenant::getId);
        return lqw;
    }
@@ -116,7 +123,9 @@
        // èŽ·å–æ‰€æœ‰ç§Ÿæˆ·ç¼–å·
        List<String> tenantIds = baseMapper.selectObjs(
            new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), Convert::toStr);
                new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId), x -> {
                    return Convert.toStr(x);
                });
        String tenantId = generateTenantId(tenantIds);
        add.setTenantId(tenantId);
        boolean flag = baseMapper.insert(add) > 0;
@@ -132,7 +141,6 @@
        SysDept dept = new SysDept();
        dept.setTenantId(tenantId);
        dept.setDeptName(bo.getCompanyName());
        dept.setLeader(bo.getUsername());
        dept.setParentId(Constants.TOP_PARENT_ID);
        dept.setAncestors(Constants.TOP_PARENT_ID.toString());
        deptMapper.insert(dept);
@@ -152,6 +160,11 @@
        user.setPassword(BCrypt.hashpw(bo.getPassword()));
        user.setDeptId(deptId);
        userMapper.insert(user);
        //新增系统用户后,默认当前用户为部门的负责人
        SysDept sd = new SysDept();
        sd.setLeader(user.getUserId());
        sd.setDeptId(deptId);
        deptMapper.updateById(sd);
        // ç”¨æˆ·å’Œè§’色关联表
        SysUserRole userRole = new SysUserRole();
@@ -161,27 +174,43 @@
        String defaultTenantId = TenantConstants.DEFAULT_TENANT_ID;
        List<SysDictType> dictTypeList = dictTypeMapper.selectList(
            new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
                new LambdaQueryWrapper<SysDictType>().eq(SysDictType::getTenantId, defaultTenantId));
        List<SysDictData> dictDataList = dictDataMapper.selectList(
            new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
                new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getTenantId, defaultTenantId));
        for (SysDictType dictType : dictTypeList) {
            dictType.setDictId(null);
            dictType.setTenantId(tenantId);
            dictType.setCreateDept(null);
            dictType.setCreateBy(null);
            dictType.setCreateTime(null);
            dictType.setUpdateBy(null);
            dictType.setUpdateTime(null);
        }
        for (SysDictData dictData : dictDataList) {
            dictData.setDictCode(null);
            dictData.setTenantId(tenantId);
            dictData.setCreateDept(null);
            dictData.setCreateBy(null);
            dictData.setCreateTime(null);
            dictData.setUpdateBy(null);
            dictData.setUpdateTime(null);
        }
        dictTypeMapper.insertBatch(dictTypeList);
        dictDataMapper.insertBatch(dictDataList);
        List<SysConfig> sysConfigList = configMapper.selectList(
            new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getTenantId, defaultTenantId));
                new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getTenantId, defaultTenantId));
        for (SysConfig config : sysConfigList) {
            config.setConfigId(null);
            config.setTenantId(tenantId);
            config.setCreateDept(null);
            config.setCreateBy(null);
            config.setCreateTime(null);
            config.setUpdateBy(null);
            config.setUpdateTime(null);
        }
        configMapper.insertBatch(sysConfigList);
        return true;
    }
@@ -196,7 +225,7 @@
        String numbers = RandomUtil.randomNumbers(6);
        // åˆ¤æ–­æ˜¯å¦å­˜åœ¨ï¼Œå¦‚果存在则重新生成
        if (tenantIds.contains(numbers)) {
            generateTenantId(tenantIds);
            return generateTenantId(tenantIds);
        }
        return numbers;
    }
@@ -223,7 +252,7 @@
        role.setRoleName(TenantConstants.TENANT_ADMIN_ROLE_NAME);
        role.setRoleKey(TenantConstants.TENANT_ADMIN_ROLE_KEY);
        role.setRoleSort(1);
        role.setStatus(TenantConstants.NORMAL);
        role.setStatus("0");
        roleMapper.insert(role);
        Long roleId = role.getRoleId();
@@ -261,7 +290,9 @@
    @CacheEvict(cacheNames = CacheNames.SYS_TENANT, key = "#bo.tenantId")
    @Override
    public int updateTenantStatus(SysTenantBo bo) {
        SysTenant tenant = MapstructUtils.convert(bo, SysTenant.class);
        SysTenant tenant = new SysTenant();
        tenant.setId(bo.getId());
        tenant.setStatus(bo.getStatus());
        return baseMapper.updateById(tenant);
    }
@@ -289,7 +320,7 @@
                throw new ServiceException("超管租户不能删除");
            }
        }
        return baseMapper.deleteBatchIds(ids) > 0;
        return baseMapper.deleteByIds(ids) > 0;
    }
    /**
@@ -298,8 +329,8 @@
    @Override
    public boolean checkCompanyNameUnique(SysTenantBo bo) {
        boolean exist = baseMapper.exists(new LambdaQueryWrapper<SysTenant>()
            .eq(SysTenant::getCompanyName, bo.getCompanyName())
            .ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId()));
                .eq(SysTenant::getCompanyName, bo.getCompanyName())
                .ne(ObjectUtil.isNotNull(bo.getTenantId()), SysTenant::getTenantId, bo.getTenantId()));
        return !exist;
    }
@@ -337,10 +368,10 @@
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean syncTenantPackage(String tenantId, String packageId) {
    public Boolean syncTenantPackage(String tenantId, Long packageId) {
        SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
        List<SysRole> roles = roleMapper.selectList(
            new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, tenantId));
                new LambdaQueryWrapper<SysRole>().eq(SysRole::getTenantId, tenantId));
        List<Long> roleIds = new ArrayList<>(roles.size() - 1);
        List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
        roles.forEach(item -> {
@@ -360,8 +391,103 @@
        });
        if (!roleIds.isEmpty()) {
            roleMenuMapper.delete(
                new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds));
                    new LambdaQueryWrapper<SysRoleMenu>().in(SysRoleMenu::getRoleId, roleIds).notIn(!menuIds.isEmpty(), SysRoleMenu::getMenuId, menuIds));
        }
        return true;
    }
    /**
     * åŒæ­¥ç§Ÿæˆ·å­—å…¸
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void syncTenantDict() {
        // æŸ¥è¯¢è¶…管 æ‰€æœ‰å­—典数据
        List<SysDictType> dictTypeList = new ArrayList<>();
        List<SysDictData> dictDataList = new ArrayList<>();
        TenantHelper.ignore(() -> {
            dictTypeList.addAll(dictTypeMapper.selectList());
            dictDataList.addAll(dictDataMapper.selectList());
        });
        Map<String, List<SysDictType>> typeMap = StreamUtils.groupByKey(dictTypeList, TenantEntity::getTenantId);
        Map<String, Map<String, List<SysDictData>>> typeDataMap = StreamUtils.groupBy2Key(
                dictDataList, TenantEntity::getTenantId, SysDictData::getDictType);
        // ç®¡ç†ç§Ÿæˆ·å­—典数据
        List<SysDictType> defaultTypeMap = typeMap.get(TenantConstants.DEFAULT_TENANT_ID);
        Map<String, List<SysDictData>> defaultTypeDataMap = typeDataMap.get(TenantConstants.DEFAULT_TENANT_ID);
        // èŽ·å–æ‰€æœ‰ç§Ÿæˆ·ç¼–å·
        List<String> tenantIds = baseMapper.selectObjs(
                new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId)
                        .eq(SysTenant::getStatus, SystemConstants.NORMAL), x -> {
                    return Convert.toStr(x);
                });
        List<SysDictType> saveTypeList = new ArrayList<>();
        List<SysDictData> saveDataList = new ArrayList<>();
        Set<String> set = new HashSet<>();
        for (String tenantId : tenantIds) {
            if (TenantConstants.DEFAULT_TENANT_ID.equals(tenantId)) {
                continue;
            }
            for (SysDictType dictType : defaultTypeMap) {
                List<String> typeList = StreamUtils.toList(typeMap.get(tenantId), SysDictType::getDictType);
                List<SysDictData> dataList = defaultTypeDataMap.get(dictType.getDictType());
                if (typeList.contains(dictType.getDictType())) {
                    List<SysDictData> dataListTenant = typeDataMap.get(tenantId).get(dictType.getDictType());
                    Map<String, SysDictData> map = StreamUtils.toIdentityMap(dataListTenant, SysDictData::getDictValue);
                    for (SysDictData dictData : dataList) {
                        if (!map.containsKey(dictData.getDictValue())) {
                            SysDictData data = BeanUtil.toBean(dictData, SysDictData.class);
                            // è®¾ç½®å­—典编码为 null
                            data.setDictCode(null);
                            data.setTenantId(tenantId);
                            data.setCreateTime(null);
                            data.setUpdateTime(null);
                            data.setCreateDept(null);
                            data.setCreateBy(null);
                            data.setUpdateBy(null);
                            set.add(tenantId);
                            saveDataList.add(data);
                        }
                    }
                } else {
                    SysDictType type = BeanUtil.toBean(dictType, SysDictType.class);
                    type.setDictId(null);
                    type.setTenantId(tenantId);
                    type.setCreateTime(null);
                    type.setUpdateTime(null);
                    set.add(tenantId);
                    saveTypeList.add(type);
                    if (CollUtil.isNotEmpty(dataList)) {
                        // ç­›é€‰å‡º dictType å¯¹åº”çš„ data
                        for (SysDictData dictData : dataList) {
                            SysDictData data = BeanUtil.toBean(dictData, SysDictData.class);
                            // è®¾ç½®å­—典编码为 null
                            data.setDictCode(null);
                            data.setTenantId(tenantId);
                            data.setCreateTime(null);
                            data.setUpdateTime(null);
                            data.setCreateDept(null);
                            data.setCreateBy(null);
                            data.setUpdateBy(null);
                            set.add(tenantId);
                            saveDataList.add(data);
                        }
                    }
                }
            }
        }
        TenantHelper.ignore(() -> {
            if (CollUtil.isNotEmpty(saveTypeList)) {
                dictTypeMapper.insertBatch(saveTypeList);
            }
            if (CollUtil.isNotEmpty(saveDataList)) {
                dictDataMapper.insertBatch(saveDataList);
            }
        });
        for (String tenantId : set) {
            TenantHelper.dynamic(tenantId, () -> CacheUtils.clear(CacheNames.SYS_DICT));
        }
    }
}
ruoyi-modules-api/ruoyi-system-api/src/main/java/org/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -16,9 +16,9 @@
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StreamUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.helper.DataBaseHelper;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.helper.DataBaseHelper;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.system.domain.SysDept;
import org.ruoyi.system.domain.SysUser;
ruoyi-modules/pom.xml
@@ -18,11 +18,9 @@
    </description>
    <modules>
        <module>ruoyi-demo</module>
        <module>ruoyi-chat</module>
        <module>ruoyi-system</module>
        <module>ruoyi-generator</module>
        <module>ruoyi-admin</module>
    </modules>
    <properties>
ruoyi-modules/ruoyi-chat/pom.xml
@@ -113,6 +113,12 @@
            <groupId>org.ruoyi</groupId>
            <artifactId>ruoyi-system-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-ollama</artifactId>
            <version>1.0.0-M6</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/api/ChatController.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/api/FaceController.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/api/LumaController.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/api/SubmitController.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/api/SunoController.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/api/TaskController.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatAgentManageController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.domain.bo.ChatAgentManageBo;
import org.ruoyi.domain.vo.ChatAgentManageVo;
@@ -16,7 +16,7 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatAppStoreController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatAppStoreBo;
import org.ruoyi.domain.vo.ChatAppStoreVo;
import org.ruoyi.service.IChatAppStoreService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatConfigController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.system.domain.bo.ChatConfigBo;
import org.ruoyi.system.domain.vo.ChatConfigVo;
import org.ruoyi.system.service.IChatConfigService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
@@ -31,7 +31,7 @@
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/config")
@RequestMapping("/system/chatConfig")
public class ChatConfigController extends BaseController {
    private final IChatConfigService chatConfigService;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,105 @@
package org.ruoyi.chat.controller.chat;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chat.service.chat.ISseService;
import org.ruoyi.common.chat.request.ChatRequest;
import org.ruoyi.common.chat.entity.Tts.TextToSpeech;
import org.ruoyi.common.chat.entity.files.UploadFileResponse;
import org.ruoyi.common.chat.entity.whisper.WhisperResponse;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.domain.model.LoginUser;
import org.ruoyi.common.core.exception.base.BaseException;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.domain.bo.ChatMessageBo;
import org.ruoyi.domain.vo.ChatMessageVo;
import org.ruoyi.service.IChatMessageService;
import org.springframework.core.io.Resource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
 * æè¿°ï¼šèŠå¤©ç®¡ç†
 *
 * @author ageerle@163.com
 * @date 2023-03-01
 */
@Controller
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/chat")
public class ChatController {
    private final ISseService sseService;
    private final IChatMessageService chatMessageService;
    /**
     * èŠå¤©æŽ¥å£
     */
    @PostMapping("/send")
    @ResponseBody
    public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletRequest request) {
        return sseService.sseChat(chatRequest,request);
    }
    /**
     * ä¸Šä¼ æ–‡ä»¶
     */
    @PostMapping("/upload")
    @ResponseBody
    public UploadFileResponse upload(@RequestPart("file") MultipartFile file) {
        return sseService.upload(file);
    }
    /**
     * è¯­éŸ³è½¬æ–‡æœ¬
     *
     * @param file
     */
    @PostMapping("/audio")
    @ResponseBody
    public WhisperResponse audio(@RequestParam("file") MultipartFile file) {
        WhisperResponse whisperResponse = sseService.speechToTextTranscriptionsV2(file);
        return whisperResponse;
    }
    /**
     * æ–‡æœ¬è½¬è¯­éŸ³
     *
     * @param textToSpeech
     */
    @PostMapping("/speech")
    @ResponseBody
    public ResponseEntity<Resource> speech(@RequestBody TextToSpeech textToSpeech) {
        return sseService.textToSpeed(textToSpeech);
    }
    /**
     * èŠå¤©è®°å½•
     */
    @PostMapping("/chatList")
    @ResponseBody
    public R<TableDataInfo<ChatMessageVo>> list(@RequestBody @Valid ChatMessageBo chatRequest, @RequestBody PageQuery pageQuery) {
        // é»˜è®¤æŸ¥è¯¢å½“前登录用户消息记录
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("用户未登录!");
        }
        chatRequest.setUserId(loginUser.getUserId());
        TableDataInfo<ChatMessageVo> chatMessageVoTableDataInfo = chatMessageService.queryPageList(chatRequest, pageQuery);
        return R.ok(chatMessageVoTableDataInfo);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatGptsController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatGptsBo;
import org.ruoyi.domain.vo.ChatGptsVo;
import org.ruoyi.service.IChatGptsService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatMessageController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatMessageBo;
import org.ruoyi.domain.vo.ChatMessageVo;
import org.ruoyi.service.IChatMessageService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatModelController.java
@@ -9,7 +9,7 @@
import org.ruoyi.chat.service.chat.UserModelService;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatModelBo;
import org.ruoyi.domain.vo.ChatModelVo;
import org.ruoyi.service.IChatModelService;
@@ -17,7 +17,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatPackagePlanController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatPackagePlanBo;
import org.ruoyi.domain.vo.ChatPackagePlanVo;
import org.ruoyi.service.IChatPackagePlanService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatPayOrderController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatPayOrderBo;
import org.ruoyi.domain.vo.ChatPayOrderVo;
import org.ruoyi.service.IChatPayOrderService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatPluginController.java
@@ -8,7 +8,7 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatPluginBo;
import org.ruoyi.domain.vo.ChatPluginVo;
import org.ruoyi.service.IChatPluginService;
@@ -16,7 +16,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/chat/ChatVoucherController.java
@@ -7,7 +7,7 @@
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.domain.bo.ChatVoucherBo;
import org.ruoyi.domain.vo.ChatVoucherVo;
import org.ruoyi.service.IChatVoucherService;
@@ -15,7 +15,7 @@
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/tripartite/FaceController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,42 @@
package org.ruoyi.chat.controller.tripartite;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import org.apache.commons.lang3.math.NumberUtils;
import org.ruoyi.chat.domain.InsightFace;
import org.ruoyi.chat.service.chat.IChatCostService;
import org.ruoyi.chat.util.MjOkHttpUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "任务查询")
@RestController
@RequestMapping("/mj")
@RequiredArgsConstructor
@Slf4j
public class FaceController {
    private final IChatCostService chatCostService;
    private final MjOkHttpUtil mjOkHttpUtil;
    @ApiOperation(value = "换脸")
    @PostMapping("/insight-face/swap")
    public String insightFace(@RequestBody InsightFace insightFace) {
        // æ‰£é™¤æŽ¥å£è´¹ç”¨å¹¶ä¸”保存消息记录
        chatCostService.taskDeduct("mj","Face Changing", NumberUtils.toDouble(mjOkHttpUtil.getKey("faceSwapping"), 0.1));
        // åˆ›å»ºè¯·æ±‚体(这里使用JSON作为媒体类型)
        String insightFaceJson = JSONUtil.toJsonStr(insightFace);
        String url = "mj/insight-face/swap";
        Request request = mjOkHttpUtil.createPostRequest(url, insightFaceJson);
        return mjOkHttpUtil.executeRequest(request);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/tripartite/LumaController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package org.ruoyi.chat.controller.tripartite;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import org.apache.commons.lang3.math.NumberUtils;
import org.ruoyi.chat.config.OkHttpConfig;
import org.ruoyi.chat.domain.bo.GenerateLuma;
import org.ruoyi.chat.service.chat.IChatCostService;
import org.ruoyi.common.core.utils.OkHttpUtil;
import org.springframework.web.bind.annotation.*;
/**
 * æè¿°ï¼šæ–‡ç”Ÿè§†é¢‘
 *
 * @author ageerle@163.com
 * date 2024/6/27
 */
@RestController
@RequestMapping("/luma")
@RequiredArgsConstructor
@Slf4j
public class LumaController {
    private final OkHttpConfig okHttpConfig;
    private final IChatCostService chatCostService;
    @ApiOperation(value = "文生视频")
    @PostMapping("/generations/")
    public String generateVideo(@RequestBody GenerateLuma generateLuma) {
        OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("luma");
        chatCostService.taskDeduct("luma", "文生视频", NumberUtils.toDouble(okHttpConfig.getGenerate(), 0.3));
        String generateJson = JSONUtil.toJsonStr(generateLuma);
        String url = "luma/generations";
        Request request = okHttpUtil.createPostRequest(url, generateJson);
        return okHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "文生视频任务查询")
    @GetMapping("/generations/{taskId}")
    public String getGenerationTask(@PathVariable String taskId) {
        OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("luma");
        String url = "luma/generations/" + taskId;
        Request request = okHttpUtil.createGetRequest(url);
        return okHttpUtil.executeRequest(request);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/tripartite/SubmitController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,134 @@
package org.ruoyi.chat.controller.tripartite;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import org.apache.commons.lang3.math.NumberUtils;
import org.ruoyi.chat.domain.dto.*;
import org.ruoyi.chat.enums.ActionType;
import org.ruoyi.chat.service.chat.IChatCostService;
import org.ruoyi.chat.util.MjOkHttpUtil;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;
@Api(tags = "任务提交")
@RestController
@RequestMapping("/mj/submit")
@RequiredArgsConstructor
@Slf4j
public class SubmitController {
    private final IChatCostService chatCostService;
    private final MjOkHttpUtil mjOkHttpUtil;
    @ApiOperation(value = "绘图变化")
    @PostMapping("/change")
    public String change(@RequestBody SubmitChangeDTO changeDTO) {
        String jsonStr = JSONUtil.toJsonStr(changeDTO);
        String url = "mj/submit/change";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "执行动作")
    @PostMapping("/action")
    public String action(@RequestBody SubmitActionDTO changeDTO) {
        ActionType actionType = ActionType.fromCustomId(getAction(changeDTO.getCustomId()));
        Optional.ofNullable(actionType).ifPresentOrElse(
            type -> {
                switch (type) {
                    case UP_SAMPLE:
                        chatCostService.taskDeduct("mj","enlarge", NumberUtils.toDouble(mjOkHttpUtil.getKey("upsample"), 0.3));
                        break;
                    case IN_PAINT:
                        // å±€éƒ¨é‡ç»˜å·²ç»æ‰£è´¹,不执行任何操作
                        break;
                    default:
                        chatCostService.taskDeduct("mj","change", NumberUtils.toDouble(mjOkHttpUtil.getKey("change"), 0.3));
                        break;
                }
            },
            () -> chatCostService.taskDeduct("mj","change", NumberUtils.toDouble(mjOkHttpUtil.getKey("change"), 0.3))
        );
        String jsonStr = JSONUtil.toJsonStr(changeDTO);
        String url = "mj/submit/action";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "绘图变化-simple")
    @PostMapping("/simple-change")
    public String simpleChange(@RequestBody SubmitSimpleChangeDTO simpleChangeDTO) {
        String jsonStr = JSONUtil.toJsonStr(simpleChangeDTO);
        String url = "mj/submit/simple-change";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "提交图生图、混图任务")
    @PostMapping("/blend")
    public String blend(@RequestBody SubmitBlendDTO blendDTO) {
        chatCostService.taskDeduct("mj","blend", NumberUtils.toDouble(mjOkHttpUtil.getKey("blend"), 0.3));
        String jsonStr = JSONUtil.toJsonStr(blendDTO);
        String url = "mj/submit/blend";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "提交图生文任务")
    @PostMapping("/describe")
    public String describe(@RequestBody SubmitDescribeDTO describeDTO) {
        chatCostService.taskDeduct("mj","describe", NumberUtils.toDouble(mjOkHttpUtil.getKey("describe"), 0.1));
        String jsonStr = JSONUtil.toJsonStr(describeDTO);
        String url = "mj/submit/describe";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "提交文生图任务")
    @PostMapping("/imagine")
    public String imagine(@RequestBody SubmitImagineDTO imagineDTO) {
        chatCostService.taskDeduct("mj",imagineDTO.getPrompt(), NumberUtils.toDouble(mjOkHttpUtil.getKey("imagine"), 0.3));
        String jsonStr = JSONUtil.toJsonStr(imagineDTO);
        String url = "mj/submit/imagine";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "提交局部重绘任务")
    @PostMapping("/modal")
    public String modal(@RequestBody SubmitModalDTO submitModalDTO) {
        chatCostService.taskDeduct("mj","repaint ", NumberUtils.toDouble(mjOkHttpUtil.getKey("inpaint"), 0.1));
        String jsonStr = JSONUtil.toJsonStr(submitModalDTO);
        String url = "mj/submit/modal";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "提交提示词分析任务")
    @PostMapping("/shorten")
    public String shorten(@RequestBody SubmitShortenDTO submitShortenDTO) {
        chatCostService.taskDeduct("mj","shorten", NumberUtils.toDouble(mjOkHttpUtil.getKey("shorten"), 0.1));
        String jsonStr = JSONUtil.toJsonStr(submitShortenDTO);
        String url = "mj/submit/shorten";
        Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
        return mjOkHttpUtil.executeRequest(request);
    }
    public String getAction(String customId) {
        if (customId == null || customId.isEmpty()) {
            return null;
        }
        String[] parts = customId.split("::");
        return customId.endsWith("SOLO") ? parts[1] : parts[2];
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/tripartite/SunoController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,69 @@
package org.ruoyi.chat.controller.tripartite;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import org.apache.commons.lang3.math.NumberUtils;
import org.ruoyi.chat.config.OkHttpConfig;
import org.ruoyi.chat.domain.bo.GenerateLyric;
import org.ruoyi.chat.domain.bo.GenerateSuno;
import org.ruoyi.chat.service.chat.IChatCostService;
import org.ruoyi.common.core.utils.OkHttpUtil;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/sunoapi")
@RequiredArgsConstructor
@Slf4j
public class SunoController {
    private final OkHttpConfig okHttpConfig;
    private final IChatCostService chatCostService;
    @ApiOperation(value = "文生歌曲")
    @PostMapping("/generate")
    public String generate(@RequestBody GenerateSuno generateSuno) {
        OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
        // æ‰£é™¤æŽ¥å£è´¹ç”¨å¹¶ä¸”保存消息记录
        chatCostService.taskDeduct("suno","文生歌曲", NumberUtils.toDouble(okHttpConfig.getGenerate(), 0.3));
        // åˆ›å»ºè¯·æ±‚体(这里使用JSON作为媒体类型)
        String generateJson = JSONUtil.toJsonStr(generateSuno);
        String url = "suno/generate";
        Request request = okHttpUtil.createPostRequest(url, generateJson);
        return okHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "生成歌词")
    @PostMapping("/generate/lyrics/")
    public String generate(@RequestBody GenerateLyric generateLyric) {
        OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
        String generateJson = JSONUtil.toJsonStr(generateLyric);
        String url = "task/suno/v1/submit/lyrics";
        Request request = okHttpUtil.createPostRequest(url, generateJson);
        return okHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "查询歌词任务")
    @GetMapping("/lyrics/{taskId}")
    public String lyrics(@PathVariable String taskId) {
        OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
        String url = "task/suno/v1/fetch/"+taskId;
        Request request = okHttpUtil.createGetRequest(url);
        return okHttpUtil.executeRequest(request);
    }
    @ApiOperation(value = "查询歌曲任务")
    @GetMapping("/feed/{taskId}")
    public String feed(@PathVariable String taskId) {
        OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
        String url = "suno/feed/"+taskId;
        Request request = okHttpUtil.createGetRequest(url);
        return okHttpUtil.executeRequest(request);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/controller/tripartite/TaskController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
package org.ruoyi.chat.controller.tripartite;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Request;
import org.ruoyi.chat.domain.dto.TaskConditionDTO;
import org.ruoyi.chat.util.MjOkHttpUtil;
import org.springframework.web.bind.annotation.*;
@Api(tags = "任务查询")
@RestController
@RequestMapping("/mj/task")
@RequiredArgsConstructor
@Slf4j
public class TaskController {
    private final MjOkHttpUtil mjOkHttpUtil;
   @ApiOperation(value = "指定ID获取任务")
   @GetMapping("/{id}/fetch")
    public String fetch(@ApiParam(value = "任务ID") @PathVariable String id) {
        String url = "mj/task/" + id + "/fetch";
        Request request = mjOkHttpUtil.createGetRequest(url);
        return mjOkHttpUtil.executeRequest(request);
    }
   @ApiOperation(value = "根据ID列表查询任务")
   @PostMapping("/list-by-condition")
   public String listByIds(@RequestBody TaskConditionDTO conditionDTO) {
        String url = "mj/task/list-by-condition";
        String conditionJson = JSONUtil.toJsonStr(conditionDTO);
        Request request = mjOkHttpUtil.createPostRequest(url,conditionJson);
        return mjOkHttpUtil.executeRequest(request);
   }
    @ApiOperation(value = "获取任务图片的seed")
    @GetMapping("/{id}/image-seed")
    public String getSeed(@ApiParam(value = "任务ID") @PathVariable String id) {
        String url = "mj/task/" + id + "/image-seed";
        Request request = mjOkHttpUtil.createGetRequest(url);
        return mjOkHttpUtil.executeRequest(request);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/factory/SseServiceFactory.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/factory/VectorStoreFactory.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/factory/VectorizationFactory.java
@@ -4,8 +4,8 @@
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chat.service.knowledge.vectorizer.BgeLargeVectorization;
import org.ruoyi.chat.service.knowledge.vectorizer.OpenAiVectorization;
import org.ruoyi.chat.service.knowledge.BgeLargeVectorizationImpl;
import org.ruoyi.chat.service.knowledge.OpenAiVectorizationImpl;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.service.IKnowledgeInfoService;
import org.ruoyi.service.VectorizationService;
@@ -20,15 +20,15 @@
@Slf4j
public class VectorizationFactory {
    private final OpenAiVectorization openAiVectorization;
    private final OpenAiVectorizationImpl openAiVectorization;
    private final BgeLargeVectorization bgeLargeVectorization;
    private final BgeLargeVectorizationImpl bgeLargeVectorization;
    @Lazy
    @Resource
    private IKnowledgeInfoService knowledgeInfoService;
    public VectorizationFactory(OpenAiVectorization openAiVectorization, BgeLargeVectorization bgeLargeVectorization) {
    public VectorizationFactory(OpenAiVectorizationImpl openAiVectorization, BgeLargeVectorizationImpl bgeLargeVectorization) {
        this.openAiVectorization = openAiVectorization;
        this.bgeLargeVectorization = bgeLargeVectorization;
    }
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/OllamaServiceImpl.java
@@ -39,13 +39,21 @@
    @Autowired
    private  IChatModelService chatModelService;
    @Autowired
    private ChatClient chatClient;
    @Autowired
    private ToolCallbackProvider tools;
    private final ChatClient chatClient;
    private final ChatMemory chatMemory = new InMemoryChatMemory();
    public OllamaServiceImpl(ChatClient.Builder chatClientBuilder,ToolCallbackProvider tools) {
        this.chatClient = chatClientBuilder
                .defaultTools(tools)
                .defaultOptions(
                        OllamaOptions.builder()
                                .model(OllamaModel.QWEN_2_5_7B)
                                .temperature(0.4)
                                .build())
                .build();
    }
    @Override
    public SseEmitter chat(ChatRequest chatRequest,SseEmitter emitter) {
@@ -104,11 +112,6 @@
        this.chatClient.prompt(chatRequest.getPrompt())
                .advisors(messageChatMemoryAdvisor)
                .tools(tools)
                .options(OllamaOptions.builder()
                        .model(OllamaModel.QWEN_2_5_7B)
                        .temperature(0.4)
                        .build())
                .stream()
                .chatResponse()
                .subscribe(
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/OpenAIServiceImpl.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/chat/impl/SseServiceImpl.java
@@ -14,7 +14,6 @@
import org.ruoyi.chat.service.chat.IChatCostService;
import org.ruoyi.chat.service.chat.IChatService;
import org.ruoyi.chat.service.chat.ISseService;
import org.ruoyi.chat.factory.SseServiceFactory;
import org.ruoyi.chat.util.IpUtil;
import org.ruoyi.chat.util.SSEUtil;
import org.ruoyi.common.chat.request.ChatRequest;
@@ -73,7 +72,8 @@
    private final IChatCostService chatCostService;
    private final SseServiceFactory sseServiceFactory;
    private final IChatService chatService;
    private static final String requestIdTemplate = "company-%d";
@@ -135,11 +135,10 @@
        String model = chatRequest.getModel();
        // å¦‚果模型名称以ollama开头,则调用ollama中部署的本地模型
        if (model.startsWith("ollama-")) {
            String[] parts = chatRequest.getModel().split("ollama-", 2); // é™åˆ¶åˆ†å‰²æ¬¡æ•°ä¸º2
            String[] parts = chatRequest.getModel().split("ollama-", 2);
            if (parts.length > 1) {
                chatRequest.setModel(parts[1]);
                IChatService chatService = sseServiceFactory.getSseService("ollama");
                chatService.chat(chatRequest,emitter);
                chatService.mcpChat(chatRequest,emitter);
            } else {
                throw new IllegalArgumentException("Invalid ollama model name: " + chatRequest.getModel());
            }
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/BgeLargeVectorizationImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,66 @@
package org.ruoyi.chat.service.knowledge;
import io.github.ollama4j.OllamaAPI;
import io.github.ollama4j.models.embeddings.OllamaEmbeddingsRequestModel;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.common.core.exception.ServiceException;
import org.ruoyi.domain.vo.ChatModelVo;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.service.IChatModelService;
import org.ruoyi.service.IKnowledgeInfoService;
import org.ruoyi.service.VectorizationService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
 * @author ageer
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class BgeLargeVectorizationImpl implements VectorizationService {
    @Lazy
    @Resource
    private IKnowledgeInfoService knowledgeInfoService;
    @Lazy
    @Resource
    private final IChatModelService chatModelService;
    @Override
    public List<List<Double>> batchVectorization(List<String> chunkList, String kid) {
        KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid));
        ChatModelVo chatModelVo = chatModelService.selectModelByName(knowledgeInfoVo.getVectorModel());
        OllamaAPI api = new OllamaAPI(chatModelVo.getApiHost());
        List<Double> doubleVector;
        List<List<Double>> vectorList = new ArrayList<>();
        try {
            for (String chunk : chunkList) {
                doubleVector = api.generateEmbeddings(new OllamaEmbeddingsRequestModel(knowledgeInfoVo.getVectorModel(), chunk));
                vectorList.add(doubleVector);
            }
        } catch (Exception e) {
            throw new ServiceException("文本向量化异常:"+e.getMessage());
        }
        return vectorList;
    }
    @Override
    public List<Double> singleVectorization(String chunk, String kid) {
        List<String> chunkList = new ArrayList<>();
        chunkList.add(chunk);
        List<List<Double>> vectorList = batchVectorization(chunkList, kid);
        return vectorList.get(0);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/OpenAiVectorizationImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,107 @@
package org.ruoyi.chat.service.knowledge;
import jakarta.annotation.Resource;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chat.config.ChatConfig;
import org.ruoyi.common.chat.entity.embeddings.Embedding;
import org.ruoyi.common.chat.entity.embeddings.EmbeddingResponse;
import org.ruoyi.common.chat.openai.OpenAiStreamClient;
import org.ruoyi.domain.vo.ChatModelVo;
import org.ruoyi.domain.vo.KnowledgeInfoVo;
import org.ruoyi.service.IChatModelService;
import org.ruoyi.service.IKnowledgeInfoService;
import org.ruoyi.service.VectorizationService;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
@Slf4j
@RequiredArgsConstructor
public class OpenAiVectorizationImpl implements VectorizationService {
    @Lazy
    @Resource
    private IKnowledgeInfoService knowledgeInfoService;
    @Lazy
    @Resource
    private IChatModelService chatModelService;
    @Getter
    private OpenAiStreamClient openAiStreamClient;
    private final ChatConfig chatConfig;
    @Override
    public List<List<Double>> batchVectorization(List<String> chunkList, String kid) {
        List<List<Double>> vectorList;
        // èŽ·å–çŸ¥è¯†åº“ä¿¡æ¯
        KnowledgeInfoVo knowledgeInfoVo = knowledgeInfoService.queryById(Long.valueOf(kid));
        if(knowledgeInfoVo == null){
            log.warn("知识库不存在:请查检ID {}",kid);
            vectorList=new ArrayList<>();
            vectorList.add(new ArrayList<>());
            return vectorList;
        }
        ChatModelVo chatModelVo = chatModelService.selectModelByName(knowledgeInfoVo.getVectorModel());
        String apiHost= chatModelVo.getApiHost();
        String apiKey= chatModelVo.getApiKey();
        openAiStreamClient = chatConfig.createOpenAiStreamClient(apiHost,apiKey);
        Embedding embedding = buildEmbedding(chunkList, knowledgeInfoVo);
        EmbeddingResponse embeddings = openAiStreamClient.embeddings(embedding);
        // å¤„理 OpenAI è¿”回的嵌入数据
        vectorList = processOpenAiEmbeddings(embeddings);
        return vectorList;
    }
    /**
     * æž„建 Embedding å¯¹è±¡
     */
    private Embedding buildEmbedding(List<String> chunkList, KnowledgeInfoVo knowledgeInfoVo) {
        return Embedding.builder()
                .input(chunkList)
                .model(knowledgeInfoVo.getVectorModel())
                .build();
    }
    /**
     * å¤„理 OpenAI è¿”回的嵌入数据
     */
    private List<List<Double>> processOpenAiEmbeddings(EmbeddingResponse embeddings) {
        List<List<Double>> vectorList = new ArrayList<>();
        embeddings.getData().forEach(data -> {
            List<BigDecimal> vector = data.getEmbedding();
            List<Double> doubleVector = convertToDoubleList(vector);
            vectorList.add(doubleVector);
        });
        return vectorList;
    }
    /**
     * å°† BigDecimal è½¬æ¢ä¸º Double åˆ—表
     */
    private List<Double> convertToDoubleList(List<BigDecimal> vector) {
        return vector.stream()
                .map(BigDecimal::doubleValue)
                .collect(Collectors.toList());
    }
    @Override
    public List<Double> singleVectorization(String chunk, String kid) {
        List<String> chunkList = new ArrayList<>();
        chunkList.add(chunk);
        List<List<Double>> vectorList = batchVectorization(chunkList, kid);
        return vectorList.get(0);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/VectorizationWrapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,30 @@
package org.ruoyi.chat.service.knowledge;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.chat.factory.VectorizationFactory;
import org.ruoyi.service.VectorizationService;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
@Slf4j
@Primary
@AllArgsConstructor
public class VectorizationWrapper implements VectorizationService {
    private final VectorizationFactory vectorizationFactory;
    @Override
    public List<List<Double>> batchVectorization(List<String> chunkList, String kid) {
        VectorizationService embedding = vectorizationFactory.getEmbedding(kid);
        return embedding.batchVectorization(chunkList, kid);
    }
    @Override
    public List<Double> singleVectorization(String chunk, String kid) {
        VectorizationService embedding = vectorizationFactory.getEmbedding(kid);
        return embedding.singleVectorization(chunk, kid);
    }
}
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/vectorizer/BgeLargeVectorization.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/vectorizer/OpenAiVectorization.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/vectorstore/MilvusVectorStore.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/chat/service/knowledge/vectorstore/WeaviateVectorStore.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/controller/TestDemoController.java
@@ -16,8 +16,8 @@
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.demo.domain.TestDemo;
import org.ruoyi.demo.domain.bo.TestDemoBo;
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/domain/bo/TestDemoBo.java
@@ -7,7 +7,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.demo.domain.TestDemo;
/**
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/domain/bo/TestTreeBo.java
@@ -7,7 +7,7 @@
import lombok.EqualsAndHashCode;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import org.ruoyi.demo.domain.TestTree;
/**
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/mapper/TestDemoEncryptMapper.java
@@ -1,6 +1,6 @@
package org.ruoyi.demo.mapper;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.demo.domain.TestDemoEncrypt;
/**
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/mapper/TestDemoMapper.java
@@ -5,9 +5,9 @@
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.ruoyi.common.mybatis.annotation.DataColumn;
import org.ruoyi.common.mybatis.annotation.DataPermission;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.annotation.DataColumn;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.demo.domain.TestDemo;
import org.ruoyi.demo.domain.vo.TestDemoVo;
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/mapper/TestTreeMapper.java
@@ -1,8 +1,8 @@
package org.ruoyi.demo.mapper;
import org.ruoyi.common.mybatis.annotation.DataColumn;
import org.ruoyi.common.mybatis.annotation.DataPermission;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.annotation.DataColumn;
import org.ruoyi.annotation.DataPermission;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.demo.domain.TestTree;
import org.ruoyi.demo.domain.vo.TestTreeVo;
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/service/ITestDemoService.java
@@ -1,7 +1,7 @@
package org.ruoyi.demo.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.demo.domain.TestDemo;
import org.ruoyi.demo.domain.bo.TestDemoBo;
import org.ruoyi.demo.domain.vo.TestDemoVo;
ruoyi-modules/ruoyi-demo/src/main/java/org/ruoyi/demo/service/impl/TestDemoServiceImpl.java
@@ -6,8 +6,8 @@
import lombok.RequiredArgsConstructor;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.demo.domain.TestDemo;
import org.ruoyi.demo.domain.bo.TestDemoBo;
import org.ruoyi.demo.domain.vo.TestDemoVo;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/controller/GenController.java
@@ -3,15 +3,15 @@
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.IoUtil;
import org.ruoyi.common.mybatis.helper.DataBaseHelper;
import org.ruoyi.helper.DataBaseHelper;
import org.ruoyi.generator.domain.GenTable;
import org.ruoyi.generator.domain.GenTableColumn;
import org.ruoyi.generator.service.IGenTableService;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/domain/GenTable.java
@@ -6,7 +6,7 @@
import com.baomidou.mybatisplus.annotation.TableName;
import org.ruoyi.generator.constant.GenConstants;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/domain/GenTableColumn.java
@@ -5,7 +5,7 @@
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/mapper/GenTableColumnMapper.java
@@ -2,7 +2,7 @@
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import org.ruoyi.generator.domain.GenTableColumn;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import java.util.List;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/mapper/GenTableMapper.java
@@ -2,7 +2,7 @@
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.generator.domain.GenTable;
import org.apache.ibatis.annotations.Param;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/service/GenTableServiceImpl.java
@@ -17,8 +17,8 @@
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.core.utils.file.FileUtils;
import org.ruoyi.common.json.utils.JsonUtils;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.generator.constant.GenConstants;
import org.ruoyi.generator.domain.GenTable;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/service/IGenTableService.java
@@ -1,7 +1,7 @@
package org.ruoyi.generator.service;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.generator.domain.GenTable;
import org.ruoyi.generator.domain.GenTableColumn;
ruoyi-modules/ruoyi-generator/src/main/java/org/ruoyi/generator/util/VelocityUtils.java
@@ -10,7 +10,7 @@
import org.ruoyi.common.core.utils.DateUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.json.utils.JsonUtils;
import org.ruoyi.common.mybatis.helper.DataBaseHelper;
import org.ruoyi.helper.DataBaseHelper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.apache.velocity.VelocityContext;
ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml
@@ -8,7 +8,7 @@
    </resultMap>
    <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isMySql()">
            select column_name,
                   (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required,
                   (case when column_key = 'PRI' then '1' else '0' end) as is_pk,
@@ -19,7 +19,7 @@
            from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
            order by ordinal_position
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isOracle()">
            select lower(temp.column_name) as column_name,
                    (case when (temp.nullable = 'N'  and  temp.constraint_type != 'P') then '1' else null end) as is_required,
                    (case when temp.constraint_type = 'P' then '1' else '0' end) as is_pk,
@@ -39,7 +39,7 @@
            WHERE temp.row_flg = 1
            ORDER BY temp.column_id
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isPostgerSql()">
            SELECT column_name, is_required, is_pk, sort, column_comment, is_increment, column_type
            FROM (
                SELECT c.relname AS table_name,
@@ -73,7 +73,7 @@
            WHERE table_name = (#{tableName})
                AND column_type <![CDATA[ <> ]]> '-'
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isSqlServer()">
            SELECT
                cast(A.NAME as nvarchar) as column_name,
                cast(B.NAME as nvarchar) + (case when B.NAME = 'numeric' then '(' + cast(A.prec as nvarchar) + ',' + cast(A.scale as nvarchar) + ')' else '' end) as column_type,
ruoyi-modules/ruoyi-generator/src/main/resources/mapper/generator/GenTableMapper.xml
@@ -15,7 +15,7 @@
    </resultMap>
    <select id="selectPageDbTableList" resultMap="GenTableResult">
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isMySql()">
            select table_name, table_comment, create_time, update_time
            from information_schema.tables
            where table_schema = (select database())
@@ -29,7 +29,7 @@
            </if>
            order by create_time desc
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isOracle()">
            select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
            from user_tables dt, user_tab_comments dtc, user_objects uo
            where dt.table_name = dtc.table_name
@@ -45,7 +45,7 @@
            </if>
            order by create_time desc
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isPostgerSql()">
            select table_name, table_comment, create_time, update_time
            from (
                SELECT c.relname AS table_name,
@@ -69,7 +69,7 @@
            </if>
            order by create_time desc
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isSqlServer()">
            SELECT cast(D.NAME as nvarchar) as table_name,
                   cast(F.VALUE as nvarchar) as table_comment,
                   crdate as create_time,
@@ -90,7 +90,7 @@
    </select>
    <select id="selectDbTableListByNames" resultMap="GenTableResult">
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isMySql()">
            select table_name, table_comment, create_time, update_time from information_schema.tables
            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
            and table_name in
@@ -98,7 +98,7 @@
                 #{name}
            </foreach>
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isOracle()">
            select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
            from user_tables dt, user_tab_comments dtc, user_objects uo
            where dt.table_name = dtc.table_name
@@ -111,7 +111,7 @@
                #{name}
            </foreach>
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isPostgerSql()">
            select table_name, table_comment, create_time, update_time
            from (
                SELECT c.relname AS table_name,
@@ -131,7 +131,7 @@
                #{name}
            </foreach>
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isSqlServer()">
            SELECT cast(D.NAME as nvarchar) as table_name,
                   cast(F.VALUE as nvarchar) as table_comment,
                   crdate as create_time,
@@ -148,12 +148,12 @@
    </select>
    <select id="selectTableByName" parameterType="String" resultMap="GenTableResult">
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isMySql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isMySql()">
            select table_name, table_comment, create_time, update_time from information_schema.tables
            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database())
            and table_name = #{tableName}
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isOracle()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isOracle()">
            select lower(dt.table_name) as table_name, dtc.comments as table_comment, uo.created as create_time, uo.last_ddl_time as update_time
            from user_tables dt, user_tab_comments dtc, user_objects uo
            where dt.table_name = dtc.table_name
@@ -163,7 +163,7 @@
            AND dt.table_name NOT IN (select table_name from gen_table)
            and lower(dt.table_name) = #{tableName}
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isPostgerSql()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isPostgerSql()">
            select table_name, table_comment, create_time, update_time
            from (
                SELECT c.relname AS table_name,
@@ -180,7 +180,7 @@
            where table_name NOT LIKE 'xxl_job_%' and table_name NOT LIKE 'gen_%'
            and table_name = #{tableName}
        </if>
        <if test="@org.ruoyi.common.mybatis.helper.DataBaseHelper@isSqlServer()">
        <if test="@org.ruoyi.helper.DataBaseHelper@isSqlServer()">
            SELECT cast(D.NAME as nvarchar) as table_name,
                   cast(F.VALUE as nvarchar) as table_comment,
                   crdate as create_time,
ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/bo.java.vm
@@ -1,7 +1,7 @@
package ${packageName}.domain.bo;
import ${packageName}.domain.${ClassName};
import org.ruoyi.common.mybatis.core.domain.BaseEntity;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/controller.java.vm
@@ -11,7 +11,7 @@
import annotation.idempotent.common.org.ruoyi.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
@@ -21,7 +21,7 @@
import ${packageName}.domain.bo.${ClassName}Bo;
import ${packageName}.service.I${ClassName}Service;
#if($table.crud || $table.sub)
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
#elseif($table.tree)
#end
ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/mapper.java.vm
@@ -2,7 +2,7 @@
import ${packageName}.domain.${ClassName};
import ${packageName}.domain.vo.${ClassName}Vo;
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
 * ${functionName}Mapper接口
ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/service.java.vm
@@ -4,8 +4,8 @@
import ${packageName}.domain.vo.${ClassName}Vo;
import ${packageName}.domain.bo.${ClassName}Bo;
#if($table.crud || $table.sub)
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
#end
import java.util.Collection;
ruoyi-modules/ruoyi-generator/src/main/resources/vm/java/serviceImpl.java.vm
@@ -2,8 +2,8 @@
import org.ruoyi.common.core.utils.MapstructUtils;
    #if($table.crud || $table.sub)
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
#end
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
ruoyi-modules/ruoyi-mcp-server/pom.xml
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-mcp-server/src/main/java/org/ruoyi/mcp/service/McpCustomService.java
ÎļþÒÑɾ³ý
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/monitor/SysLogininforController.java
@@ -6,8 +6,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.redis.utils.RedisUtils;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysLogininforBo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/monitor/SysOperlogController.java
@@ -7,8 +7,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysOperLogBo;
import org.ruoyi.system.domain.vo.SysOperLogVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/monitor/SysUserOnlineController.java
@@ -12,7 +12,7 @@
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.redis.utils.RedisUtils;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.SysUserOnline;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysConfigController.java
@@ -7,8 +7,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysConfigBo;
import org.ruoyi.system.domain.vo.SysConfigVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysDictDataController.java
@@ -8,8 +8,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysDictDataBo;
import org.ruoyi.system.domain.vo.SysDictDataVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysDictTypeController.java
@@ -7,8 +7,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysDictTypeBo;
import org.ruoyi.system.domain.vo.SysDictTypeVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysNoticeController.java
@@ -4,8 +4,8 @@
import org.ruoyi.common.core.domain.R;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.SysNotice;
import org.ruoyi.system.domain.bo.SysNoticeBo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysNoticeStateController.java
@@ -10,8 +10,8 @@
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysNoticeStateBo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysOssConfigController.java
@@ -11,8 +11,8 @@
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysOssConfigBo;
import org.ruoyi.system.domain.vo.SysOssConfigVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysOssController.java
@@ -10,8 +10,8 @@
import org.ruoyi.common.core.validate.QueryGroup;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysOssBo;
import org.ruoyi.system.domain.vo.SysOssUploadVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysPostController.java
@@ -5,8 +5,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysPostBo;
import org.ruoyi.system.domain.vo.SysPostVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysRoleController.java
@@ -7,8 +7,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.SysUserRole;
import org.ruoyi.system.domain.bo.SysDeptBo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysTenantController.java
@@ -16,13 +16,14 @@
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.tenant.helper.TenantHelper;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysTenantBo;
import org.ruoyi.system.domain.vo.SysTenantVo;
import org.ruoyi.system.service.ISysTenantService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@@ -37,6 +38,7 @@
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/tenant")
@ConditionalOnProperty(value = "tenant.enable", havingValue = "true")
public class SysTenantController extends BaseController {
    private final ISysTenantService tenantService;
@@ -56,7 +58,7 @@
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:export")
    @Log(title = "租户", businessType = BusinessType.EXPORT)
    @Log(title = "租户管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(SysTenantBo bo, HttpServletResponse response) {
        List<SysTenantVo> list = tenantService.queryList(bo);
@@ -79,9 +81,10 @@
    /**
     * æ–°å¢žç§Ÿæˆ·
     */
    //@ApiEncrypt
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:add")
    @Log(title = "租户", businessType = BusinessType.INSERT)
    @Log(title = "租户管理", businessType = BusinessType.INSERT)
    @Lock4j
    @RepeatSubmit()
    @PostMapping()
@@ -97,7 +100,7 @@
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @Log(title = "租户管理", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SysTenantBo bo) {
@@ -113,7 +116,7 @@
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @Log(title = "租户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public R<Void> changeStatus(@RequestBody SysTenantBo bo) {
        tenantService.checkTenantAllowed(bo.getTenantId());
@@ -127,7 +130,7 @@
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:remove")
    @Log(title = "租户", businessType = BusinessType.DELETE)
    @Log(title = "租户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] ids) {
@@ -142,7 +145,7 @@
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @GetMapping("/dynamic/{tenantId}")
    public R<Void> dynamicTenant(@NotBlank(message = "租户ID不能为空") @PathVariable String tenantId) {
        TenantHelper.setDynamic(tenantId);
        TenantHelper.setDynamic(tenantId, true);
        return R.ok();
    }
@@ -165,10 +168,25 @@
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @SaCheckPermission("system:tenant:edit")
    @Log(title = "租户", businessType = BusinessType.UPDATE)
    @Log(title = "租户管理", businessType = BusinessType.UPDATE)
    @GetMapping("/syncTenantPackage")
    public R<Void> syncTenantPackage(@NotBlank(message = "租户ID不能为空") String tenantId, @NotBlank(message = "套餐ID不能为空") String packageId) {
    public R<Void> syncTenantPackage(@NotBlank(message = "租户ID不能为空") String tenantId,
                                     @NotNull(message = "套餐ID不能为空") Long packageId) {
        return toAjax(TenantHelper.ignore(() -> tenantService.syncTenantPackage(tenantId, packageId)));
    }
    /**
     * åŒæ­¥ç§Ÿæˆ·å­—å…¸
     */
    @SaCheckRole(TenantConstants.SUPER_ADMIN_ROLE_KEY)
    @Log(title = "租户管理", businessType = BusinessType.INSERT)
    @GetMapping("/syncTenantDict")
    public R<Void> syncTenantDict() {
        if (!TenantHelper.isEnable()) {
            return R.fail("当前未开启租户模式");
        }
        tenantService.syncTenantDict();
        return R.ok("同步租户字典成功");
    }
}
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysTenantPackageController.java
@@ -14,8 +14,8 @@
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.system.domain.bo.SysTenantPackageBo;
import org.ruoyi.system.domain.vo.SysTenantPackageVo;
ruoyi-modules/ruoyi-system/src/main/java/org/ruoyi/system/controller/system/SysUserController.java
@@ -16,8 +16,8 @@
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.log.enums.BusinessType;
import org.ruoyi.common.mybatis.core.page.PageQuery;
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.common.satoken.utils.LoginHelper;
import org.ruoyi.common.tenant.helper.TenantHelper;
import org.ruoyi.common.web.core.BaseController;