chenping 1 سال پیش
کامیت
4f5fab6ab4
34فایلهای تغییر یافته به همراه2201 افزوده شده و 0 حذف شده
  1. 8 0
      .idea/.gitignore
  2. 18 0
      .idea/compiler.xml
  3. 6 0
      .idea/encodings.xml
  4. 50 0
      .idea/jarRepositories.xml
  5. 9 0
      .idea/jimureport_jenkins.iml
  6. 15 0
      .idea/misc.xml
  7. 6 0
      .idea/vcs.xml
  8. 16 0
      Dockerfile
  9. 66 0
      README.md
  10. 9 0
      db/Dockerfile
  11. 546 0
      db/jimureport.mysql5.7.create.sql
  12. 27 0
      docker-compose.yml
  13. 17 0
      docker.sh
  14. 33 0
      logs/error-log.html
  15. 229 0
      pom.xml
  16. 29 0
      src/main/java/com/jeecg/modules/JimuReportApplication.java
  17. 35 0
      src/main/java/com/jeecg/modules/jmreport/config/ApiSecurityConfigFilter.java
  18. 18 0
      src/main/java/com/jeecg/modules/jmreport/config/CustomCorsConfiguration.java
  19. 27 0
      src/main/java/com/jeecg/modules/jmreport/config/CustomLoginSuccessHandler.java
  20. 61 0
      src/main/java/com/jeecg/modules/jmreport/config/JimuReportSysSwitchFilter.java
  21. 30 0
      src/main/java/com/jeecg/modules/jmreport/config/RedisConfig.java
  22. 89 0
      src/main/java/com/jeecg/modules/jmreport/config/SpringSecurityConfig.java
  23. 42 0
      src/main/java/com/jeecg/modules/jmreport/config/ViewPageCustomAccess.java
  24. 21 0
      src/main/java/com/jeecg/modules/jmreport/controller/IndexController.java
  25. 116 0
      src/main/java/com/jeecg/modules/jmreport/extend/JimuDragExternalServiceImpl.java
  26. 204 0
      src/main/java/com/jeecg/modules/jmreport/extend/JimuReportTokenServiceImpl.java
  27. 90 0
      src/main/java/com/jeecg/modules/jmreport/testdb/TestRpSpringBean.java
  28. 85 0
      src/main/resources/application-dev.yml
  29. 78 0
      src/main/resources/application-prod.yml
  30. 3 0
      src/main/resources/application.yml
  31. 77 0
      src/main/resources/logback-spring.xml
  32. BIN
      src/main/resources/static/favicon.ico
  33. 5 0
      src/main/resources/static/login/cdn/bootstrap.min.css
  34. 136 0
      src/main/resources/static/login/login.html

+ 8 - 0
.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml

+ 18 - 0
.idea/compiler.xml

@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <annotationProcessing>
+      <profile name="Maven default annotation processors profile" enabled="true">
+        <sourceOutputDir name="target/generated-sources/annotations" />
+        <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
+        <outputRelativeToContentRoot value="true" />
+        <module name="jimureport" />
+      </profile>
+    </annotationProcessing>
+  </component>
+  <component name="JavacSettings">
+    <option name="ADDITIONAL_OPTIONS_OVERRIDE">
+      <module name="jimureport" options="-parameters" />
+    </option>
+  </component>
+</project>

+ 6 - 0
.idea/encodings.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding">
+    <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
+  </component>
+</project>

+ 50 - 0
.idea/jarRepositories.xml

@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="RemoteRepositoriesConfiguration">
+    <remote-repository>
+      <option name="id" value="nexus" />
+      <option name="name" value="nexus" />
+      <option name="url" value="http://192.168.1.252:8081/repository/maven-public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jeecg" />
+      <option name="name" value="jeecg Repository" />
+      <option name="url" value="https://maven.jeecg.org/nexus/content/repositories/jeecg" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jeecg-snapshots" />
+      <option name="name" value="jeecg snapshots Repository" />
+      <option name="url" value="https://maven.jeecg.org/nexus/content/repositories/snapshots/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="https://repo.maven.apache.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="aliyun" />
+      <option name="name" value="aliyun Repository" />
+      <option name="url" value="https://maven.aliyun.com/nexus/content/groups/public" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Maven Central repository" />
+      <option name="url" value="https://repo1.maven.org/maven2" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="jboss.community" />
+      <option name="name" value="JBoss Community repository" />
+      <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="central" />
+      <option name="name" value="Central Repository" />
+      <option name="url" value="http://maven.aliyun.com/repository/central" />
+    </remote-repository>
+    <remote-repository>
+      <option name="id" value="aliyunmavenspring" />
+      <option name="name" value="aliyunmavenspring" />
+      <option name="url" value="https://maven.aliyun.com/repository/public" />
+    </remote-repository>
+  </component>
+</project>

+ 9 - 0
.idea/jimureport_jenkins.iml

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

+ 15 - 0
.idea/misc.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ExternalStorageConfigurationManager" enabled="true" />
+  <component name="MavenProjectsManager">
+    <option name="originalFiles">
+      <list>
+        <option value="$PROJECT_DIR$/pom.xml" />
+      </list>
+    </option>
+    <option name="workspaceImportForciblyTurnedOn" value="true" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>

+ 6 - 0
.idea/vcs.xml

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

+ 16 - 0
Dockerfile

@@ -0,0 +1,16 @@
+FROM registry.cn-hangzhou.aliyuncs.com/jeecgdocker/alpine-java:8_server-jre_unlimited
+
+MAINTAINER jeecgos@163.com
+
+RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
+
+RUN mkdir -p /jimureport
+
+WORKDIR /jimureport
+
+EXPOSE 8085
+
+ADD jimureport-1.9.jar ./
+# ADD conf ./
+# ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Dfile.encoding=utf-8","jimureport-example-1.9.jar","--spring.config.location=config/"]
+CMD java -Dfile.encoding=utf-8 -Djava.security.egd=file:/dev/./urandom -Dspring.config.location=./conf/ -jar jimureport-1.9.jar

+ 66 - 0
README.md

