upgrade(jimu): 1.8.1 ,避免 CVE

This commit is contained in:
冷冷 committed 2024-11-26 21:14:35 +08:00
1 parent 536be6fb15
commit 062034a3a3
8 files changed
+2735 -1742

No files matched your search

+1 -1
View File
@@ -5,7 +5,7 @@ pigX 并非一个开源软件,作者保留全部的权利。
## 商业使用
- [商用请购买商业授权](https://pig4cloud.com)
- [使用对应的专属版本](https://pigx.vip/#/buy/form3)
- [使用对应的专属版本](https://pig4cloud.com/data/other/form3.html)
### 🚫禁止
+2626 -815
View File
File diff suppressed because it is too large. Load diff
+8 -1
View File
@@ -54,10 +54,17 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<!-- 积木报表核心依赖-->
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-spring-boot3-starter</artifactId>
<artifactId>jimureport-spring-boot3-starter-fastjson2</artifactId>
<version>${jimu.version}</version>
<exclusions>
<exclusion>
<artifactId>html2image</artifactId>
<groupId>gui.ava</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- druid 连接池 -->
<dependency>
@@ -0,0 +1,91 @@
package com.pig4cloud.pigx.bi.config;
import cn.hutool.core.io.IoUtil;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpServletResponseWrapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.CharArrayWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
/**
* @author lengleng
* @date 2024/11/26
* <p>
* 删除 积木报表的 header 避免 iframe 嵌套 , 造成页面显示异常
*/
@Component
public class HtmlEnhanceFilter extends OncePerRequestFilter {
@Value("classpath:/templates/enhance.ftl")
private Resource resource;
/**
* do 过滤器内部
*
* @param request 请求
* @param response 响应
* @param filterChain Filter Chain (筛选链)
* @throws ServletException Servlet 异常
* @throws IOException io异常
*/
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 不是首页直接跳过
if (!request.getRequestURI().equals("/jmreport/list")) {
filterChain.doFilter(request, response);
return;
}
// 包装响应对象
EditedResponseWrapper responseWrapper = new EditedResponseWrapper(response);
// 执行链并捕获响应内容
filterChain.doFilter(request, responseWrapper);
// 获取原始 HTML 内容
String originalHtml = responseWrapper.toString();
// 在 HTML 内容中插入自定义 JS
String enhancedHtml = originalHtml.replace("</body>", IoUtil.read(resource.getInputStream(), Charset.defaultCharset()) + "</body>");
// 将增强后的内容写回响应
response.getWriter().write(enhancedHtml);
}
/**
* 可编辑响应流包装器
*
* @author lengleng
* @date 2024/11/26
*/
static class EditedResponseWrapper extends HttpServletResponseWrapper {
private CharArrayWriter charArrayWriter = new CharArrayWriter();
public EditedResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public PrintWriter getWriter() {
return new PrintWriter(charArrayWriter);
}
@Override
public String toString() {
return charArrayWriter.toString();
}
}
}
@@ -1,5 +1,7 @@
server:
port: 5008
undertow:
buffer-size: 1MB
spring:
application:
@@ -0,0 +1,5 @@
<script>
document.addEventListener("DOMContentLoaded", function () {
document.querySelector("#app > div.layout > div:nth-child(1)").remove()
});
</script>
@@ -1,923 +0,0 @@
<#assign CACHE_VERSION = "v=1699715555.10">
<!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);
//update-begin---author:wangshuai ---date:20220708 for:[JMREP-2661]多租户权限集成------------
let tenantId = getRequestUrl().tenantId;
if("" == tenantId || null == tenantId){
tenantId = window.localStorage.getItem('JmReport-Tenant-Id');
}
window.localStorage.setItem('JmReport-Tenant-Id',tenantId);
//update-end---author:wangshuai ---date:20220708 for:[JMREP-2661]多租户权限集成------------
</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;
}
/*列表底部tooltip字体大小*/
.tooltip-footer-font-size .ivu-tooltip-inner{
font-size: 12px;
}
.tooltip-footer-font-size{
font-size: 12px;
}
</style>
<!--引入自定义组件-->
<#include "./template/list.ftl">
<div id="app" style="padding-left: 30px">
<div class="layout" style="margin-left: -30px;margin-top: -10px;">
<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="recycleBin">
<Icon type="md-trash"></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 style="display: flex">
<input type="file" accept=".json" id="fileInput" ref="fileInput" style="display: none" @input="handleFileUpload">
<i-button size="small" icon="ios-cloud-upload-outline" style="margin-right: 5px;" type="primary" @click="uploadFile" v-if="menuitem!='recycleBin'">导入报表</i-button>
<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" v-if="menuitem!='recycleBin'">
<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 && menuitem!='recycleBin'">
<a :href="getExcelEditUrl(item)" target="_blank">
设计
</a>
</div>
</div>
<!-- 底部 &ndash;&gt;-->
<div class="item-footer">
<Tooltip :content="item.name" placement="top-start" :transfer="true">
<template slot="content">
<span class="tooltip-footer-font-size">{{item.name}}</span>
</template>
<div class="item-name">
{{ item.name }}
</div>
</Tooltip>
<div v-if="menuitem!='recycleBin'">
<a class="opt-show" :href="getExcelViewUrl(item)" target="_blank">
<Tooltip content="预览报表" placement="top" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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 style="margin-left: 14%;" v-else>
<a class="opt-show" @click="handleReduction(item)">
<Tooltip content="还原报表" placement="top" class="tooltip-footer-font-size">
<i class="ivu-icon ivu-icon-ios-refresh" style="font-size: 16px;transform: rotate(200deg)"></i>
</Tooltip>
</a>
<a class="opt-show" @click="handleRealDelete(item)">
<Tooltip content="彻底删除报表" placement="top" transfer class="tooltip-footer-font-size">
<i class="ivu-icon ivu-icon-md-trash" style="font-size: 16px"></i>
</Tooltip>
</a>
</div>
</div>
</div>
<!-- 循环结束 &ndash;&gt;-->
</div>
<div v-else style="padding: 10px 10px">
<i-button v-if="menuitem!='recycleBin'" 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">
<template v-if="menuitem!='recycleBin'">
<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>
<template v-else>
<a class="opt-list-show" @click="handleReduction(row)">
<Tooltip content="还原报表" placement="top" transfer class="tooltip-footer-font-size">
<i class="ivu-icon ivu-icon-ios-refresh" style="font-size: 16px;transform: rotate(200deg)"></i>
</Tooltip>
</a>
<a class="opt-list-show" @click="handleRealDelete(row)">
<Tooltip content="彻底删除报表" placement="top" transfer class="tooltip-footer-font-size">
<i class="ivu-icon ivu-icon-md-trash" style="font-size: 16px"></i>
</Tooltip>
</a>
</template>
</template>
</i-table>
</div>
</tab-pane>
<tab-pane icon="md-options" label="模板案例" name="name2" class="jimu-tab" v-if="menuitem!='recycleBin'">
<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">
<Tooltip placement="top-start" transfer>
<template slot="content">
<span class="tooltip-footer-font-size">{{item.name}}</span>
</template>
<div class="item-name">
{{ item.name }}
</div>
</Tooltip>
<div style="margin-left: 14%;">
<a class="opt-show" :href="getExcelViewUrl(item)" target="_blank">
<Tooltip content="预览报表" placement="top" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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" class="tooltip-footer-font-size">
<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>
<#-- <i-button @click="show">Click me!</i-button>
<Modal v-model="visible" title="Welcome">Welcome to ViewUI</Modal>-->
</div>
<script>
var BASE_URL="${base}"+"${customPrePath}";
var currentPage = new Vue({
el: '#app',
data: {
isCollapsed: false,
token:'',//token
tenantId:'',//租户id
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'
}
],//列表的列
},
computed: {
menuitemClasses: function () {
return [
'menu-item',
this.isCollapsed ? 'collapsed-menu' : ''
]
}
},
mounted:function(){
this.token = token;
this.tenantId = tenantId;
//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,};
}
//查询报表名称加trim
if(that.name){
that.name = that.name.trim();
}
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)=>{
//update-begin---author:wangshuai ---date:20220215 for:[issues/I4SOSH]做完的积木报表,预览生成的访问地址,默认都加了token=null------------
let url = api.index+result.id+"?menuType="+this.menuitem;
window.open(this.splicingToken(url));
//update-end---author:wangshuai ---date:20220215 for:[issues/I4SOSH]做完的积木报表,预览生成的访问地址,默认都加了token=null------------
}
},that)
},
//未使用
handleEditConfig: function(item){
window.location.href = api.index+item.id+"?token="+this.token;
},
/**
* 为路径拼接token
* @param url 需要拼接的路径
* @return 拼接后的token
*/
splicingToken(url){
if(this.token && "null" != this.token){
url = this.splicingUrl("token",this.token,url);
}
if(this.tenantId && "null" !== this.tenantId){
url = this.splicingUrl("tenantId",this.tenantId,url);
}
return url;
},
/**
* 拼接路径
* @param name
* @param value
* @param url
*/
splicingUrl(name, value, url) {
if (url.indexOf("?") !== -1) {
url = url + "&" + name + "=" + value;
} else {
url = url + "?" + name + "=" + value;
}
return url;
},
//删除报表
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){
//update-begin---author:wangshuai ---date:20220215 for:[issues/I4SOSH]做完的积木报表,预览生成的访问地址,默认都加了token=null------------
return this.splicingToken(api.index+item.id);
//update-end---author:wangshuai ---date:20220215 for:[issues/I4SOSH]做完的积木报表,预览生成的访问地址,默认都加了token=null------------
},
getExcelViewUrl: function(item){
//update-begin---author:wangshuai ---date:20220215 for:[issues/I4SOSH]做完的积木报表,预览生成的访问地址,默认都加了token=null------------
return this.splicingToken(api.view+item.id);
//update-end---author:wangshuai ---date:20220215 for:[issues/I4SOSH]做完的积木报表,预览生成的访问地址,默认都加了token=null------------
},
getLabelText1:function (createElement) {
return createElement('div',
{
style:{color:'#fff'}
},
[
createElement('Icon',{props:{type:'ios-checkmark'}}),
'模板库'
]
)
},
onMenuSelect:function(name){
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);*/
},
//----------导入导出begin----------------------
handleFileUpload(event) {
const file = event.target.files[0];
const formData = new FormData();
formData.append('file', file);
// 处理文件上传操作,例如读取文件内容等
$http.post({
url:api.importReportJson,
contentType: "multipart/form-data",
data:formData,
success:(result)=>{
//console.log(result);
this.$Message.success(result);
this.loadData()
this.$refs.fileInput.value = null;
},
error:(err)=>{
console.error(err);
this.$Message.error(err);
}
});
},
uploadFile(event) {
const input = document.querySelector("#fileInput");
input?.click();
},
//----------导入导出end----------------------
//分享按钮点击事件
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;
//update-begin---author:wangshuai ---date:20221118 for:[issues/1383]yml中设置了项目前缀,分享链接地址有误------------
let url = protocol+"//"+host+BASE_URL;
//update-end---author:wangshuai ---date:20221118 for:[issues/1383]yml中设置了项目前缀,分享链接地址有误------------
result.previewUrl = url+result.previewUrl;
this.$refs.jurisdiction.jurisdictionData = result;
this.$refs.jurisdiction.shareUrlModal = true
}else{
//update-begin---author:wangshuai ---date:20220315 for:[issues/I4WWKE]分享链接的预览密码能否忽略------------
//兼容老数据没有是否显示密码的情况下;
//previewLockStatus 密码锁状态(0不存在密码锁,1存在密码锁);原来取消分享后的默认应该是1
if(!result.previewLockStatus){
result.previewLockStatus = "1"
}
//update-end---author:wangshuai ---date:20220315 for:[issues/I4WWKE]分享链接的预览密码能否忽略------------
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}"+JM_VIEW_IMG_URL+"/"+item.thumb
}
}
},
/**
* 真实删除
* @param item
*/
handleRealDelete(item){
var that = this;
this.$Modal.confirm({
title: "彻底删除",
content: "确定要彻底删除吗,删除之后无法恢复",
closable: true,
onOk: (res) => {
$http.del({
url: api.deleteReportById,
data: {
id: item.id
},
success:(res)=>{
that.loadData();
}
})
},
});
},
/**
* 撤回
* @param item
*/
handleReduction(item){
var that = this;
$http.post({
contentType:'json',
url: api.revertReportById,
data: {
id: item.id
},
success:(res)=>{
that.loadData();
}
})
}
}
})
</script>
<#include "./common/tj.ftl">
</body>
</html>
+2 -2
View File
@@ -54,9 +54,9 @@
<jasypt.version>3.0.5</jasypt.version>
<ttl.version>2.12.6</ttl.version>
<jaxb.version>2.3.5</jaxb.version>
<jimu.version>1.6.6-beta2</jimu.version>
<jimu.version>1.8.1</jimu.version>
<aws.version>1.12.261</aws.version>
<xxl.job.version>2.4.0</xxl.job.version>
<xxl.job.version>2.4.2</xxl.job.version>
<docker.registry>registry.cn-hangzhou.aliyuncs.com</docker.registry>
<docker.host>http://127.0.0.1:2375</docker.host>
<docker.namespace>pigcloudx</docker.namespace>