Authored by 王涛

积木报表

Showing 33 changed files with 2876 additions and 0 deletions
FROM 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
\ No newline at end of file
... ...
This diff could not be displayed because it is too large.
<?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.5.0</version>
<relativePath/>
</parent>
<groupId>org.jeecg</groupId>
<artifactId>JimuReport</artifactId>
<version>1.3</version>
<name>JimuReport</name>
<url>http://www.jimureport.com</url>
<description>积木报表</description>
<repositories>
<repository>
<id>aliyun</id>
<name>aliyun Repository</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jeecg</id>
<name>jeecg Repository</name>
<url>http://maven.jeecg.org/nexus/content/repositories/jeecg</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<java.version>1.8</java.version>
<minio.version>8.0.3</minio.version>
<!-- DB驱动 -->
<mysql-connector-java.version>8.0.20</mysql-connector-java.version>
</properties>
<dependencies>
<!-- JimuReport -->
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-spring-boot-starter</artifactId>
<version>1.3.795</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>
<!-- 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>
<!-- sqlserver-->
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.0</version>
<scope>runtime</scope>
</dependency>
<!-- oracle驱动-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</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.7.2</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>-->
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- baomidou -->
<!--<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
<version>2.7</version>
</dependency>
</dependencies>
<build>
<finalName>jimu-report</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>utf-8</encoding>
<useDefaultDelimiters>true</useDefaultDelimiters>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>woff</nonFilteredFileExtension>
<nonFilteredFileExtension>woff2</nonFilteredFileExtension>
<nonFilteredFileExtension>eot</nonFilteredFileExtension>
<nonFilteredFileExtension>ttf</nonFilteredFileExtension>
<nonFilteredFileExtension>svg</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
... ...
//package org.jeecg.modules;
//
//import lombok.Builder;
//
//import java.io.UnsupportedEncodingException;
//import java.security.MessageDigest;
//import java.security.NoSuchAlgorithmException;
//import java.util.Random;
//
//public class DbSchemaKeyGenerator {
//
// public static void main(String[] args) {
//
// String name = "Your_name";
// try {
// String key = generateKey(name);
// System.out.println("key: " + key);
// } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
// e.printStackTrace();
// }
//
// }
//
//
// private static String generateKey(String name) throws NoSuchAlgorithmException, UnsupportedEncodingException {
// String salt = getSalt();
// String encryptSource = "ax5" + name + "b52w" + salt + "vb3";
// MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
// String hash = formatToHex(localMessageDigest.digest(encryptSource.getBytes("UTF-8")));
// return hash.substring(0, 4) + salt + hash.substring(4);
// }
//
//
// private static String formatToHex(byte[] paramArrayOfByte) {
// StringBuilder localStringBuilder = new StringBuilder();
// for (int m = 0; m < paramArrayOfByte.length; m++) {
// if ((m % 32 == 0) && (m != 0)) {
// localStringBuilder.append("\n");
// }
// String str = Integer.toHexString(paramArrayOfByte[m]);
// if (str.length() < 2) {
// str = "0" + str;
// }
// if (str.length() > 2) {
// str = str.substring(str.length() - 2);
// }
// localStringBuilder.append(str);
// }
// return localStringBuilder.toString();
// }
//
// private static int random(int min, int max) {
// return rand() % (max - min + 1) + min;
// }
//
// private static int rand() {
// return new Random().nextInt(Integer.MAX_VALUE);
// }
//
// private static String getSalt() {
// int r = random(10000, 30000);
// return String.valueOf(r);
// }
//}
//
... ...
package org.jeecg.modules;
import org.jeecg.modules.jmreport.common.util.oConvertUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
/**
* 积木报表独立服务启动类
*/
@SpringBootApplication(scanBasePackages = {"org.jeecg.modules.jmreport"})
@MapperScan({"org.jeecg.modules.jmreport.ext.dao","org.jeecgframework.minidao.**"})
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 = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
System.out.print("\n----------------------------------------------------------\n\t" +
"Application JimuReport Demo is running! Access URL:\n\t" +
"Local: \t\thttp://localhost:" + port + path + "/jmreport/list\n\t" +
"----------------------------------------------------------");
}
}
... ...
package org.jeecg.modules.jmreport.config;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
* 1.自定义获取登录token
* 2.自定义获取登录用户
*/
@Component
public class JimuReportTokenService implements JmReportTokenServiceI {
/**
* 通过请求获取Token
* @param request
* @return
*/
@Override
public String getToken(HttpServletRequest request) {
//return TokenUtils.getTokenByRequest(request);
return "123456";
}
/**
* 通过Token获取登录人用户名
* @param token
* @return
*/
@Override
public String getUsername(String token) {
// return JwtUtil.getUsername(token);
return "admin";
}
/**
* Token校验
* @param token
* @return
*/
@Override
public Boolean verifyToken(String token) {
//return TokenUtils.verifyToken(token, sysBaseAPI, redisUtil);
return true;
}
/**
* 自定义请求头
* @return
*/
@Override
public HttpHeaders customApiHeader() {
HttpHeaders header = new HttpHeaders();
header.add("custom-header1", "Please set a custom value 1");
header.add("token", "token value 2");
return header;
}
}
\ No newline at end of file
... ...
package org.jeecg.modules.jmreport.controller;
import com.alibaba.fastjson.JSON;
import org.jeecg.modules.jmreport.common.util.ViewFreemarker;
import org.jeecg.modules.jmreport.common.util.oConvertUtils;
import org.jeecg.modules.jmreport.config.JmReportBaseConfig;
import org.jeecg.modules.jmreport.desreport.util.d;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* 积木报表-设置默认首页跳转
*/
@Controller
public class IndexController {
private Logger logger = LoggerFactory.getLogger(IndexController.class);
@Autowired
private JmReportBaseConfig jmBaseConfig;
@GetMapping("/")
public String index(Model model) {
model.addAttribute("name", "jimureport");
return "jmreport/list"; // 视图重定向 - 跳转
}
@GetMapping("/page/{pageCode}")
public void page(Model model,HttpServletRequest request, HttpServletResponse response,@PathVariable("pageCode") String pageCode) throws Exception {
model.addAttribute("name", "jimureport");
String template = "jmreport/desreport/page.ftl";
Map<String, Object> paras = new HashMap<>();
paras.put("pageCode",pageCode);
paras.put("base", request.getContextPath());
paras.put("baseURL", d.a(request));
paras.put("customPrePath", oConvertUtils.getString(request.getAttribute("customPrePath"), ""));
paras.put("reportConfig", JSON.toJSONString(this.jmBaseConfig));
ViewFreemarker.view(request, response, template, paras);
}
}
... ...
package org.jeecg.modules.jmreport.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
@RequestMapping(value = "/list", method = RequestMethod.GET)
public void queryPageList(HttpServletRequest req) {
System.out.println("getMaxRows="+jdbcTemplate.getMaxRows());
System.out.println("getCacheLimit="+namedParameterJdbcTemplate.getCacheLimit());
}
}
... ...
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.jeecg.modules.jmreport.desreport.render.a;
import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import org.jeecg.modules.jmreport.common.util.oConvertUtils;
import org.jeecg.modules.jmreport.desreport.model.RenderInfo;
import org.jeecg.modules.jmreport.desreport.model.ReportDbInfo;
import org.jeecg.modules.jmreport.desreport.render.handler.RowsRenderHandler;
import org.jeecg.modules.jmreport.desreport.render.utils.FreeMarkerUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.Map.Entry;
@Component("loopBlockRenderStrategy")
public class a implements RowsRenderHandler {
private static final Logger a = LoggerFactory.getLogger(a.class);
public a() {
}
public boolean support(RenderInfo renderInfo, JSONObject rows) {
return oConvertUtils.isNotEmpty(renderInfo.getLoopBlockList());
}
private String a(JSONObject var1, JSONObject var2, Integer var3, Integer var4) {
Integer var5 = var4 - var3 + 1;
Integer var6 = var1.getInteger("sci");
Integer var7 = var1.getInteger("eci");
Integer var8 = oConvertUtils.getInt(var1.getInteger("loopTime"), 1);
StringBuilder var9 = new StringBuilder();
String var10 = var1.getString("db");
var9.append("{");
var9.append(String.format("<#list list as %s>", var10));
for (int var11 = var3; var11 <= var4; ++var11) {
var9.append(String.format("\"${(%s_index*%s)+%s+%s}\":", var10, var5, var3, var11 - var3));
JSONObject var12 = (JSONObject) var2.get(var11);
JSONObject var13 = new JSONObject(true);
JSONObject var14 = var12.getJSONObject("cells");
if (oConvertUtils.isNotEmpty(var14)) {
JSONObject var15 = new JSONObject(true);
int var16;
JSONObject var17;
for (var16 = var6; var16 <= var7; ++var16) {
if (oConvertUtils.isNotEmpty(var14)) {
var17 = var14.getJSONObject(var16 + "");
var15.put(var16 + "", var17);
}
}
if (var8 > 1) {
for (var16 = 1; var16 <= var8 - 1; ++var16) {
var17 = JSONObject.parseObject(JSONObject.toJSONString(var14), new Feature[]{Feature.OrderedField});
for (int var18 = var6; var18 <= var7; ++var18) {
JSONObject var19 = (JSONObject) var17.get(var18);
String var20 = var19.getString("text");
int var21 = (var7 - var6 + 1) * var16 + var18;
if (oConvertUtils.isNotEmpty(var20) && var20.indexOf("_index") <= -1 && var20.indexOf("${") > -1) {
var19.put("text", var20.replace("}", var16 + "}"));
var15.put(var21 + "", var19);
} else {
var15.put(var21 + "", var19);
}
}
}
}
var13.put("cells", var15);
Object var22 = var12.get("height");
if (oConvertUtils.isNotEmpty(var22)) {
var13.put("height", var22);
}
}
var9.append(JSONUtils.toJSONString(var13));
if (var11 < var4) {
var9.append(",");
}
}
var9.append(String.format("<#if %s_has_next>,</#if>", var10));
var9.append("</#list>");
var9.append("}");
return var9.toString();
}
public JSONObject render(RenderInfo renderInfo, JSONObject rows) {
JSONObject var3 = new JSONObject(true);
Map var4 = renderInfo.getReport().getDataList();
JSONArray var5 = renderInfo.getLoopBlockList();
Integer var6 = 0;
Iterator var7 = var5.iterator();
JSONObject var9;
Integer var10;
Integer var11;
Integer var12;
ReportDbInfo var27;
do {
if (!var7.hasNext()) {
return rows;
}
Object var8 = var7.next();
var9 = (JSONObject) var8;
var10 = var9.getInteger("sri");
var11 = var9.getInteger("eri");
var12 = oConvertUtils.getInt(var9.getInteger("loopTime"), 1);
if (var10 > 0) {
for (int var13 = 0; var13 < var10; ++var13) {
Object var14 = rows.get(var13);
if (oConvertUtils.isNotEmpty(var14)) {
var3.put(var13 + "", var14);
}
}
}
String var26 = var9.getString("db");
var27 = (ReportDbInfo) var4.get(var26);
} while (!oConvertUtils.isNotEmpty(var27));
Object var15 = this.getData(var27);
HashMap var16 = new HashMap(5);
if (oConvertUtils.isNotEmpty(var15) && var15 instanceof List) {
List var17 = (List) var15;
if (var12 > 1) {
int var18 = 0;
ArrayList var19 = new ArrayList();
JSONObject var20 = new JSONObject();
Iterator var21 = var17.iterator();
while (true) {
if (!var21.hasNext()) {
var15 = var19;
break;
}
JSONObject var22 = (JSONObject) var21.next();
if (var18 % var12 == 0) {
var20 = new JSONObject();
var20.put("idx", var18 + 1);
var20.putAll(var22);
var19.add(var20);
} else {
Iterator var23 = var22.entrySet().iterator();
while (var23.hasNext()) {
Entry var24 = (Entry) var23.next();
String var25 = var24.getKey().toString();
var20.put("idx" + var18 % var12, var18 + 1);
var20.put(var25 + var18 % var12, var24.getValue());
}
}
++var18;
}
}
var16.put("list", var15);
}
String var28 = this.a(var9, rows, var10, var11);
String var29 = FreeMarkerUtils.a(var28, var16);
JSONObject var30 = JSONObject.parseObject(var29, new Feature[]{Feature.OrderedField});
Iterator var31 = rows.entrySet().iterator();
while (var31.hasNext()) {
Entry var32 = (Entry) var31.next();
Object var33 = var32.getValue();
if (var33 instanceof JSONObject) {
Integer var34 = Integer.parseInt(var32.getKey().toString());
if (var34 > var11) {
var6 = var30.size() + var10;
var30.put(var6.toString(), var33);
}
}
}
var3.putAll(var30);
return var3;
}
public Object getData(ReportDbInfo reportDbInfo) {
return reportDbInfo.getList();
}
}
... ...
This diff could not be displayed because it is too large.
package org.jeecg.modules.jmreport.ext.Base;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.api.ApiController;
import java.util.List;
public class BaseApiController extends ApiController {
/**
* 请求成功
*
* @param data 数据内容
* @return ignore
*/
@Override
protected <T> BaseR<T> success(T data) {
return BaseR.ok(data);
}
/**
* 请求成功
*
* @param data 数据内容
* @return ignore
*/
protected JSONObject api(List<JSONObject> data) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("data",data);
return jsonObject;
}
}
... ...
package org.jeecg.modules.jmreport.ext.Base;
import com.baomidou.mybatisplus.extension.api.IErrorCode;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import java.io.Serializable;
public class BaseR<T> extends R<T> implements Serializable {
private boolean success;
private T result;
public static <T> BaseR<T> ok(T data) {
ApiErrorCode aec = ApiErrorCode.SUCCESS;
if (data instanceof Boolean && Boolean.FALSE.equals(data)) {
aec = ApiErrorCode.FAILED;
}
BaseR<T> tBaseR = restResult(null, aec);
tBaseR.setSuccess(true);
tBaseR.setCode(200);
tBaseR.setResult(data);
return tBaseR;
}
public static <T> BaseR<T> restResult(T data, IErrorCode errorCode) {
return restResult(data, errorCode.getCode(), errorCode.getMsg());
}
private static <T> BaseR<T> restResult(T data, long code, String msg) {
BaseR<T> apiResult = new BaseR<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
}
... ...
package org.jeecg.modules.jmreport.ext.controller;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.influxdb.dto.QueryResult;
import org.jeecg.modules.jmreport.ext.Base.BaseApiController;
import org.jeecg.modules.jmreport.ext.service.ApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api")
public class APiController extends BaseApiController {
@Autowired
private ApiService apiService;
/**
* 查询树结构
*
* @return
*/
@GetMapping("/test")
public JSONObject getTree(String resid) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("data", StringUtils.isBlank(resid) ? "empty"+System.currentTimeMillis():resid);
return api(Arrays.asList(jsonObject));
}
/**
* 查询树结构
*
* @return
*/
@GetMapping("/cpu/lyratio")
public JSONObject getCpu() {
String sql = "SELECT resId, max AS cpuRateMax, mean AS cpuRateAvg, min AS cpuRateMin FROM monitor.rp_1000d.performance_3d WHERE flag = 'cpu' AND kpiId = 'KPI7054BC34' AND time > NOW() - 2160h GROUP BY resId";
List<Map<String, Object>> maps = apiService.queryInFlux(sql);
JSONObject jsonObject = new JSONObject();
jsonObject.put("data", maps);
return api(Arrays.asList(jsonObject));
}
}
... ...
package org.jeecg.modules.jmreport.ext.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.api.ApiController;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.jmreport.ext.Base.BaseApiController;
import org.jeecg.modules.jmreport.ext.entity.ExtPageConfig;
import org.jeecg.modules.jmreport.ext.service.ExtPageConfigService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;
/**
* (ExtPageConfig)表控制层
*
* @author makejava
* @since 2021-09-14 14:59:33
*/
@RestController
@RequestMapping("/ext/pageconfig")
public class ExtPageConfigController extends BaseApiController {
/**
* 服务对象
*/
@Resource
private ExtPageConfigService extPageConfigService;
/**
* 查询树结构
*
* @return
*/
@GetMapping("/tree")
public R getTree() {
return success(extPageConfigService.getTree());
}
/**
* 保存页面的报表
*
* @return
*/
@GetMapping("/{id}/{code}")
public R save(@PathVariable("id") Integer id,@PathVariable("code") String code) {
if(id != null && StringUtils.isNotBlank(code)){
ExtPageConfig config = new ExtPageConfig();
config.setId(id);
config.setReportCode(code);
return success(extPageConfigService.updateById(config));
}
return failed("保存失败");
}
/**
* 保存页面的报表
*
* @return
*/
@GetMapping("/detail/{pageCode}")
public R save(@PathVariable("pageCode") String pageCode) {
return success(extPageConfigService.getPageDetail(pageCode));
}
/**
* 分页查询所有数据
*
* @param page 分页对象
* @param extPageConfig 查询实体
* @return 所有数据
*/
@GetMapping
public R selectAll(Page<ExtPageConfig> page, ExtPageConfig extPageConfig) {
return success(this.extPageConfigService.page(page, new QueryWrapper<>(extPageConfig)));
}
/**
* 通过主键查询单条数据
*
* @param id 主键
* @return 单条数据
*/
@GetMapping("{id}")
public R selectOne(@PathVariable Serializable id) {
return success(this.extPageConfigService.getById(id));
}
/**
* 新增数据
*
* @param extPageConfig 实体对象
* @return 新增结果
*/
@PostMapping
public R insert(@RequestBody ExtPageConfig extPageConfig) {
return success(this.extPageConfigService.save(extPageConfig));
}
/**
* 修改数据
*
* @param extPageConfig 实体对象
* @return 修改结果
*/
@PutMapping
public R update(@RequestBody ExtPageConfig extPageConfig) {
return success(this.extPageConfigService.updateById(extPageConfig));
}
/**
* 删除数据
*
* @param idList 主键结合
* @return 删除结果
*/
@DeleteMapping
public R delete(@RequestParam("idList") List<Long> idList) {
return success(this.extPageConfigService.removeByIds(idList));
}
}
... ...
package org.jeecg.modules.jmreport.ext.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.jeecg.modules.jmreport.ext.entity.ExtPageConfig;
import org.jeecg.modules.jmreport.ext.pojo.PageTreeNode;
import java.util.List;
/**
* (ExtPageConfig)表数据库访问层
*
* @author makejava
* @since 2021-09-14 14:59:31
*/
public interface ExtPageConfigDao extends BaseMapper<ExtPageConfig> {
}
... ...
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.jeecg.modules.jmreport.ext.dao.ExtPageConfigDao">
</mapper>
... ...
package org.jeecg.modules.jmreport.ext.entity;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import java.io.Serializable;
import java.util.Date;
/**
* (ExtPageConfig)表实体类
*
* @author makejava
* @since 2021-09-14 14:59:28
*/
@SuppressWarnings("serial")
public class ExtPageConfig extends Model<ExtPageConfig> {
private Integer id;
//父级页面
private Integer parentId;
//页面名称
private String pageName;
//页面编码
private String pageCode;
//状态 0启动1停用2删除
private Integer status;
//挂载报表
private String reportCode;
// 排序
private Integer sort;
// 排序
private Date createTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getParentId() {
return parentId;
}
public void setParentId(Integer parentId) {
this.parentId = parentId;
}
public String getPageName() {
return pageName;
}
public void setPageName(String pageName) {
this.pageName = pageName;
}
public String getPageCode() {
return pageCode;
}
public void setPageCode(String pageCode) {
this.pageCode = pageCode;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getReportCode() {
return reportCode;
}
public void setReportCode(String reportCode) {
this.reportCode = reportCode;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 获取主键值
*
* @return 主键值
*/
@Override
protected Serializable pkVal() {
return this.id;
}
}
... ...
package org.jeecg.modules.jmreport.ext.pojo;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
@Builder
public class PageDetail implements Serializable {
public PageDetail() {
}
public PageDetail(String pageName, String pageCode, String reportCode, List<PageDetail> child) {
this.pageName = pageName;
this.pageCode = pageCode;
this.reportCode = reportCode;
this.child = child;
}
//页面名称
private String pageName;
//页面编码
private String pageCode;
//挂载报表
private String reportCode;
private List<PageDetail> child = new ArrayList<>();
}
... ...
package org.jeecg.modules.jmreport.ext.pojo;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Data
public class PageTreeNode implements Serializable {
public PageTreeNode() {
}
public PageTreeNode(Integer id, boolean expand, boolean disabled, String title) {
this.id = id;
this.expand = expand;
this.disabled = disabled;
this.title = title;
}
public PageTreeNode(Integer id,String title) {
this.id = id;
this.title = title;
}
private Integer id;
// 是否打开
private boolean expand = true;
// 是否可点击
private boolean disabled = false;
private String title;
private List<PageTreeNode> children = new ArrayList<>();
private Map<String,String> props = new HashMap<>();
}
... ...
package org.jeecg.modules.jmreport.ext.service;
import java.util.List;
import java.util.Map;
public interface ApiService {
/**
* 查询时序 返回list
*
* @param sql
* @return
*/
List<Map<String, Object>> queryInFlux(String sql);
}
... ...
package org.jeecg.modules.jmreport.ext.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.jmreport.ext.entity.ExtPageConfig;
import org.jeecg.modules.jmreport.ext.pojo.PageDetail;
import org.jeecg.modules.jmreport.ext.pojo.PageTreeNode;
import java.util.List;
/**
* (ExtPageConfig)表服务接口
*
* @author makejava
* @since 2021-09-14 14:59:32
*/
public interface ExtPageConfigService extends IService<ExtPageConfig> {
/**
* 获取树节点信息
* @return
*/
PageTreeNode getTree();
/**
* 获取报表页面详细信息
* @return
*/
PageDetail getPageDetail(String pageCode);
}
... ...
package org.jeecg.modules.jmreport.ext.service;
import org.jeecg.modules.jmreport.common.vo.Result;
public interface SourceExtService {
/**
* 扩展源码中的show接口
*/
void showApiExt(Result result);
}
... ...
package org.jeecg.modules.jmreport.ext.service.impl;
import org.influxdb.dto.QueryResult;
import org.jeecg.modules.jmreport.ext.service.ApiService;
import org.jeecg.modules.jmreport.utils.influx.InfluxDbUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class ApiServiceImpl implements ApiService {
@Autowired
private InfluxDbUtils influxDbUtils;
public List<Map<String, Object>> queryInFlux(String sql) {
QueryResult monitor = influxDbUtils.query(sql, "monitor");
List<Map<String, Object>> maps = influxDbUtils.queryResultToMapList(monitor);
return maps;
}
}
... ...
package org.jeecg.modules.jmreport.ext.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.jmreport.ext.dao.ExtPageConfigDao;
import org.jeecg.modules.jmreport.ext.entity.ExtPageConfig;
import org.jeecg.modules.jmreport.ext.pojo.PageDetail;
import org.jeecg.modules.jmreport.ext.pojo.PageTreeNode;
import org.jeecg.modules.jmreport.ext.service.ExtPageConfigService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* (ExtPageConfig)表服务实现类
*
* @author makejava
* @since 2021-09-14 14:59:32
*/
@Service
public class ExtPageConfigServiceImpl extends ServiceImpl<ExtPageConfigDao, ExtPageConfig> implements ExtPageConfigService {
/**
* 获取树节点信息
*
* @return
*/
@Override
public PageTreeNode getTree() {
PageTreeNode root = new PageTreeNode(-1,"页面配置");
LambdaQueryWrapper<ExtPageConfig> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.orderByAsc(ExtPageConfig::getSort);
List<ExtPageConfig> list = this.list(queryWrapper);
// 获取所有父节点
List<ExtPageConfig> parentList = list.stream().filter(item -> item.getParentId() == null).collect(Collectors.toList());
parentList.stream().forEach(item ->{
PageTreeNode node = new PageTreeNode(item.getId(),item.getPageName());
node.getProps().put("reportCode",item.getReportCode());
getChild(node,list,item);
root.getChildren().add(node);
});
return root;
}
/**
* 获取报表页面详细信息
*
* @param pageCode
* @return
*/
@Override
public PageDetail getPageDetail(String pageCode) {
if(StringUtils.isBlank(pageCode)){
return null;
}
LambdaQueryWrapper<ExtPageConfig> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ExtPageConfig::getPageCode,pageCode);
ExtPageConfig one = this.getOne(queryWrapper);
if(one == null){
return null;
}
PageDetail root = PageDetail.builder()
.pageCode(one.getPageCode())
.pageName(one.getPageName())
.reportCode(one.getReportCode())
.child(new ArrayList<>())
.build();
LambdaQueryWrapper<ExtPageConfig> queryWrapper1 = new LambdaQueryWrapper<>();
queryWrapper1.eq(ExtPageConfig::getParentId,one.getId());
queryWrapper1.orderByAsc(ExtPageConfig::getSort);
List<ExtPageConfig> list = this.list(queryWrapper1);
list.stream().forEach(item ->{
PageDetail child = PageDetail.builder()
.pageCode(item.getPageCode())
.pageName(item.getPageName())
.reportCode(item.getReportCode())
.build();
root.getChild().add(child);
});
return root;
}
private void getChild(PageTreeNode root,List<ExtPageConfig> list,ExtPageConfig pageConfig){
// 获取子节点
List<ExtPageConfig> childList = list.stream().filter(item -> item.getParentId() == root.getId()).collect(Collectors.toList());
if(!childList.isEmpty()){
childList.stream().forEach(item ->{
PageTreeNode node = new PageTreeNode(item.getId(),item.getPageName());
node.getProps().put("reportCode",item.getReportCode());
root.getChildren().add(node);
});
}
}
}
... ...
package org.jeecg.modules.jmreport.ext.service.impl;
import org.jeecg.modules.jmreport.common.vo.Result;
import org.jeecg.modules.jmreport.desreport.entity.JimuReport;
import org.jeecg.modules.jmreport.desreport.model.ReportDbInfo;
import org.jeecg.modules.jmreport.ext.service.SourceExtService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class SourceExtServiceImpl implements SourceExtService {
/**
* 扩展源码中的show接口
*
* @param result
*/
@Override
public void showApiExt(Result result) {
Object obj = result.getResult();
if(obj instanceof JimuReport){
JimuReport jimuReport = (JimuReport)obj;
Map<String, Object> dataList = jimuReport.getDataList();
dataList.forEach((k,v) ->{
// 当前类型 是数据源
if(v instanceof ReportDbInfo){
ReportDbInfo info = (ReportDbInfo)v;
List<Map<String, Object>> list = info.getList();
list.stream().forEach(item ->{
if(item.containsKey("influxcpumin")){
item.put("influxcpumin",System.currentTimeMillis()+"");
}
if(item.containsKey("influxcpumax")){
item.put("influxcpumax",System.currentTimeMillis() +"");
}
});
}
});
Map<String, Object> data = (Map<String, Object>)dataList.get("");
}
}
}
... ...
package org.jeecg.modules.jmreport.utils.influx;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDBFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class InfluxDBConfig {
@Value("${spring.influx.url}")
private String url;
private String database;
private String retentionPolicy;
private InfluxDB influxDB;
public InfluxDBConfig() {
}
public InfluxDBConfig(String userName, String password, String url, String database) {
// this.userName = userName;
// this.password = password;
this.url = url;
this.database = database;
build();
}
public InfluxDBConfig(String database) {
this.database = database;
build();
}
private void build() {
if (influxDB == null) {
//influxDB = InfluxDBFactory.connect(this.url,this.userName,this.password);
influxDB = InfluxDBFactory.connect(this.url);
}
influxDB.setDatabase(this.database);
influxDB.setLogLevel(InfluxDB.LogLevel.BASIC);
}
public InfluxDB getInfluxDB() {
return influxDB;
}
}
... ...
package org.jeecg.modules.jmreport.utils.influx;
import lombok.extern.slf4j.Slf4j;
import org.influxdb.InfluxDB;
import org.influxdb.dto.Point;
import org.influxdb.dto.Query;
import org.influxdb.dto.QueryResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class InfluxDbUtils {
@Autowired
InfluxDBConfig influxDBConfig;
@Autowired
private InfluxDB influxDB;
/**
* 创建数据库
*
* @param dbName
*/
public void createDB(String dbName) {
influxDB.createDatabase(dbName);
}
/**
* 删除数据库
*
* @param dbName
*/
public void deleteDB(String dbName) {
influxDB.deleteDatabase(dbName);
}
/**
* 创建策略
*
* @param command
* @param database
*/
public void createRetentionPolicy(String command, String defalut, String database, String policy, int fb) {
command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT", defalut, database, policy, fb);
query(command, database);
}
/**
* 删除策略
*
* @param command
* @param database
*/
public void removeRetentionPolicy(String command, String defalut, String database, String policy, int fb) {
}
/**
* 创建表
*
* @param command 删除语句
* @return 返回错误信息
*/
public void createMeasurementData(String command, String database) {
}
/**
* 删除表
*
* @param command 删除语句
* @return 返回错误信息
*/
public String deleteMeasurementData(String command, String database) {
QueryResult result = influxDB.query(new Query(command, database));
return result.getError();
}
/**
* 查询
*
* @param command 查询语句
* @return
*/
public QueryResult query(String command, String database) {
return influxDB.query(new Query(command, database));
}
// public void insert(String measurements, Map<String, String> tagsMap, Map<String, Object> fieldsMap) {
// influxDBConfig.getInfluxDB();
// influxDB.insert(measurements, tagsMap, fieldsMap);
// }
/**
* 新增
*
* @param dateabse
* @param measurements
* @param tagsMap
* @param fieldsMap
*/
public void insert(String dateabse, String measurements, Map<String, String> tagsMap, Map<String, Double> fieldsMap) {
Point.Builder builder = Point.measurement(measurements);
//builder.time(System.currentTimeMillis(),TimeUnit.MICROSECONDS);
builder.addField("kpiValue", fieldsMap.get("kpiValue"));
//builder.tag("resType", tagsMap.get("resType"));
builder.tag("resId", tagsMap.get("resId"));
builder.tag("kpiId", tagsMap.get("kpiId"));
builder.tag("flag", tagsMap.get("flag"));
//builder.tag("ipAdde", tagsMap.get("ipAdde"));
Point point = builder.build();
influxDB.setDatabase(dateabse).write(point);
}
/**
* 将queryResult 查询结果转换为 map
*
* @param queryResult 查询结果
* @return List<Map < String , Object>>
* @author 惠佳旭
* @date 2020/12/17
*/
public List<Map<String, Object>> queryResultToMapList(QueryResult queryResult) {
List<Map<String, Object>> resultList = new LinkedList<>();
for (QueryResult.Result result : queryResult.getResults()) {
if (result == null || result.getSeries() == null) {
break;
}
for (QueryResult.Series series : result.getSeries()) {
if (series == null || series.getValues() == null) {
break;
}
List<String> columns = series.getColumns();
for (List<Object> value : series.getValues()) {
if (value == null) {
break;
}
Map<String, Object> map = new HashMap<>(columns.size());
for (int i = 0; i < value.size(); i++) {
String columnName = columns.get(i);
if ("time".equals(columnName)) {
try {
String timeStr = value.get(i).toString();
map.put(columnName, timeStr.substring(0, 10) + " " + timeStr.substring(11, 19));
} catch (Exception e) {
log.error("转换失败:{}转换为日期失败", value.get(i));
map.put(columnName, value.get(i));
}
} else {
map.put(columnName, value.get(i));
}
}
resultList.add(map);
}
}
}
return resultList;
}
public List<Map<String, Object>> queryResultToMap(QueryResult queryResult, String dateFormat) {
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
List<Map<String, Object>> resultList = new LinkedList<>();
for (QueryResult.Result result : queryResult.getResults()) {
if (result == null || result.getSeries() == null) {
break;
}
for (QueryResult.Series series : result.getSeries()) {
if (series == null || series.getValues() == null) {
break;
}
List<String> columns = series.getColumns();
for (List<Object> value : series.getValues()) {
if (value == null) {
break;
}
Map<String, Object> map = new HashMap<>(columns.size());
for (int i = 0; i < value.size(); i++) {
String columnName = columns.get(i);
if ("time".equals(columnName)) {
try {
map.put(columnName, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(sdf.parse(value.get(i).toString())));
} catch (Exception e) {
log.error("转换失败:{}转换为日期失败", value.get(i));
map.put(columnName, value.get(i));
}
} else {
map.put(columnName, value.get(i));
}
}
resultList.add(map);
}
}
}
return resultList;
}
}
... ...
server:
port: 8085
spring:
#配置静态资源
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/
#配置数据库
datasource:
url: jdbc:mysql://${MYSQL-HOST:192.168.0.249}:${MYSQL-PORT:3306}/${MYSQL-DB:jreport}?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#Minidao配置
minidao :
base-package: org.jeecg.modules.jmreport.*
#JimuReport[上传配置]
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: ??
#输出sql日志
logging:
level:
org.jeecg.modules.jmreport : info
... ...
server:
port: 8085
spring:
#配置静态资源
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/
#配置数据库
datasource:
url: jdbc:mysql://69.12.93.116:3306/jreport?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#Minidao配置
minidao :
base-package: org.jeecg.modules.jmreport.*
#JimuReport[上传配置]
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: ??
#输出sql日志
logging:
level:
org.jeecg.modules.jmreport : info
... ...
server:
port: 8085
spring:
#配置静态资源
mvc:
static-path-pattern: /**
resource:
static-locations: classpath:/static/
#配置数据库
datasource:
url: jdbc:mysql://${MYSQL-HOST:127.0.0.1}:${MYSQL-PORT:3306}/${MYSQL-DB:jreport}?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true
username: yx
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
profiles:
active: tjserver
influx:
url: http://192.168.0.244:8086
database: monitor
retention_policy: default
retention_policy_time: 7d
#mybatis
mybatis-plus:
mapper-locations: classpath*:org/jeecg/modules/jmreport/**/dao/*.xml
#Minidao配置
minidao :
base-package: org.jeecg.modules.jmreport.*
#JimuReport[上传配置]
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: ??
#输出sql日志
logging:
level:
org.jeecg.modules.jmreport : info
... ...
<#assign CACHE_VERSION = "v=1.0.38">
<!DOCTYPE html>
<html>
<head>
<script>
let base = "${base}";
let baseFull = "${base}" + "${customPrePath}";
/**
* 获取url参数
*/
function getRequestUrl() {
var url = location.search;
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
}
}
return theRequest;
}
let token = getRequestUrl().token;
if (token == "" || token == null) {
token = window.localStorage.getItem('JmReport-Access-Token');
}
window.localStorage.setItem('JmReport-Access-Token', token);
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>在线设计</title>
<#include "./common/resource.ftl">
<link rel="stylesheet" href="${base}${customPrePath}/jmreport/desreport_/corelib/cust.css?${CACHE_VERSION}">
<link rel="shortcut icon" href="${base}${customPrePath}/jmreport/desreport_/corelib/logo.png?${CACHE_VERSION}"
type="image/x-ico">
</head>
<body style="background: #ffffff">
<style>
.ivu-page,
.ivu-page-prev,
.ivu-page-next,
.ivu-select-selection,
.ivu-select-dropdown,
.ivu-page.mini .ivu-page-options-elevator input {
background-color: #ffffff;
color: #515a6e;
}
.page {
display: flex;
justify-content: center;
-webkit-box-pack: center;
}
.ivu-page-item {
background-color: #ffffff;
border: 1px solid rgba(131, 125, 125, 0.5);
}
.ivu-page-item-active {
background-color: white;
border: 1px solid #409eff;
}
.ivu-page-item a {
margin: 0 6px;
text-decoration: none;
color: #515a6e;
}
.ivu-page-next a, .ivu-page-prev a {
font-size: 14px;
color: #515a6e;
}
.ivu-spin-fix {
background-color: rgba(131, 125, 125, 0.5);
}
</style>
<style>
.title {
font-size: 20px;
color: #000000;
text-align: center;
line-height: 60px;
font-weight: 500;
}
.ivu-layout-sider {
transition: all .2s ease-in-out;
position: relative;
background: #ffffff;
}
.ivu-layout {
display: flex;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
flex-direction: column;
-webkit-box-flex: 1;
flex: auto;
background: #ffffff;
}
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-opened .ivu-menu-submenu-title {
background: #ffffff;
}
.ivu-menu-dark.ivu-menu-vertical .ivu-menu-opened {
background: #ffffff;
}
.ivu-upload-list {
display: none;
}
.ivu-table-tip table tbody tr td {
background-color: ffffff;
color: #000000;
}
.ivu-select-dropdown-list .ivu-select-item-focus {
background: none !important;
}
</style>
<!--引入自定义组件-->
<#include "./template/list.ftl">
<div id="app" style="padding-left: 30px">
<div class="layout" style="margin-left: -30px;margin-top: -10px;">
<div style="background-color: #1890FF;height: 47px">
<span class="aui-logo"></span>
<span class="jimu-header">报表工作台 </span>
</div>
<Layout>
<Sider breakpoint="md" collapsible :collapsed-width="78" v-model="isCollapsed">
<i-menu theme="primary" width="auto" :class="menuitemClasses" active-name="datainfo"
:open-names="['sub']" @on-select="onMenuSelect">
<Submenu name="sub">
<template slot="title">
<Icon type="ios-apps"/>
</Icon>
报表管理
</template>
<Menu-Item name="datainfo">
<Icon type="md-list"/>
</Icon>
<span>数据报表</span>
</Menu-Item>
<Menu-Item name="chartinfo">
<Icon type="md-images"></Icon>
<span>图形报表</span>
</Menu-Item>
<Menu-Item name="printinfo">
<Icon type="md-print"></Icon>
<span>打印设计</span>
</Menu-Item>
<Menu-Item name="setting">
<Icon type="md-settings"></Icon>
<span>报表设置</span>
</Menu-Item>
</Submenu>
</i-menu>
<div slot="trigger"></div>
</Sider>
<Tabs value="name1" style="width: 100%" @on-click="tabsClick">
<tab-pane icon="md-desktop" label="报表设计" name="name1" class="jimu-tab">
<div style="display: flex;justify-content:space-between;margin-left:16px;margin-right: 38px;">
<div>
<i-input size="small" v-model="name" @keyup.enter.native="enterSearchClick"
placeholder="回车搜索报表名称"></i-input>
</div>
<div class="page">
<Page :total="page.total"
show-total
show-elevator
:page-size="page.size"
show-sizer
@on-change="handleCurrentChange"
@on-page-size-change="handleSizeChange"
size="small">
</Page>
</div>
<div>
<i-select
transfer="true"
v-model="previewModel"
size="small"
style="width: 78px;text-align: center;">
<i-option value="view" style="font-size: 10px">视图</i-option>
<i-option value="list" style="font-size: 10px">列表</i-option>
</i-select>
</div>
</div>
<div style="display: flex;flex-wrap: wrap;" v-if="previewModel =='view'">
<div class="excel-view-item excel-list-add">
<a @click="createExcel">
<i class="ivu-icon ivu-icon-md-add" style="font-size:20px; padding-bottom: 5px;"></i>
<p style="letter-spacing: 2px;font-size: 14px;">新建报表</p>
</a>
</div>
<!-- 循环开始 &ndash;&gt;-->
<div
v-for="(item,index) in dataSource"
:key="index"
class="excel-view-item"
@mouseover="item.editable=true"
@mouseout="item.editable=false">
<!-- 缩略图 &ndash;&gt;-->
<div class="thumb">
<img :src="getThumbSrc(item)"/>
<div class="excel-edit-container" v-show="item.editable">
<a :href="getExcelEditUrl(item)" target="_blank">
设计
</a>
</div>
</div>
<!-- 底部 &ndash;&gt;-->
<div class="item-footer">
<span class="item-name">{{ item.name }}</span>
<div>
<a class="opt-show" :href="getExcelViewUrl(item)" target="_blank">
<Tooltip content="预览模板" placement="top">
<i class="ivu-icon ivu-icon-ios-eye-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-show" v-show="userMessage" @click="setTemplate(item,1)">
<Tooltip content="收藏模板" placement="top">
<i class="ivu-icon ivu-icon-ios-star-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-show" @click="handleDelete(item)">
<Tooltip content="删除模板" placement="top">
<i class="ivu-icon ivu-icon-ios-trash" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-show" @click="handleCopy(item)">
<Tooltip content="复制模板" placement="top">
<i class="ivu-icon ivu-icon-ios-browsers" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-show" @click="handleShare(item.id)">
<Tooltip content="分享" placement="top">
<i class="ivu-icon ivu-icon-ios-share-alt" style="font-size: 16px"></i>
</Tooltip>
</a>
</div>
</div>
</div>
<!-- 循环结束 &ndash;&gt;-->
</div>
<div v-else style="padding: 10px 10px">
<i-button type="primary" @click="createExcel" size="small"
style="margin-left: 6px;width:78px;font-size: 10px">
新建报表
</i-button>
<i-table size="small" style="margin-top: 10px" border :columns="listColumns" :data="dataSource">
<template slot-scope="{ row, index }" slot="action">
<a class="opt-list-show" :href="getExcelViewUrl(row)" target="_blank">
<Tooltip transfer="true" content="预览模板" placement="top">
<i class="ivu-icon ivu-icon-ios-eye-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" :href="getExcelEditUrl(row)" target="_blank">
<Tooltip transfer="true" content="编辑" placement="top">
<i class="ivu-icon ivu-icon-md-create" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" v-show="userMessage" @click="setTemplate(row,1)">
<Tooltip transfer="true" content="收藏模板" placement="top">
<i class="ivu-icon ivu-icon-ios-star-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" @click="handleDelete(row)">
<Tooltip transfer="true" content="删除模板" placement="top">
<i class="ivu-icon ivu-icon-ios-trash" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" @click="handleCopy(row)">
<Tooltip transfer="true" content="复制模板" placement="top">
<i class="ivu-icon ivu-icon-ios-browsers" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" @click="handleShare(row.id)">
<Tooltip transfer="true" content="分享" placement="top">
<i class="ivu-icon ivu-icon-ios-share-alt" style="font-size: 16px"></i>
</Tooltip>
</a>
</template>
</i-table>
</div>
</tab-pane>
<tab-pane icon="md-options" label="模板案例" name="name2" class="jimu-tab">
<div style="display: flex;justify-content:space-between;margin-left:16px;margin-right: 38px">
<div>
<i-input size="small" v-model="name" @keyup.enter.native="loadData"
placeholder="回车搜索报表名称"></i-input>
</div>
<div class="page">
<Page :total="page.total"
show-total
show-elevator
:page-size="page.size"
show-sizer
@on-change="handleCurrentChange"
@on-page-size-change="handleSizeChange"
size="small">
</Page>
</div>
<div>
<i-select
transfer="true"
v-model="previewModel"
size="small"
style="width: 78px;text-align: center;">
<i-option value="view" style="font-size: 10px">视图</i-option>
<i-option value="list" style="font-size: 10px">列表</i-option>
</i-select>
</div>
</div>
<div style="display: flex;flex-wrap: wrap;" v-if="previewModel =='view'">
<!-- 循环开始 &ndash;&gt;-->
<div
v-for="(item,index) in dataSource"
:key="index"
class="excel-view-item"
@mouseover="item.editable=true"
@mouseout="item.editable=false">
<!-- 缩略图 &ndash;&gt;-->
<div class="thumb">
<img :src="getThumbSrc(item)"/>
<div class="excel-edit-container" v-show="item.editable">
<a v-show="userMessage" :href="getExcelEditUrl(item)" target="_blank">
设计
</a>
</div>
</div>
<!-- 底部 &ndash;&gt;-->
<div class="item-footer">
<span class="item-name">{{ item.name }}</span>
<div style="margin-left: 14%;">
<a class="opt-show" :href="getExcelViewUrl(item)" target="_blank">
<Tooltip content="预览模板" placement="top">
<i class="ivu-icon ivu-icon-ios-eye-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-show" v-show="userMessage" @click="setTemplate(item,0)">
<Tooltip content="取消收藏" placement="top">
<i class="ivu-icon ivu-icon-ios-star" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-show" @click="handleCopy(item)">
<Tooltip content="复制模板" placement="top">
<i class="ivu-icon ivu-icon-ios-browsers" style="font-size: 16px"></i>
</Tooltip>
</a>
</div>
<div v-show="userMessage">
<Upload
:headers="uploadHeader"
:before-upload="handleUpload"
:data="{'id':item.id}"
:action="actionUrl"
:format="['jpg','jpeg','png']"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:on-success="handleSuccess">
<Tooltip content="上传封面" placement="top-end">
<i class="ivu-icon ivu-icon-md-image" style="font-size: 16px"></i>
</Tooltip>
</Upload>
</div>
</div>
</div>
<!-- 循环结束 &ndash;&gt;-->
</div>
<div v-else style="padding: 10px 10px">
<i-button type="primary" @click="createExcel"
style="margin-left: 6px;width:78px;font-size: 10px" size="small">
新建报表
</i-button>
<i-table size="small" style="margin-top: 10px" border :columns="listColumns" :data="dataSource">
<template slot-scope="{ row, index }" slot="action">
<a class="opt-list-show" :href="getExcelEditUrl(row)" target="_blank">
<Tooltip transfer="true" content="编辑" placement="top">
<i class="ivu-icon ivu-icon-md-create" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" :href="getExcelViewUrl(row)" target="_blank">
<Tooltip transfer="true" content="预览模板" placement="top">
<i class="ivu-icon ivu-icon-ios-eye-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" v-show="userMessage" @click="setTemplate(row,0)">
<Tooltip transfer="true" content="取消收藏" placement="top">
<i class="ivu-icon ivu-icon-ios-star" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" @click="handleCopy(row)">
<Tooltip transfer="true" content="复制模板" placement="top">
<i class="ivu-icon ivu-icon-ios-browsers" style="font-size: 16px"></i>
</Tooltip>
</a>
</template>
</i-table>
</div>
</tab-pane>
</Tabs>
</Layout>
</div>
<#--分享弹窗-->
<j-jurisdiction ref="jurisdiction"></j-jurisdiction>
<#--报表设置-->
<Modal v-model="visibleSetting"
:styles="{top: '20px',width:'80%'}"
title="报表设置"
@on-cancel="visibleSetting = false">
<div style="display: flex;flex-direction: row">
<div style="width: 200px">
<Tree ref="tree" :data="treeData" @on-select-change="onTreeChange"></Tree>
</div>
<div style="width: calc(100% - 200px)">
<div style="text-align: right;padding-right: 12px">
<i-button type="primary" @click="savePageConfig"
style="margin-left: 6px;width:78px;font-size: 10px" size="small">
保存配置
</i-button>
</div>
<i-table ref="treeTable" size="small" style="margin-top: 10px" border :columns="treeTableColumns" :data="dataSource">
<template slot-scope="{ row, index }" slot="action">
<a class="opt-list-show" :href="getExcelViewUrl(row)" target="_blank">
<Tooltip transfer="true" content="预览模板" placement="top">
<i class="ivu-icon ivu-icon-ios-eye-outline" style="font-size: 16px"></i>
</Tooltip>
</a>
<a class="opt-list-show" @click="handleShare(row.id)">
<Tooltip transfer="true" content="分享" placement="top">
<i class="ivu-icon ivu-icon-ios-share-alt" style="font-size: 16px"></i>
</Tooltip>
</a>
</template>
</i-table>
</div>
</div>
<div slot="footer">
</div>
</Modal>
</div>
<script>
var BASE_URL = "${base}" + "${customPrePath}";
var currentPage = new Vue({
el: '#app',
data: {
isCollapsed: false,
token: '',//token
name: '',
designerObj: {},
loading: true,
showEdit: false,
dataSource: [],
modalTitle: "",
page: { //分页参数
page: 1,
size: 10,
total: 0,
},
changecode: "",
changename: "",
menuitem: "datainfo",
tabpan: "name1",
userMessage: false,
file: null,
uploadHeader: {},
actionUrl: "",
previewModel: "view",//浏览方式
listColumns: [
<#--{-->
<#-- title: '背景图',-->
<#-- align: 'center',-->
<#-- key: 'thumb',-->
<#-- width: 150,-->
<#-- className: 'table-background',-->
<#-- render: (h, params) => {-->
<#-- let _img = ""-->
<#-- if(!params.row.thumb){-->
<#-- _img = "${base}"+"${customPrePath}"+"/jmreport/desreport_/corelib/jiade.jpg"-->
<#-- }else{-->
<#-- if(params.row.thumb.indexOf('http')==0){-->
<#-- _img = params.row.thumb-->
<#-- }else{-->
<#-- _img = "${base}"+"${customPrePath}"+"/jmreport/img/"+params.row.thumb-->
<#-- }-->
<#-- }-->
<#-- if(_img){-->
<#-- return h('img', {-->
<#-- attrs: {-->
<#-- src: _img,-->
<#-- style: 'width: 100px;height: 39px;vertical-align: middle;'-->
<#-- },-->
<#-- })-->
<#-- }else{-->
<#-- return h("span", '');-->
<#-- }-->
<#-- }-->
<#--},-->
{
title: '报表名称',
key: 'name',
align: 'left',
className: 'table-background'
},
{
title: '操作',
width: 240,
align: 'center',
slot: 'action',
className: 'table-background',
fixed: 'right'
}
],//列表的列
// 显示设置
visibleSetting: false,
treeNode:{},
treeData: [],
treeTableColumns: [
{
type: 'selection',
width: 60,
align: 'center'
},
{
title: '报表名称',
key: 'name',
align: 'left',
className: 'table-background'
},
{
title: '报表编码',
key: 'code',
align: 'left',
className: 'table-background'
},
{
title: '创建时间',
key: 'createTime',
align: 'left',
className: 'table-background'
},
{
title: '操作',
width: 120,
align: 'center',
slot: 'action',
className: 'table-background',
fixed: 'right'
}
]
},
computed: {
menuitemClasses: function () {
return [
'menu-item',
this.isCollapsed ? 'collapsed-menu' : ''
]
}
},
mounted: function () {
this.token = token;
console.log("list_mount--------------", this.token);
this.uploadHeader = {"X-Access-Token": this.token};
this.actionUrl = BASE_URL + "/jmreport/putFile";
this.$nextTick(() => {
this.dataSource = [];
this.userInfo();
});
},
methods: {
handleSizeChange(val) {
this.page.size = val;
this.loadData();
},
handleCurrentChange(val) {
this.page.page = val;
this.loadData();
},
show: function () {
},
//查询用户信息并加载数据
userInfo: function () {
var that = this;
$http.get({
url: api.userInfo,
data: {
token: that.token
},
success: (result) => {
if (result.message != null && result.message != "") {
if (result.message === "admin") {
that.userMessage = true;
}
}
that.$nextTick(() => {
that.loadData();
});
},
error: (err) => {
that.handleSpinHide();
}
}, that)
},
//加载数据
loadData: function (name) {
var that = this;
if (name != null && name != "") {
that.tabpan = name;
that.page = {page: 1, size: 10, total: 0,};
}
var url = "";
that.dataSource = [];
if (that.tabpan == "name1") {
url = api.excelQuery
} else {
url = api.excelQueryByTemplate
}
$http.get({
url: url,
data: {
pageNo: that.page.page,
pageSize: that.page.size,
reportType: that.menuitem,
name: that.name,
token: that.token
},
success: (result) => {
var ls = result.records;
that.page.total = result.total
if (ls && ls.length > 0) {
for (var i = 0; i < ls.length; i++) {
//预览时设置报表打印宽度
let jsonStr = ls[i].jsonStr;
let width;
if (jsonStr) {
jsonStr = JSON.parse(jsonStr);
width = jsonStr.printElWidth || jsonStr.dataRectWidth || 800;
ls[i].printWidth = width;
}
ls[i].editable = false;
}
that.$nextTick(() => {
that.dataSource = JSON.parse(JSON.stringify(ls));
});
}
},
error: (err) => {
that.handleSpinHide();
}
}, that)
},
//新建报表
createExcel: function () {
var that = this;
$http.post({
url: api.saveReport,
data: {},
contentType: 'json',
success: (result) => {
window.open(api.index + result.id + "?token=" + this.token + "&menuType=" + this.menuitem);
}
}, that)
},
//未使用
handleEditConfig: function (item) {
window.location.href = api.index + item.id + "?token=" + this.token;
},
//删除报表
handleDelete: function (item) {
$http.confirm({
title: '删除报表',
content: '是否确认删除?',
url: api.deleteReport,
data: {
id: item.id,
token: this.token
},
success: (result) => {
this.loadData();
}
}, this);
},
//复制模版
handleCopy: function (item) {
$http.confirm({
title: '复制报表',
content: '是否确认复制?',
url: api.reportCopy,
method: 'get',
data: {
id: item.id,
token: this.token
},
success: (result) => {
this.loadData();
}
}, this);
},
handlerViewExcel: function (item) {
console.log(item)
},
getExcelEditUrl: function (item) {
return api.index + item.id + "?token=" + this.token;
},
getExcelViewUrl: function (item) {
return api.view + item.id + "?token=" + this.token;
},
getLabelText1: function (createElement) {
return createElement('div',
{
style: {color: '#fff'}
},
[
createElement('Icon', {props: {type: 'ios-checkmark'}}),
'模板库'
]
)
},
onMenuSelect: function (name) {
if (name == 'setting') {
this.loadTree();
this.visibleSetting = true;
return;
}
this.menuitem = name;
this.page = {page: 1, size: 10, total: 0,};
this.dataSource = [];
this.name = ""
this.loadData();
},
//报表设计和模板案例点击事件
tabsClick(name) {
this.name = ""
this.loadData(name)
},
//回车搜索事件
enterSearchClick() {
this.loadData()
},
//设置取消模版
setTemplate: function (item, arg) {
var content = (arg == 1) ? '是否确认设置为模板?' : '是否确认取消模板?';
let title = (arg == 1) ? '收藏报表' : '取消收藏报表'
$http.confirm({
title: title,
content: content,
url: api.setTemplate,
method: 'get',
data: {
id: item.id,
template: arg,
token: this.token
},
success: (result) => {
this.loadData();
}
}, this);
},
handleUpload(file) {
this.file = file;
return true;
},
handleFormatError(file) {
this.$Notice.warning({
title: '文件格式不正确',
desc: '文件 ' + file.name + ' 格式不正确,请上传 jpg 或 png 格式的图片。'
});
},
handleMaxSize(file) {
this.$Notice.warning({
title: '超出文件大小限制',
desc: '文件 ' + file.name + ' 太大,不能超过 2M。'
});
},
handleSuccess(res) {
if (res != null) {
this.$Message.success(res.message);
this.dataSource.forEach((item, index, array) => {
if (item.id === res.result.id) {
item.thumb = res.result.thumb;
}
})
}
},
handleSpinHide() {
/* setTimeout(() => {
this.$Spin.hide();
}, 3000);*/
},
//分享按钮点击事件
handleShare(id) {
$http.get({
url: api.queryJurisdiction,
data: {reportId: id},
success: (result) => {
if (result) {
if (result.status == '0') {
let protocol = window.location.protocol;
let host = window.location.host;
let url = protocol + "//" + host + base;
result.previewUrl = url + result.previewUrl;
this.$refs.jurisdiction.jurisdictionData = result;
this.$refs.jurisdiction.shareUrlModal = true
} else {
this.$refs.jurisdiction.jurisdictionData = result;
this.$refs.jurisdiction.shareModal = true
}
} else {
this.$refs.jurisdiction.jurisdictionData.reportId = id
this.$refs.jurisdiction.shareModal = true
}
}
})
},
// 获取缩略图的预览地址
getThumbSrc(item) {
if (!item.thumb) {
return "${base}" + "${customPrePath}" + "/jmreport/desreport_/corelib/jiade.jpg"
} else {
if (item.thumb.indexOf('http') == 0) {
return item.thumb
} else {
return "${base}" + "${customPrePath}" + "/jmreport/img/" + item.thumb
}
}
},
loadTree() {
let that = this;
//console.log("BASE_URL", window.location.origin);
$http.get({
url: window.location.origin + "/ext/pageconfig/tree",
data: {
token: that.token
},
success: (result) => {
let arr = [];
arr.push(result);
that.treeData = arr;
},
error: (err) => {
that.handleSpinHide();
}
}, that)
},
onTreeChange(arr) {
let that = this;
let reportCode = '';
if(arr && arr[0] && arr[0].props){
reportCode = arr[0].props.reportCode;
}
that.dataSource.forEach(function (e,i) {
if(e.id == reportCode){
that.$refs.treeTable.toggleSelect(i);
} else {
that.$refs.treeTable.$refs.tbody.objData[i]._isChecked = false
}
});
that.treeNode = arr[0];
},
savePageConfig(){
var that = this;
let id = this.treeNode.id
let code = that.$refs.treeTable.getSelection()[0].id;
$http.get({
url: window.location.origin + '/ext/pageconfig/' + id + '/' + code,
data: {},
contentType: 'json',
success: (result) => {
that.$Message.success('保存成功!');
}
}, that)
}
}
})
</script>
<#include "./common/tj.ftl">
</body>
</html>
... ...
<#assign CACHE_VERSION = "v=1.0.38">
<!DOCTYPE html>
<html>
<head>
<script>
let base = "${base}";
let baseFull = "${base}" + "${customPrePath}";
let pageCode = "${pageCode}";
/**
* 获取url参数
*/
function getRequestUrl() {
var url = location.search;
var theRequest = new Object();
if (url.indexOf("?") != -1) {
var str = url.substr(1);
strs = str.split("&");
for (var i = 0; i < strs.length; i++) {
theRequest[strs[i].split("=")[0]] = decodeURI(strs[i].split("=")[1]);
}
}
return theRequest;
}
let token = getRequestUrl().token;
if (token == "" || token == null) {
token = window.localStorage.getItem('JmReport-Access-Token');
}
window.localStorage.setItem('JmReport-Access-Token', token);
</script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>在线设计</title>
<#include "./common/resource.ftl">
<link rel="stylesheet" href="${base}${customPrePath}/jmreport/desreport_/corelib/cust.css?${CACHE_VERSION}">
<link rel="shortcut icon" href="${base}${customPrePath}/jmreport/desreport_/corelib/logo.png?${CACHE_VERSION}"
type="image/x-ico">
</head>
<body style="background: #ffffff">
<style>
</style>
<!--引入自定义组件-->
<div id="app" style="padding-left: 30px;height: 100%">
<div class="layout" style="margin-left: -30px;margin-top: -10px;;height: 100%;display: flex">
<div v-if="dataSource.child && dataSource.child.length > 0" style="width: 200px;height: 100%">
<Sider breakpoint="md" collapsible :collapsed-width="78" v-model="isCollapsed">
<i-menu theme="primary" width="auto" :class="menuitemClasses" active-name="datainfo"
:open-names="['sub']" @on-select="onMenuSelect">
<Submenu name="sub">
<template slot="title">
<Icon type="ios-apps"/>
</Icon>
{{dataSource.pageName}}
</template>
<Menu-Item :name="item.pageCode" v-for="(item,index) in dataSource.child">
<span>{{item.pageName}}</span>
</Menu-Item>
</Submenu>
</i-menu>
<div slot="trigger"></div>
</Sider>
</div>
<div v-if="dataSource.child && dataSource.child.length > 0" style="width: calc(100% - 200px);height: 100%">
<iframe id="reportFrame" frameborder="0" width="100%" :height="height" :src="src" style="border: none;padding-top: 15px;"></iframe>
</div>
<div v-else>
<iframe id="reportFrame" frameborder="0" width="100%" :height="height" :src="src" style="border: none;padding-top: 15px;"></iframe>
</div>
</div>
</div>
<script>
var BASE_URL = "${base}" + "${customPrePath}";
var currentPage = new Vue({
el: '#app',
data: {
isCollapsed: false,
token: '',//token
src:'',
height:document.documentElement.clientHeight,
dataSource: {},
},
computed: {
menuitemClasses: function () {
return [
'menu-item',
this.isCollapsed ? 'collapsed-menu' : ''
]
}
},
mounted: function () {
this.token = token;
this.$nextTick(() => {
this.loadData();
});
const reportFrame = document.getElementById('reportFrame');
const deviceHeight = document.documentElement.clientHeight;
reportFrame.style.height = Number(deviceHeight) + 'px'; //数字是页面布局高度差
},
methods: {
//加载数据
loadData: function () {
console.log(pageCode);
let that = this;
$http.get({
url: window.location.origin + "/ext/pageconfig/detail/" + pageCode,
data: {
token: that.token
},
success: (result) => {
that.dataSource = result;
let flg = false;
if (result.reportCode) {
that.setReportSrc(result.reportCode);
} else {
if (result.child) {
result.child.forEach(function (d) {
if (d.reportCode && !flg) {
flg = true;
that.setReportSrc(d.reportCode);
}
})
}
}
},
error: (err) => {
}
}, that)
},
setReportSrc(code) {
//const reportFrame = document.getElementById('reportFrame');
//reportFrame.src = "/jmreport/view/" + code ;//+ "?token=" + that.token;
this.src = window.location.origin + "/jmreport/view/" + code ;
},
onMenuSelect: function (key) {
let that = this;
let ds = this.dataSource;
if (ds.pageCode == key) {
let code = ds.reportCode;
if (code) {
that.setReportSrc(code);
}
} else {
if (ds.child) {
let flg = false;
ds.child.forEach(function (d) {
if (d.reportCode && d.pageCode == key && !flg) {
flg = true;
that.setReportSrc(d.reportCode);
}
})
}
}
console.log(key);
}
}
})
</script>
<#include "./common/tj.ftl">
</body>
</html>
... ...