@@ -0,0 +1,66 @@
+# jimureport-example
+
+积木报表集成示例代码。
+
+```
+采用mysql5.7数据库
+```
+
+
+
+
+使用步骤
+-----------------------------------
+
+-  第一步:执行初始化脚步(自动创建数据库jimureport)
+
+           db/jimureport.mysql5.7.create.sql
+           
+-  第三步: 启动项目(右键运行)
+
+           org.jeecg.modules.JimuReportApplication
+           
+-  第四步: 访问项目(默认账号:admin 密码:123456)
+
+      报表工作台: http://localhost:8085/jmreport/list
+      
+      仪表盘工作台: http://localhost:8085/drag/list
+           
+
+
+
+
+Docker镜像制作
+-----------------------------------
+
+-  第一步:下载项目
+
+         git clone https://gitee.com/jeecg/JimuReport.git
+
+-  第二步:进入项目 jimureport-example 根目录
+
+         cd JimuReport/jimureport-example
+	
+-  第三步:maven执行package
+
+         mvn clean package
+		 
+-  第四步:执行命令,生成镜像
+
+         docker-compose up -d
+		 
+-  第五步:访问报表(默认账号:admin 密码:123456)
+
+      报表工作台: http://localhost:8085/jmreport/list
+      
+      仪表盘工作台: http://localhost:8085/drag/list
+
+> 如果使用的是Mac M系列芯片:
+
+**1、将`jimureport-mysql`的基础镜像改为arm平台:**
+
+修改`JimuReport/db/Dockerfile`文件的第一行为:`FROM arm64v8/mysql:8`
+
+**2、 将`jimureport`的基础镜像改为arm平台**
+* 制作基于arm架构的jdk8的docker镜像。
+* 修改 `JimuReport/Dockerfile`文件的第一行为:`FROM <制作的镜像名称>`

+ 9 - 0
db/Dockerfile

@@ -0,0 +1,9 @@
+FROM registry.cn-hangzhou.aliyuncs.com/jeecgdocker/mysql:8.0.19
+
+MAINTAINER jeecgos@163.com
+
+ENV TZ=Asia/Shanghai
+
+RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
+
+COPY ./jimureport.mysql5.7.create.sql /docker-entrypoint-initdb.d

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 546 - 0
db/jimureport.mysql5.7.create.sql


+ 27 - 0
docker-compose.yml

@@ -0,0 +1,27 @@
+version: '2'
+services:
+  jimureport-mysql:
+    build:
+      context: ./db
+    environment:
+      MYSQL_ROOT_PASSWORD: root
+    restart: always
+    container_name: jimureport-mysql
+    image: jimureport-mysql
+    command:
+      --character-set-server=utf8mb4
+      --collation-server=utf8mb4_general_ci
+      --explicit_defaults_for_timestamp=true
+      --lower_case_table_names=1
+      --max_allowed_packet=128M
+    ports:
+      - 3307:3306
+
+  jimureport:
+    build:
+      context: .
+    restart: always
+    container_name: jimureport
+    image: jimureport
+    ports:
+      - 8085:8085

+ 17 - 0
docker.sh

@@ -0,0 +1,17 @@
+#!/bin/bash
+NS="kingdom"
+VERSION=1.9
+GROUP_ID="com.kingdom.aiot"
+ARTIFACT_ID="jimureport"
+docker container stop ${NS}-${ARTIFACT_ID} || true
+docker container rm ${NS}-${ARTIFACT_ID} || true
+docker image rm ${NS}/${ARTIFACT_ID} || true
+docker build -t ${NS}/${ARTIFACT_ID} ./
+
+# /opt/conf/aiot-api-starter/hosts: 定义主机名nacos.host,指向192.168.1.51
+# /opt/conf/aiot-api-starter/:  提供{application.properties, application-dev.properties}等配置文件,提供数据库连接串等信息
+docker run -idt --name ${NS}-${ARTIFACT_ID} -p 8085:8085 -e TZ="Asia/Shanghai" \
+        -v /etc/localtime:/etc/localtime:ro \
+        -v /opt/conf/${ARTIFACT_ID}/:/jimureport/conf \
+        -v /opt/logs/${ARTIFACT_ID}:/jimureport/logs  \
+        --privileged=true --restart=always ${NS}/${ARTIFACT_ID}

+ 33 - 0
logs/error-log.html

@@ -0,0 +1,33 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+  <head>
+    <title>Logback Log Messages</title>
+<style  type="text/css">
+table { margin-left: 2em; margin-right: 2em; border-left: 2px solid #AAA; }
+TR.even { background: #FFFFFF; }
+TR.odd { background: #EAEAEA; }
+TR.warn TD.Level, TR.error TD.Level, TR.fatal TD.Level {font-weight: bold; color: #FF4040 }
+TD { padding-right: 1ex; padding-left: 1ex; border-right: 2px solid #AAA; }
+TD.Time, TD.Date { text-align: right; font-family: courier, monospace; font-size: smaller; }
+TD.Thread { text-align: left; }
+TD.Level { text-align: right; }
+TD.Logger { text-align: left; }
+TR.header { background: #596ED5; color: #FFF; font-weight: bold; font-size: larger; }
+TD.Exception { background: #A2AEE8; font-family: courier, monospace;}
+</style>
+
+  </head>
+<body>
+<hr/>
+<p>Log session start time Thu Feb 13 13:59:15 CST 2025</p><p></p>
+
+<table cellspacing="0">
+<tr class="header">
+<td class="Level">Level</td>
+<td class="Date">Date</td>
+<td class="Message">Message</td>
+<td class="MethodOfCaller">MethodOfCaller</td>
+<td class="FileOfCaller">FileOfCaller</td>
+<td class="LineOfCaller">LineOfCaller</td>
+</tr>
+

+ 229 - 0
pom.xml

@@ -0,0 +1,229 @@
+<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.7.18</version>
+        <relativePath/>
+    </parent>
+
+    <name>jimureport</name>
+    <groupId>org.jeecg</groupId>
+    <artifactId>jimureport</artifactId>
+    <version>1.9</version>
+
+    <url>http://www.jimureport.com</url>
+    <description>积木报表集成示例</description>
+
+    <repositories>
+        <repository>
+            <id>aliyun</id>
+            <name>aliyun Repository</name>
+            <url>https://maven.aliyun.com/nexus/content/groups/public</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>jeecg</id>
+            <name>jeecg Repository</name>
+            <url>https://maven.jeecg.org/nexus/content/repositories/jeecg</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>jeecg-snapshots</id>
+            <name>jeecg snapshots Repository</name>
+            <url>https://maven.jeecg.org/nexus/content/repositories/snapshots/</url>
+            <snapshots>
+                <enabled>true</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <properties>
+        <jimureport.version>1.9.3</jimureport.version>
+        <java.version>1.8</java.version>
+        <minio.version>8.0.3</minio.version>
+        <!-- DB驱动 -->
+        <mysql-connector-java.version>8.0.27</mysql-connector-java.version>
+        <!-- SQL解析引擎 -->
+        <jsqlparser.version>4.6</jsqlparser.version>
+        <kingdom.version>0.0.1-SNAPSHOT</kingdom.version>
+    </properties>
+
+
+
+
+    <dependencies>
+        <!-- Lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <!-- 积木报表 -->
+        <dependency>
+            <groupId>org.jeecgframework.jimureport</groupId>
+            <artifactId>jimureport-spring-boot-starter</artifactId>
+            <version>${jimureport.version}</version>
+        </dependency>
+        <!-- 积木报表扩展包 csv excel json mogodb redis数据集支持 -->
+        <dependency>
+            <groupId>org.jeecgframework.jimureport</groupId>
+            <artifactId>jimureport-nosql-starter</artifactId>
+            <version>${jimureport.version}</version>
+        </dependency>
+        <!-- 积木BI大屏 -->
+        <dependency>
+            <groupId>org.jeecgframework.jimureport</groupId>
+            <artifactId>jimubi-spring-boot-starter</artifactId>
+            <version>${jimureport.version}</version>
+        </dependency>
+        <!-- jsqlparser -->
+        <dependency>
+            <groupId>com.github.jsqlparser</groupId>
+            <artifactId>jsqlparser</artifactId>
+            <version>${jsqlparser.version}</version>
+        </dependency>
+
+
+        <!-- SpringBoot-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-freemarker</artifactId>
+        </dependency>
+
+        <!--spring security-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-security</artifactId>
+        </dependency>
+        
+        <!-- minio oss-->
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>${minio.version}</version>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- ============================数据库驱动========================== -->
+        <!--mysql-->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>${mysql-connector-java.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- oracle驱动-->
+        <dependency>
+            <groupId>com.oracle</groupId>
+            <artifactId>ojdbc6</artifactId>
+            <version>11.2.0.3</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--  sqlserver-->
+       <dependency>
+           <groupId>com.microsoft.sqlserver</groupId>
+           <artifactId>sqljdbc4</artifactId>
+           <version>4.0</version>
+           <scope>runtime</scope>
+       </dependency>
+        <!-- postgresql驱动-->
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>42.2.6</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- ===需要什么数据库,手工打开注释=== -->
+        <!-- 达梦驱动-->
+        <dependency>
+            <groupId>com.dameng</groupId>
+            <artifactId>DmJdbcDriver18</artifactId>
+            <version>1.0</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.dameng</groupId>
+            <artifactId>DmDialectForHibernate</artifactId>
+            <version>5.3</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!-- sqlite-->
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.34.0</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--hsqldb-->
+        <dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>2.2.8</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--h2-->
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>1.4.197</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--derby-->
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derbyclient</artifactId>
+            <version>10.11.1.1</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--db2-->
+        <dependency>
+            <groupId>com.ibm.db2</groupId>
+            <artifactId>jcc</artifactId>
+            <version>11.5.0.0</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--神通-->
+        <dependency>
+            <groupId>com.csicit.thirdparty</groupId>
+            <artifactId>oscar</artifactId>
+            <version>1.0.1</version>
+            <scope>runtime</scope>
+        </dependency>
+        <!--人大金仓-->
+        <dependency>
+            <groupId>kingbase</groupId>
+            <artifactId>kingbase8</artifactId>
+            <version>8</version>
+            <scope>runtime</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.auth0</groupId>
+            <artifactId>java-jwt</artifactId>
+            <version>3.10.2</version>
+        </dependency>
+        <!-- ============================数据库驱动========================== -->
+
+    </dependencies>
+    <build>
+        <plugins>
+            <!-- SpringBoot启动 -->
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 29 - 0
src/main/java/com/jeecg/modules/JimuReportApplication.java

@@ -0,0 +1,29 @@
+package com.jeecg.modules;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.env.Environment;
+
+/**
+ * 积木报表独立服务启动类
+ */
+@SpringBootApplication(scanBasePackages = {"org.jeecg", "com.jeecg"})
+@EnableAutoConfiguration(exclude = {MongoAutoConfiguration.class})
+public class JimuReportApplication {
+
+    public static void main(String[] args) {
+        ConfigurableApplicationContext application = SpringApplication.run(JimuReportApplication.class, args);
+        Environment env = application.getEnvironment();
+        String port = env.getProperty("server.port");
+        String path = env.containsProperty("server.servlet.context-path") ? env.getProperty("server.servlet.context-path") : "";
+        System.out.println("\n----------------------------------------------------------\n\t" +
+                "JimuReport 积木报表平台 is running!  Access URL:\n\t" +
+                "报表工作台: \t\thttp://localhost:" + port + path + "/jmreport/list\n\t" +
+                "BI大屏工作台: \t\thttp://localhost:" + port + path + "/drag/list\n\t" +
+                "----------------------------------------------------------");
+    }
+
+}

+ 35 - 0
src/main/java/com/jeecg/modules/jmreport/config/ApiSecurityConfigFilter.java

@@ -0,0 +1,35 @@
+package com.jeecg.modules.jmreport.config;
+
+import com.alibaba.fastjson.JSONObject;
+import org.jeecg.modules.jmreport.common.util.OkConvertUtils;
+import org.springframework.security.core.context.SecurityContextImpl;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+* @Description: api访问权限过滤器
+*
+* @author: wangshuai
+* @date: 2024/9/25 下午6:22
+*/
+public class ApiSecurityConfigFilter implements Filter {
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletRequest req = (HttpServletRequest) request;
+        String loginFrom = req.getHeader("jm_login_from");
+        if(OkConvertUtils.isNotEmpty(loginFrom)){
+            String springSecurityContext = req.getHeader("jm_spring_security_context");
+            if(OkConvertUtils.isNotEmpty(springSecurityContext)){
+                SecurityContextImpl securityContext = JSONObject.parseObject(springSecurityContext, SecurityContextImpl.class);
+                HttpSession session = req.getSession();
+                session.setAttribute("loginFrom", loginFrom);
+                session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
+            }
+        }
+        chain.doFilter(request, response);
+    }
+}

+ 18 - 0
src/main/java/com/jeecg/modules/jmreport/config/CustomCorsConfiguration.java

@@ -0,0 +1,18 @@
+package com.jeecg.modules.jmreport.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+public class CustomCorsConfiguration implements WebMvcConfigurer {
+    @Override
+    public void addCorsMappings(CorsRegistry registry) {
+        registry.addMapping("/**") // 所有接口
+                .allowCredentials(true) // 是否发送 Cookie
+                .allowedOriginPatterns("*") // 支持域
+                .allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}) // 支持方法
+                .allowedHeaders("*")
+                .exposedHeaders("*");
+    }
+}

+ 27 - 0
src/main/java/com/jeecg/modules/jmreport/config/CustomLoginSuccessHandler.java

@@ -0,0 +1,27 @@
+package com.jeecg.modules.jmreport.config;
+
+import org.springframework.security.core.Authentication;
+import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+ * 自定义springsecurity登录成功处理
+ * [TV360X-1884]jimureport-example集成简单的 spring security,设置登录账号密码
+ * @author chenrui
+ * @date 2024/8/2 16:26
+ */
+public class CustomLoginSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
+
+    @Override
+    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
+                                        Authentication authentication) throws IOException, ServletException {
+        HttpSession session = request.getSession();
+        session.setAttribute("loginFrom", "jimu_example");
+        super.onAuthenticationSuccess(request, response, authentication);
+    }
+}

+ 61 - 0
src/main/java/com/jeecg/modules/jmreport/config/JimuReportSysSwitchFilter.java

@@ -0,0 +1,61 @@
+package com.jeecg.modules.jmreport.config;
+
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+
+/**
+ * 积木报表子系统切换处理类
+ * @author chenrui
+ * @date 2024/10/31 11:33
+ */
+@Component("jimuReportSwitchSysHandler")
+public class JimuReportSysSwitchFilter implements Filter {
+
+    // 包含积木报表
+    boolean includeJimuReport = false;
+    // 包含积木仪表盘
+    boolean includeJimuDrag = false;
+
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        Filter.super.init(filterConfig);
+        // 判断是否包含积木报表
+        try {
+            Class.forName("org.jeecg.modules.jmreport.config.JmReportBaseConfig");
+            includeJimuReport = true;
+        } catch (ClassNotFoundException ignored) {
+        }
+        // 判断是否包含积木仪表盘
+        try {
+            Class.forName("org.jeecg.modules.drag.service.IOnlDragCompService");
+            includeJimuDrag = true;
+        } catch (ClassNotFoundException ignored) {
+        }
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        if (request instanceof HttpServletRequest) {
+            HttpServletRequest httpRequest = (HttpServletRequest) request;
+            HttpSession session = httpRequest.getSession();
+            if(includeJimuReport) {
+                session.setAttribute("switchJimuReport", "true");
+            }else{
+                session.setAttribute("switchJimuReport", "false");
+            }
+            if(includeJimuDrag) {
+                session.setAttribute("switchJimuDrag", "true");
+            }else {
+                session.setAttribute("switchJimuDrag", "false");
+            }
+        }
+        chain.doFilter(request, response);
+    }
+
+
+}

+ 30 - 0
src/main/java/com/jeecg/modules/jmreport/config/RedisConfig.java

@@ -0,0 +1,30 @@
+package com.jeecg.modules.jmreport.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+
+/**
+ * RedisTemplate实例化
+ */
+@Slf4j
+@Configuration
+@ConditionalOnMissingBean(RedisTemplate.class)
+public class RedisConfig {
+
+    @Bean
+    JedisConnectionFactory jedisConnectionFactory() {
+        return new JedisConnectionFactory();
+    }
+
+    @Bean
+    public RedisTemplate<String, Object> redisTemplate() {
+        log.info("---- jimubi Redis Template init----");
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(jedisConnectionFactory());
+        return template;
+    }
+}

+ 89 - 0
src/main/java/com/jeecg/modules/jmreport/config/SpringSecurityConfig.java

@@ -0,0 +1,89 @@
+package com.jeecg.modules.jmreport.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
+
+/**
+ * spring security 配置
+ * [TV360X-1884]jimureport-example集成简单的 spring security,设置登录账号密码
+ * @Author chenrui
+ * @Date 2024-07-23
+ */
+@Configuration
+@EnableWebSecurity
+public class SpringSecurityConfig {
+
+
+    @Bean
+    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
+        http.csrf().disable()
+                .authorizeRequests()
+                .antMatchers("/login/**").permitAll()
+
+                // 放过静态资源
+                .antMatchers("/jmreport/**/cdn/**",
+                        "/jmreport/desreport_/**/*.js",
+                        "/jmreport/desreport_/**/*.css",
+                        "/jmreport/desreport_/**/*.ico",
+                        "/jmreport/desreport_/**/*.png").permitAll()
+                // 放过静态资源-仪表盘
+                .antMatchers("/drag/lib/**/*.css",
+                        "/drag/lib/**/*.js",
+                        "/drag/lib/**/*.png",
+                        "/drag/**/*.ico").permitAll()
+                // 不需要登录的接口
+                .antMatchers("/jmreport/excelQueryByTemplate",
+                        "/jmreport/query/report/folder/template",
+                        "/jmreport/img/**",
+                        "/jmreport/download/image",
+                        "/jmreport/verificationToken",
+                        "/jmreport/link/queryByIds",
+                        "/jmreport/test/getUserMsg",
+                        "/jmreport/test/getOrder",
+                        "/jimureport/test/**",
+                        "/jmreport/auto/export/download/**").permitAll()
+                // 分享页面
+                .antMatchers("/jmreport/shareView/**",
+                        "/jmreport/exportPdfStream",
+                        "/jmreport/exportAllExcelStream",
+                        "/jmreport/checkParam/**",
+                        "/jmreport/share/verification",
+                        "/jmreport/getQueryInfo",
+                        "/jmreport/show",
+                        "/jmreport/addViewCount/**").permitAll()
+                // 仪表盘分享页面
+                .antMatchers("/drag/share/view/**",
+                        "/drag/page/queryById",
+                        "/drag/page/addVisitsNumber",
+                        "/drag/page/queryTemplateList",
+                        "/drag/onlDragDatasetHead/getAllChartData",
+                        "/drag/onlDragDatasetHead/getTotalData",
+                        "drag/mock/json/**",
+                        "drag/getImageBase64/**").permitAll()
+                // view页面
+                .antMatchers("/jmreport/view/**").access("@viewPageCustomAccess.check(request,authentication)")
+                .anyRequest().authenticated() //所有页面都需验证登录 。不需要集成到菜单,放开这里,用jimu登录页面进行报表设计
+                //.anyRequest().permitAll() //所有页面 不验证登录,需要集成到菜单,把这里放开就可以了
+                .and()
+                .formLogin()
+                .loginPage("/login/login.html")
+                .loginProcessingUrl("/login")
+                .successHandler(new CustomLoginSuccessHandler())
+                .permitAll().and()
+                .addFilterBefore(new ApiSecurityConfigFilter(), BasicAuthenticationFilter.class)
+                .logout()
+                .invalidateHttpSession(true)
+                .clearAuthentication(true).permitAll();
+        // 开放iframe访问限制
+        http.headers().frameOptions().disable();
+        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
+        http.rememberMe().useSecureCookie(true);
+
+        return http.build();
+    }
+}

+ 42 - 0
src/main/java/com/jeecg/modules/jmreport/config/ViewPageCustomAccess.java

@@ -0,0 +1,42 @@
+package com.jeecg.modules.jmreport.config;
+
+import org.jeecg.modules.jmreport.common.util.OkConvertUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.security.core.Authentication;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 自定义view页面access处理
+ * for: [TV360X-2206] 目前这个版本必须登录后才能看报表,如何设置不登录也能查看报表 #2919
+ * @author chenrui
+ * @date 2024/8/23 14:28
+ */
+@Component("viewPageCustomAccess")
+public class ViewPageCustomAccess {
+
+    @Value("${spring.security.open-view-page:false}")
+    boolean openViewPage = false;
+
+    public boolean check(HttpServletRequest request, Authentication authentication) {
+        Object principal = authentication.getPrincipal();
+        if (OkConvertUtils.isEmpty(principal) || "anonymousUser".equalsIgnoreCase(principal.toString())) {
+            // 未登录
+            if (openViewPage) {
+                // 配置文件设置了开放view页面
+                return true;
+            }
+            HttpServletRequest httpRequest = (HttpServletRequest) request;
+            String previousPage = httpRequest.getParameter("previousPage");
+            String jmLink = httpRequest.getParameter("jmLink");
+            if (OkConvertUtils.isNotEmpty(previousPage) && OkConvertUtils.isNotEmpty(jmLink) ) {
+                // 参数中有previousPage和jmLink
+                return true;
+            }
+            return false;
+        }
+        return true;
+    }
+}
+

+ 21 - 0
src/main/java/com/jeecg/modules/jmreport/controller/IndexController.java

@@ -0,0 +1,21 @@
+package com.jeecg.modules.jmreport.controller;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * 积木报表-设置默认首页跳转
+ */
+@Controller
+public class IndexController {
+    private Logger logger = LoggerFactory.getLogger(IndexController.class);
+
+    @GetMapping("/")
+    public String index(Model model) {
+        model.addAttribute("name", "jimureport");
+        return "jmreport/list"; // 视图重定向 - 跳转
+    }
+}

+ 116 - 0
src/main/java/com/jeecg/modules/jmreport/extend/JimuDragExternalServiceImpl.java

@@ -0,0 +1,116 @@
+package com.jeecg.modules.jmreport.extend;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.drag.service.IOnlDragExternalService;
+import org.jeecg.modules.drag.vo.DragDictModel;
+import org.jeecg.modules.drag.vo.DragLogDTO;
+import org.jeecg.modules.jmreport.common.util.OkConvertUtils;
+import org.jeecg.modules.jmreport.common.vo.JmDictModel;
+import org.jeecg.modules.jmreport.desreport.service.IJimuReportDictService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @Description: 字典处理
+ * @Author: lsq
+ * @Date:2023-01-09
+ * @Version:V1.0
+ */
+@Slf4j
+@Component
+public class JimuDragExternalServiceImpl implements IOnlDragExternalService {
+
+
+    @Autowired
+    @Lazy
+    private IJimuReportDictService reportDictService;
+
+    /**
+     *  根据多个字典code查询多个字典项
+     * @param codeList
+     * @return key = dictCode ; value=对应的字典项
+     */
+    @Override
+    public Map<String, List<DragDictModel>> getManyDictItems(List<String> codeList, List<JSONObject> tableDictList) {
+        Map<String, List<DragDictModel>> manyDragDictItems  = new HashMap<>();
+        if(!CollectionUtils.isEmpty(codeList)){
+            Map<String, List<JmDictModel>> dictItemsMap = reportDictService.getManyDictItems(codeList);
+            dictItemsMap.forEach((k,v)->{
+                List<DragDictModel> dictItems  = new ArrayList<>();
+                v.forEach(dictItem->{
+                    DragDictModel dictModel = new DragDictModel();
+                    BeanUtils.copyProperties(dictItem,dictModel);
+                    dictItems.add(dictModel);
+                });
+                manyDragDictItems.put(k,dictItems);
+            });
+        }
+        if(!CollectionUtils.isEmpty(tableDictList)){
+            tableDictList.forEach(item->{
+                List<DragDictModel> dictItems  = new ArrayList<>();
+                JSONObject object = JSONObject.parseObject(item.toString());
+                String dictField = object.getString("dictField");
+                String dictTable = object.getString("dictTable");
+                String dictText = object.getString("dictText");
+                String fieldName = object.getString("fieldName");
+                List<JmDictModel> dictItemsList = reportDictService.queryTableDictItemsByCode(dictTable,dictText,dictField);
+                dictItemsList.forEach(dictItem->{
+                    DragDictModel dictModel = new DragDictModel();
+                    BeanUtils.copyProperties(dictItem,dictModel);
+                    dictItems.add(dictModel);
+                });
+                manyDragDictItems.put(fieldName,dictItems);
+            });
+        }
+        return manyDragDictItems;
+    }
+
+    /**
+     *
+     * @param dictCode
+     * @return
+     */
+    @Override
+    public List<DragDictModel> getDictItems(String dictCode) {
+        List<DragDictModel> dictItems  = new ArrayList<>();
+        if(OkConvertUtils.isNotEmpty(dictCode)){
+            List<JmDictModel> dictItemsList = reportDictService.queryDictItemsByCode(dictCode);
+            dictItemsList.forEach(dictItem->{
+                DragDictModel dictModel = new DragDictModel();
+                BeanUtils.copyProperties(dictItem,dictModel);
+                dictItems.add(dictModel);
+            });
+        }
+        return dictItems;
+    }
+
+    /**
+     * 添加日志
+     * @param dragLogDTO
+     */
+    @Override
+    public void addLog(DragLogDTO dragLogDTO) {
+
+    }
+
+    /**
+     * 保存日志
+     * @param logMsg
+     * @param logType
+     * @param operateType
+     */
+    @Override
+    public void addLog(String logMsg, int logType, int operateType) {
+
+    }
+}

+ 204 - 0
src/main/java/com/jeecg/modules/jmreport/extend/JimuReportTokenServiceImpl.java

@@ -0,0 +1,204 @@
+package com.jeecg.modules.jmreport.extend;
+
+
+//import com.kingdom.common.utils.jwt.JwtUtil;
+//import com.kingdom.main.biz.service.UserService;
+//import com.kingdom.main.biz.vo.UserVO;
+//import com.kingdom.sys.biz.dto.AccountDTO;
+//import com.kingdom.sys.biz.service.AccountApiService;
+//import org.apache.shiro.authc.AuthenticationException;
+//import org.apache.shiro.web.util.WebUtils;
+import com.auth0.jwt.JWT;
+import com.auth0.jwt.JWTVerifier;
+import com.auth0.jwt.algorithms.Algorithm;
+import com.auth0.jwt.exceptions.TokenExpiredException;
+import com.auth0.jwt.interfaces.DecodedJWT;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.auth.AuthenticationException;
+import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
+import org.jeecg.modules.jmreport.common.util.JimuSpringContextUtils;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.http.HttpHeaders;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
+ * 1.自定义获取登录token
+ * 2.自定义获取登录用户
+ */
+@Component
+@Slf4j
+public class JimuReportTokenServiceImpl implements JmReportTokenServiceI {
+    private static final String SECRET = "zoomwin[qwertyuiopasdfghjklzxcvbnm9876543210]";
+
+    public final static String ACCOUNT_ID = "accountId";
+    public final static String USER_ID = "userId";
+    public final static String GROUP_ID = "groupId";
+
+    /**
+     * 通过请求获取Token
+     * @param request
+     * @return
+     */
+//    @Override
+//    public String getToken(HttpServletRequest request) {
+//        if(request==null){
+//            return null;
+//        }
+//        String token = request.getParameter("token");
+//        if(token==null){
+//            token = request.getHeader("X-Access-Token");
+//        }
+//        return token;
+//    }
+
+    /**
+     * 自定义获取租户
+     *
+     * @return
+     */
+    @Override
+    public String getTenantId() {
+//        String headerTenantId = null;
+//        HttpServletRequest request = JimuSpringContextUtils.getHttpServletRequest();
+//        if (request != null) {
+//            headerTenantId = request.getHeader(JmConst.HEADER_TENANT_ID);
+//            if(OkConvertUtils.isEmpty(headerTenantId)){
+//                headerTenantId = request.getParameter(JmConst.TENANT_ID);
+//            }
+//        }
+//        return headerTenantId;
+        return "1";
+    }
+
+    
+    /**
+     * 通过Token获取登录人用户名
+     * @param token
+     * @return
+     */
+    @Override
+    public String getUsername(String token) {
+        if(StringUtils.isBlank(token)){
+            return "";
+        }
+        final String strUserId = this.getClaim(token, USER_ID);
+        // return JwtUtil.getUsername(token);
+        return strUserId;
+    }
+    @Override
+    public Map<String, Object> getUserInfo(String token) {
+        if(StringUtils.isBlank(token)){
+            return new HashMap<>();
+        }
+        final String strUserId = this.getClaim(token, USER_ID);//员工ID
+        final String strGroupId = this.getClaim(token, GROUP_ID);//组织机构ID
+        //此处通过token只能拿到一个信息 用户账号  后面的就是根据账号获取其他信息 查询数据或是走redis 用户根据自身业务可自定义
+        //SysUserCacheInfo userInfo = sysBaseAPI.getCacheUser(username);
+        Map<String, Object> map = new HashMap<String, Object>();
+        //设置账号名
+        map.put("sysUserCode", strUserId);
+        //设置部门编码
+        map.put("sysOrgCode", strGroupId);
+        // 将所有信息存放至map 解析sql会根据map的键值解析,可自定义其他值
+        return map;
+    }
+    /**
+     * 自定义用户拥有的角色
+     * 
+     * @param token
+     * @return
+     */
+    @Override
+    public String[] getRoles(String token) {
+        //积木内置三个角色 "admin","lowdeveloper","dbadeveloper"
+        return new String[]{"admin","lowdeveloper","dbadeveloper"};
+    }
+
+
+    /**
+     * 自定义用户拥有的权限指令
+     * 
+     * @param token
+     * @return
+     */
+    @Override
+    public String[] getPermissions(String token) {
+        //drag:datasource:testConnection   仪表盘数据库连接测试
+        //onl:drag:clear:recovery          清空回收站
+        //drag:analysis:sql                SQL解析
+        //drag:design:getTotalData         仪表盘对Online表单展示数据
+        return new String[]{"drag:datasource:testConnection","onl:drag:clear:recovery","drag:analysis:sql","drag:design:getTotalData"};
+    }
+    
+    /**
+     * Token校验
+     * @param token
+     * @return
+     */
+    @Override
+    public Boolean verifyToken(String token) {
+        //token为空 则校验是否登陆
+        if(StringUtils.isBlank(token)||"null".equals(token)){
+            HttpServletRequest request=JimuSpringContextUtils.getHttpServletRequest();
+           // HttpServletRequest request =    ( (ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
+            HttpSession session=  request.getSession();
+            Object loginResult= session.getAttribute("loginFrom");
+            if("jimu_example".equals(loginResult)){
+                return true;
+            }
+            return false;
+        }
+
+
+        // 根据密码生成JWT效验器
+        Algorithm algorithm = Algorithm.HMAC256(SECRET);
+        try {
+            JWTVerifier verifier = JWT.require(algorithm).build();
+            verifier.verify(token);
+            return true;
+        } catch (Exception e) {
+            log.error("JWT Token verify方法验证异常:" + e.getMessage());
+            return false;
+        }
+
+    }
+
+    /**
+     *  自定义请求头
+     * @return
+     */
+    @Override
+    public HttpHeaders customApiHeader() {
+        HttpHeaders header = new HttpHeaders();
+        String token=getToken();
+        header.add("Authorization", token);
+
+        return header;
+    }
+    public static String getClaim(String token, String claim) {
+        log.info("解析token:{}",token);
+        if (token == null) {
+            throw new RuntimeException("Token传值不能为空");
+        }
+        DecodedJWT decode = JWT.decode(token);
+        Date expiresAt = decode.getExpiresAt();
+        if (expiresAt.before(new Date())) {
+            throw new TokenExpiredException("Token已失效");
+        }
+        return decode.getClaim(claim).asString();
+    }
+
+}

+ 90 - 0
src/main/java/com/jeecg/modules/jmreport/testdb/TestRpSpringBean.java

@@ -0,0 +1,90 @@
+package com.jeecg.modules.jmreport.testdb;
+
+import lombok.extern.slf4j.Slf4j;
+import org.jeecg.modules.jmreport.common.util.OkConvertUtils;
+import org.jeecg.modules.jmreport.desreport.model.JmPage;
+import org.jeecg.modules.jmreport.api.data.IDataSetFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author qinfeng
+ */
+@Slf4j
+@Component("testDataJavaBean")
+public class TestRpSpringBean implements IDataSetFactory {
+
+    /**
+     * 不分页时返回list
+     * @param param 参数 包括浏览器地址栏 和 查询条件
+     * @return
+     */
+    @Override
+    public List<Map<String, Object>> createData(Map<String, Object> param) {
+        log.info(" 自定义javabean,无分页 :" + param);
+        List<Map<String, Object>> ls = new ArrayList<>();
+        Map<String, Object> obj2 = new HashMap<>();
+        obj2.put("name", "张三");
+        obj2.put("age", "14");
+        ls.add(obj2);
+
+        Map<String, Object> obj3 = new HashMap<>();
+        obj3.put("name", "李四");
+        obj3.put("age", "15");
+        ls.add(obj3);
+
+        Map<String, Object> obj4 = new HashMap<>();
+        obj4.put("name", "王五");
+        obj4.put("age", "16");
+        ls.add(obj4);
+
+        return ls;
+    }
+
+    /**
+     * 分页时返回 JmPage 并且参数param里会传入pageNo, pageSize
+     * @param param 参数 包括浏览器地址栏 和 查询条件
+     * @return
+     */
+    @Override
+    public JmPage createPageData(Map<String, Object> param) {
+        //默认必须有分页参数 pageSize
+        if(!param.containsKey("pageSize")){
+            param.put("pageSize",1);
+        }
+
+        log.info(" 自定义javabean,有分页 :" + param);
+
+        JmPage page = new JmPage();
+        List<Map<String, Object>> ls = new ArrayList<>();
+        int pageSize =  OkConvertUtils.getInt(param.get("pageSize").toString(),1);
+
+        Map<String, Object> obj2 = new HashMap<>();
+        obj2.put("name", "张三");
+        obj2.put("age", "14");
+        obj2.put("sex", "1");
+        ls.add(obj2);
+
+        Map<String, Object> obj3 = new HashMap<>();
+        obj3.put("name", "李四");
+        obj3.put("age", "15");
+        obj2.put("sex", "2");
+        ls.add(obj3);
+
+        Map<String, Object> obj4 = new HashMap<>();
+        obj4.put("name", "王五");
+        obj4.put("age", "16");
+        obj2.put("sex", "2");
+        ls.add(obj4);
+
+        //以下参数均需设置
+        page.setPageSize(pageSize);
+        page.setTotal(20);
+        page.setRecords(ls);
+        return page;
+    }
+}

+ 85 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,85 @@
+server:
+  port: 8085
+spring:
+  #数据库
+  datasource:
+    url: jdbc:mysql://${MYSQL-HOST:192.168.1.251}:${MYSQL-PORT:3306}/${MYSQL-DB:jimu}?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+    username: root
+    password: 666888
+    driver-class-name: com.mysql.cj.jdbc.Driver
+  security:
+    #放开预览页面不需要登录
+    open-view-page: true
+    #登录账号和密码
+    user:
+      name: "admin"
+      password: "123456"
+  #配置freemarker
+  freemarker:
+    # 设置模板后缀名
+    suffix: .ftl
+    # 设置文档类型
+    content-type: text/html
+    # 设置页面编码格式
+    charset: UTF-8
+    # 设置页面缓存
+    cache: false
+    prefer-file-system-access: false
+    # 设置ftl文件路径
+    template-loader-path:
+      - classpath:/templates
+    template_update_delay: 0
+#持久层框架
+minidao:
+  base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*
+jeecg:
+  # local|minio|alioss
+  uploadType: minio
+  # local
+  path:
+    #文件路径
+    upload: /opt/upload
+  # alioss
+  oss:
+    endpoint: ??
+    accessKey: ??
+    secretKey: ??
+    bucketName: jimureport
+  # minio
+  minio:
+    minio_url: http://192.168.1.251:9001
+    minio_name: admin
+    minio_pass: admin123
+    bucketName: kd-aiot
+  #大屏报表参数设置
+  jmreport:
+    #多租户模式,默认值为空(created:按照创建人隔离、tenant:按照租户隔离)
+    saasMode:
+    # 平台上线安全配置
+    firewall:
+      # 数据源安全 (开启后,不允许使用平台数据源、SQL解析加签并且不允许查询数据库)
+      dataSourceSafe: false
+      # 低代码开发模式(dev:开发模式,prod:发布模式—关闭在线报表设计功能,分配角色admin、lowdeveloper可放开限制)
+      lowCodeMode: dev
+    # 展示列数
+    col: 100
+    # 展示行数
+    row: 200
+    #自定义API接口的前缀 #{api_base_path}和#{domainURL}的值
+    apiBasePath: http://192.168.1.11:8085
+    pageSize:
+      - 10
+      - 20
+      - 30
+      - 40
+    # 邮件发送
+    mail:
+      enabled: false
+      sender: 积木报表
+      host: smtp.exmail.qq.com
+      username: ??
+      password: ??
+#输出sql日志
+logging:
+  level:
+    org.jeecg.modules.jmreport: info

+ 78 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,78 @@
+server:
+  port: 8085
+spring:
+  #数据库
+  datasource:
+    url: jdbc:mysql://${MYSQL-HOST:127.0.0.1}:${MYSQL-PORT:3306}/${MYSQL-DB:jimureport}?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
+    username: root
+    password: root
+    driver-class-name: com.mysql.cj.jdbc.Driver
+  security:
+    #放开预览页面不需要登录
+    open-view-page: true
+    #登录账号和密码
+    user:
+      name: "admin"
+      password: "123456"
+  #配置freemarker
+  freemarker:
+    # 设置模板后缀名
+    suffix: .ftl
+    # 设置文档类型
+    content-type: text/html
+    # 设置页面编码格式
+    charset: UTF-8
+    # 设置页面缓存
+    cache: false
+    prefer-file-system-access: false
+    # 设置ftl文件路径
+    template-loader-path:
+      - classpath:/templates
+    template_update_delay: 0
+#持久层框架
+minidao:
+  base-package: org.jeecg.modules.jmreport.*,org.jeecg.modules.drag.*
+jeecg:
+  # local|minio|alioss
+  uploadType: local
+  # local
+  path:
+    #文件路径
+    upload: /opt/upload
+  # alioss
+  oss:
+    endpoint: ??
+    accessKey: ??
+    secretKey: ??
+    bucketName: jimureport
+  # minio
+  minio:
+    minio_url: http://minio.jeecg.com
+    minio_name: ??
+    minio_pass: ??
+    bucketName: ??
+  #大屏报表参数设置
+  jmreport:
+    #多租户模式,默认值为空(created:按照创建人隔离、tenant:按照租户隔离)
+    saasMode: created
+    # 平台上线安全配置
+    firewall:
+      # 数据源安全 (开启后,不允许使用平台数据源、SQL解析加签并且不允许查询数据库)
+      dataSourceSafe: true
+      # 低代码开发模式(dev:开发模式,prod:发布模式—关闭在线报表设计功能,分配角色admin、lowdeveloper可放开限制)
+      lowCodeMode: prod
+    # 展示列数
+    col: 100
+    # 展示行数
+    row: 200
+    #自定义API接口的前缀 #{api_base_path}和#{domainURL}的值
+    apiBasePath: http://192.168.1.11:8085
+    pageSize:
+      - 10
+      - 20
+      - 30
+      - 40
+#输出sql日志
+logging:
+  level:
+    org.jeecg.modules.jmreport: info

+ 3 - 0
src/main/resources/application.yml

@@ -0,0 +1,3 @@
+spring:
+  profiles:
+    active: dev

+ 77 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration debug="false">
+	<!--定义日志文件的存储地址 -->
+	<property name="LOG_HOME" value="./logs" />
+
+	<!--<property name="COLOR_PATTERN" value="%black(%contextName-) %red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta( %replace(%caller{1}){'\t|Caller.{1}0|\r\n', ''})- %gray(%msg%xEx%n)" />-->
+	<!-- 控制台输出 -->
+	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>-->
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n</pattern>
+		</encoder>
+	</appender>
+
+	<!-- 按照每天生成日志文件 -->
+	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<!--日志文件输出的文件名 -->
+			<FileNamePattern>${LOG_HOME}/jimureport-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+			<!--日志文件保留天数 -->
+			<MaxHistory>30</MaxHistory>
+			<maxFileSize>10MB</maxFileSize>
+		</rollingPolicy>
+		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n</pattern>
+		</encoder>
+	</appender>
+
+	<!-- 生成 error html格式日志开始 -->
+	<appender name="HTML" class="ch.qos.logback.core.FileAppender">
+		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+			<!--设置日志级别,过滤掉info日志,只输入error日志-->
+			<level>ERROR</level>
+		</filter>
+		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+			<layout class="ch.qos.logback.classic.html.HTMLLayout">
+				<pattern>%p%d%msg%M%F{32}%L</pattern>
+			</layout>
+		</encoder>
+		<file>${LOG_HOME}/error-log.html</file>
+	</appender>
+	<!-- 生成 error html格式日志结束 -->
+
+	<!-- 每天生成一个html格式的日志开始 -->
+	<appender name="FILE_HTML" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+			<!--日志文件输出的文件名 -->
+			<FileNamePattern>${LOG_HOME}/jimureport-%d{yyyy-MM-dd}.%i.html</FileNamePattern>
+			<!--日志文件保留天数 -->
+			<MaxHistory>30</MaxHistory>
+			<MaxFileSize>10MB</MaxFileSize>
+		</rollingPolicy>
+		<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+			<layout class="ch.qos.logback.classic.html.HTMLLayout">
+				<pattern>%p%d%msg%M%F{32}%L</pattern>
+			</layout>
+		</encoder>
+	</appender>
+	<!-- 每天生成一个html格式的日志结束 -->
+
+	<!--myibatis log configure -->
+	<logger name="com.apache.ibatis" level="TRACE" />
+	<logger name="java.sql.Connection" level="DEBUG" />
+	<logger name="java.sql.Statement" level="DEBUG" />
+	<logger name="java.sql.PreparedStatement" level="DEBUG" />
+
+	<!-- 日志输出级别 -->
+	<root level="INFO">
+		<appender-ref ref="STDOUT" />
+		<appender-ref ref="FILE" />
+		<!-- <appender-ref ref="HTML" />
+		<appender-ref ref="FILE_HTML" /> -->
+	</root>
+
+</configuration>

BIN
src/main/resources/static/favicon.ico


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 5 - 0
src/main/resources/static/login/cdn/bootstrap.min.css


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 136 - 0
src/main/resources/static/login/login.html


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است