!89 update 0.9.8.5

Merge pull request !89 from Foming/dev
V0.9.8.5
Foming 2 years ago committed by Gitee
commit 4d9fa1ab02
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F

@ -1,8 +1,9 @@
```
第一步下载zip包解压
第二步conf->bootstrap.yml修改mysql连接
第二步conf->bootstrap.yml修改mysql连接等信息
第三步启动bin目录下start.sh
第四步,访问 http://localhost:9095
第四步,访问 http://localhost:9095 admin 123456
第五步,修改"数据源->mysql数据源"用户名密码
```
## 下载发行版
@ -21,10 +22,10 @@
![bootstrap.png](../picture/quickly/img_2.png) <br>
**注**请确认你的Mysql是否支持远程连接登陆用户是否有DDL权限 <br>
## 上传功能
## OSS配置
使用上传功能必须修改此内容注意路径格式比如Win是 \ ,linux是 / <br>
![file.png](../picture/quickly/img_15.png) <br>
OSS底层已支持minio、amazonS3、dfs都配置的情况下优先级minio->amazonS3->nfs <br>
![file.png](../picture/quickly/img.png) <br>
## 启动
@ -38,9 +39,7 @@ aj-report-XXX --> bin --> start.bat <br>
如果start.bat启动有问题的话可以尝试以下方法解决。<br>
修改第4行的JAVA_HOME改成你自己的JAVA_HOME并去掉**rem**注释,双击启动<br>
![java.png](../picture/quickly/img_7.png) <br>
**注**如果你JAVA_HOME目录存在空格将bat文件最下面的JAVA_HOME添加""号
![img.png](../picture/quickly/img_8.png) <br>
![java.png](../picture/quickly/img_7.png)
## 访问

@ -15,6 +15,8 @@ java -jar
BASE_API: '"./"'改成自己后端的api
npm install
npm run build
使用nginx转发
```
## linux部署后端
@ -24,8 +26,8 @@ npm run build
- [Apache Maven] 3.5 <br>
- [Node.js] v14.16.0 <br>
- [Jdk] 1.8 <br>
请在你的Windows上先准备好maven、node.js、jdk <br>
**注**:已知 **Jdk11** (部分小版本)存在兼容性问题请不要使用openJdk环境问题请看 **常见问题** 大类 <br>
**注**:已知 **Jdk11** (部分小版本)存在兼容性问题请不要使用openJdk环境问题请看 **常见问题** 大类 <br>
### 克隆源码
@ -36,46 +38,39 @@ git clone https://gitee.com/anji-plus/report.git <br>
### 修改mysql连接
report-core --> src --> main --> resources --> bootstrap.yml <br>
![bootstrap.png](../picture/quickly/img_2.png) <br>
将图中关于mysql的连接配置信息换成你使用的IP <br>
**注**aj_report库是存放底层基础信息的库flyway启动时会自动建立如果你在这里修改了库将会出错<br>
**注**请确认你的Mysql是否支持远程连接登陆用户是否有DDL权限 <br>
### 上传功能
使用上传功能必须修改此内容注意路径格式比如Win是 \ ,linux是 / <br>
![file.png](../picture/quickly/img_15.png) <br>
![bootstrap.png](../picture/quickly/img_2.png) <br>
### maven打包
**注 **
**打包之前如果系统用的不止mysql数据源需要自己在pom文件中加入对应的数据库的驱动登陆系统之后数据源提示无驱动则选择通用JDBC数据源这里不做演示了** <br>
使用 maven package <br>
**注**不要使用maven install <br>
**注**:此方式不会打包 lib目录下的驱动详情可查看 **数据源 扩展** <br>
![img10](../picture/quickly/img_10.png) <br>
### linux启动jar包
```
1、aj_report库是存放底层基础信息的库flyway启动时会自动建立如果你在这里修改了库将会出错
2、请确认你的Mysql是否支持远程连接登陆用户是否有DDL权限
```
将上步生成的jar包上传至linux使用java -jar命令启动 <br>
**注**请确保你的linux有jdk <br>
### OSS配置
## 本地启动前端
OSS底层已支持minio、amazonS3、dfs都配置的情况下优先级minio->amazonS3->nfs <br>
![file.png](../picture/quickly/img.png) <br>
### 前端编译
### maven打包
进入前端目录report-ui <br>
![img11](../picture/quickly/img_11.png) <br>
执行 npm install <br>
直接使用 maven package 打包,打包完成如图所示<br>
### 修改config
![img10](../picture/quickly/img_10.png) <br>
**注 **
目录地址report-ui --> config --> dev.env.js <br>
修改你的BASE_API地址 <br>
```
1、打包之前如果系统用的不止mysql数据源需要自己在pom文件中加入对应的数据库的驱动登陆系统之后数据源提示无驱动则选择通用JDBC数据源这里不做演示了
2、不要使用 maven install
3、此方式不会打包 lib目录下的驱动详情可查看 "数据源->扩展"
```
### 启动前端
### linux启动jar包
report-ui目录 <br>
执行 npm run dev <br>
将上步生成的jar包上传至linux使用java -jar命令启动 <br>
**注**请确保你的linux有jdk1.8 <br>
## 前端build
@ -88,14 +83,18 @@ report-ui目录 <br>
### 修改config
目录地址report-ui --> config --> prod.env.js <br>
修改你的BASE_API地址改成自己后端的api <br>
将BASE_API地址改成你后端的api地址 <br>
### build
### 打包
reoprt-ui目录 <br>
执行 npm run build <br>
生成的前端dist目录文件在report-ui下面 <br>
![img12](../picture/quickly/img_12.png) <br>
### 前端部署
使用nginx做转发

@ -9,8 +9,10 @@ cd aj-report-xxxx
vim conf/bootstrap.yml 修改数据库连接、上传文件的路径以及地址
sh bin/start.sh
访问
http://serverip:9095
访问http://serverip:9095
admin 123456
修改:"数据源->mysql数据源"用户名密码
```
## 编译环境
@ -37,7 +39,8 @@ git clone https://gitee.com/anji-plus/report.git <br>
编译完成后是放在当前目录下的build文件夹中aj-report-xxxx.zip <br>
**注:** 如果Win10部署的话如图用git执行sh build.sh就行了。Linux就直接去report目录下执行sh build.sh就行。 <br>
**特别注意:** 如果是Win10编译那么几个启动脚本的格式则是win的格式放linux上执行会报错的反之放linux编译在win10启动也会报错需要转格式。 <br>
**特别注意:**
如果是Win10编译那么几个启动脚本的格式则是win的格式放linux上执行会报错的反之放linux编译在win10启动也会报错需要转格式。 <br>
## 修改mysql连接
@ -50,10 +53,10 @@ git clone https://gitee.com/anji-plus/report.git <br>
![bootstrap.png](../picture/quickly/img_2.png) <br>
**注**请确认你的Mysql是否支持远程连接登陆用户是否有DDL权限 <br>
## 上传功能
## OSS配置
使用上传功能必须修改此内容注意路径格式比如Win是 \ ,linux是 / <br>
![file.png](../picture/quickly/img_15.png)
OSS底层已支持minio、amazonS3、dfs都配置的情况下优先级minio->amazonS3->nfs <br>
![file.png](../picture/quickly/img.png) <br>
## 启动

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

@ -1 +1,41 @@
## 后端springboot
### 采用redis缓存
#### 1.pom文件
```java
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-gaea</artifactId>
<version>2.0.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</exclusion>
</exclusions>
</dependency>
```
删除exclusions内容因为底层默认支持redis
删除ehcache相关依赖
#### 2.删除 package com.anjiplus.template.gaea.business.cache
CacheHelper底层默认实现为RedisCacheHelper。
@ConditionalOnMissingBean 注解起到的作用
```java
package com.anji.plus.gaea;
@Configuration
@EnableConfigurationProperties({GaeaProperties.class})
public class GaeaAutoConfiguration {
@Bean
@ConditionalOnClass({RedisAutoConfiguration.class})
@ConditionalOnMissingBean
public CacheHelper cacheHelper() {
return new RedisCacheHelper();
}
}
```
#### 3.bootstrap.yml加上对应的redis配置即可

@ -61,6 +61,12 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-mock</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
@ -76,7 +82,7 @@
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-gaea</artifactId>
<version>2.0.3.RELEASE</version>
<version>2.0.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
@ -85,6 +91,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>com.anji-plus</groupId>
<artifactId>spring-boot-starter-gaea-oss</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
@ -94,6 +106,7 @@
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
@ -115,7 +128,7 @@
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.10</version>
<version>4.5.13</version>
</dependency>
<dependency>

@ -118,7 +118,8 @@ public interface ResponseCode {
String FILE_SUFFIX_UNSUPPORTED = "2002";
String FILE_UPLOAD_ERROR = "2003";
String FILE_ONT_EXSIT = "2004";
String LIST_IS_EMPTY = "2005";
String FILE_OPERATION_FAILED = "file.operation.failed";
String PUSHCODE_NEED_UNIQUE = "3001";
String RECEIVER_IS_EMPTY = "3002";
String DATA_SOURCE_CONNECTION_FAILED = "4001";

@ -231,7 +231,7 @@ public class TokenFilter implements Filter {
}
private void error(HttpServletResponse response) throws IOException {
ResponseBean responseBean = ResponseBean.builder().code("50008").message("The Token has expired").build();
ResponseBean responseBean = ResponseBean.builder().code("User.credentials.expired").message("The Token has expired").build();
response.setContentType(ContentType.APPLICATION_JSON.getMimeType());
response.getWriter().print(JSONObject.toJSONString(responseBean));
}

@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
import com.anji.plus.gaea.bean.TreeNode;
import com.anji.plus.gaea.cache.CacheHelper;
import com.anji.plus.gaea.constant.BaseOperationEnum;
import com.anji.plus.gaea.constant.GaeaConstant;
import com.anji.plus.gaea.exception.BusinessException;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
@ -163,7 +164,7 @@ public class AccessUserServiceImpl implements AccessUserService {
} else {
// 生成用户token
String uuid = GaeaUtils.UUID();
token = jwtBean.createToken(loginName, uuid);
token = jwtBean.createToken(loginName, uuid, 0, GaeaConstant.TENANT_CODE);
cacheHelper.stringSetExpire(tokenKey, token, 3600);
}

@ -80,13 +80,13 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
@Autowired
private ReportService reportService;
@Value("${customer.file.downloadPath:''}")
@Value("${spring.gaea.subscribes.oss.downloadPath:}")
private String fileDownloadPath;
@Value("${customer.file.dist-path:''}")
@Value("${customer.file.tmp-path:.}")
private String dictPath;
private final static String ZIP_PATH = "/zip/";
private final static String ZIP_PATH = "/tmp_zip/";
private final static String JSON_PATH = "dashboard.json";
private Map<String, ChartStrategy> queryServiceImplMap = new HashMap<>();
@ -331,7 +331,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
GaeaFile gaeaFile = gaeaFileService.selectOne(queryWrapper);
String uploadPath;
if (null == gaeaFile) {
GaeaFile upload = gaeaFileService.upload(imageFile, fileName);
GaeaFile upload = gaeaFileService.upload(imageFile);
log.info("存入图片: {}", upload.getFilePath());
uploadPath = upload.getUrlPath();
}else {
@ -395,13 +395,9 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi
queryWrapper.eq(GaeaFile::getFileId, fileName);
GaeaFile gaeaFile = gaeaFileService.selectOne(queryWrapper);
if (null != gaeaFile) {
String fileType = gaeaFile.getFileType();
path = path + "/image/" + fileName + "." + fileType;
//path = /app/disk/upload/zip/UUID/image
//原始文件的路径
String filePath = gaeaFile.getFilePath();
FileUtil.copyFileUsingFileChannels(filePath, path);
byte[] file = gaeaFileService.getFile(gaeaFile.getFileId());
path = path + "/image/";
FileUtil.byte2File(file, path, gaeaFile.getFileId().concat(".").concat(gaeaFile.getFileType()));
}
}

@ -4,6 +4,7 @@ package com.anjiplus.template.gaea.business.modules.file.controller.param;
import com.anji.plus.gaea.annotation.Query;
import com.anji.plus.gaea.constant.QueryEnum;
import com.anji.plus.gaea.curd.params.PageParam;
import lombok.Data;
import java.io.Serializable;
@ -13,6 +14,7 @@ import java.io.Serializable;
* @author peiyanni
* @since 2021-02-18 14:48:29
*/
@Data
public class GaeaFileParam extends PageParam implements Serializable {
/** 模糊查询 */

@ -18,16 +18,6 @@ import java.io.File;
*/
public interface GaeaFileService extends GaeaBaseService<GaeaFileParam, GaeaFile> {
/**
*
*
* @param multipartFile
* @param file
* @param customFileName null
* @return
*/
GaeaFile upload(MultipartFile multipartFile, File file, String customFileName);
/**
*
*
@ -41,10 +31,9 @@ public interface GaeaFileService extends GaeaBaseService<GaeaFileParam, GaeaFile
*
*
* @param file
* @param customFileName
* @return
*/
GaeaFile upload(File file, String customFileName);
GaeaFile upload(File file);
/**
* fileId
*
@ -54,4 +43,11 @@ public interface GaeaFileService extends GaeaBaseService<GaeaFileParam, GaeaFile
* @return
*/
ResponseEntity<byte[]> download(HttpServletRequest request, HttpServletResponse response, String fileId);
/**
*
* @param fileId
* @return
*/
byte[] getFile(String fileId);
}

@ -4,59 +4,51 @@ import com.anji.plus.gaea.constant.BaseOperationEnum;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessException;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.gaea.oss.exceptions.GaeaOSSException;
import com.anji.plus.gaea.oss.exceptions.GaeaOSSTypeLimitedException;
import com.anji.plus.gaea.oss.ossbuilder.GaeaOSSTemplate;
import com.anji.plus.gaea.oss.utils.ResponseUtil;
import com.anjiplus.template.gaea.business.code.ResponseCode;
import com.anjiplus.template.gaea.business.modules.file.dao.GaeaFileMapper;
import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService;
import com.anjiplus.template.gaea.business.modules.file.util.FileUtils;
import com.anjiplus.template.gaea.business.modules.file.util.StringPatternUtil;
import com.anjiplus.template.gaea.business.util.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.entity.ContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.CacheControl;
import org.springframework.http.MediaType;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.FileInputStream;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* (GaeaFile)ServiceImpl
*
* @author peiyanni
* @since 2021-02-18 14:48:26
*
* @author: Raod
* @since: 2022-08-31
*/
@Service
@Slf4j
@RefreshScope
public class GaeaFileServiceImpl implements GaeaFileService {
@Value("${customer.file.dist-path:''}")
private String dictPath;
@Value("${customer.file.white-list:''}")
private String whiteList;
@Value("${customer.file.excelSuffix:''}")
private String excelSuffix;
@Value("${customer.file.downloadPath:''}")
@Value("${spring.gaea.subscribes.oss.downloadPath:''}")
private String fileDownloadPath;
@Autowired
private GaeaOSSTemplate gaeaOSSTemplate;
@Autowired
private GaeaFileMapper gaeaFileMapper;
@ -65,70 +57,6 @@ public class GaeaFileServiceImpl implements GaeaFileService {
return gaeaFileMapper;
}
@Override
@Transactional(rollbackFor = Exception.class)
public GaeaFile upload(MultipartFile multipartFile, File file, String customFileName) {
try {
String fileName = "";
if (null != multipartFile) {
fileName = multipartFile.getOriginalFilename();
}else {
fileName = file.getName();
}
if (StringUtils.isBlank(fileName)) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_EMPTY_FILENAME);
}
String suffixName = fileName.substring(fileName.lastIndexOf("."));
String fileInstruction = fileName.substring(0, fileName.lastIndexOf("."));
//白名单校验(不区分大小写)
List<String> list = new ArrayList<>(Arrays.asList(whiteList.split("\\|")));
list.addAll(list.stream().map(String::toUpperCase).collect(Collectors.toList()));
if (!list.contains(suffixName)) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_SUFFIX_UNSUPPORTED);
}
// 生成文件唯一性标识
String fileId;
if (StringUtils.isBlank(customFileName)) {
fileId = UUID.randomUUID().toString();
} else {
fileId = customFileName;
}
String newFileName = fileId + suffixName;
// 本地文件保存路径
String filePath = dictPath + newFileName;
String urlPath = fileDownloadPath + "/" + fileId;
GaeaFile gaeaFile = new GaeaFile();
gaeaFile.setFilePath(filePath);
gaeaFile.setFileId(fileId);
gaeaFile.setUrlPath(urlPath);
gaeaFile.setFileType(suffixName.replace(".", ""));
gaeaFile.setFileInstruction(fileInstruction);
gaeaFileMapper.insert(gaeaFile);
//写文件 将文件保存/app/dictPath/upload/下
java.io.File dest = new java.io.File(dictPath + newFileName);
java.io.File parentFile = dest.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
if (null != multipartFile) {
multipartFile.transferTo(dest);
}else {
FileUtil.copyFileUsingFileChannels(file, dest);
}
// 将完整的http访问路径返回
return gaeaFile;
} catch (Exception e) {
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
log.error("file upload error: {}", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_UPLOAD_ERROR);
}
}
/**
*
*
@ -137,66 +65,138 @@ public class GaeaFileServiceImpl implements GaeaFileService {
*/
@Override
public GaeaFile upload(MultipartFile multipartFile) {
return upload(multipartFile, null, null);
String originalFilename = multipartFile.getOriginalFilename();
if (StringUtils.isBlank(originalFilename)) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_EMPTY_FILENAME);
}
// 文件后缀 .png
String suffixName = originalFilename.substring(originalFilename.lastIndexOf("."));
// 生成文件唯一性标识
String fileId = UUID.randomUUID().toString();
// 生成在oss中存储的文件名 402b6193e70e40a9bf5b73a78ea1e8ab.png
String fileObjectName = fileId + suffixName;
// 生成链接通过fileId http访问路径 http://10.108.3.121:9089/meta/file/download/402b6193e70e40a9bf5b73a78ea1e8ab
String urlPath = fileDownloadPath + "/" + fileId;
// 上传文件
try{
gaeaOSSTemplate.uploadFileByInputStream(multipartFile, fileObjectName);
}catch (GaeaOSSTypeLimitedException e){
log.error("上传失败GaeaOSSTypeLimitedException", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_SUFFIX_UNSUPPORTED, e.getMessage());
}catch (GaeaOSSException e){
log.error("上传失败GaeaOSSException", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_UPLOAD_ERROR, e.getMessage());
}
// 保存到文件管理中
GaeaFile gaeaFile = new GaeaFile();
gaeaFile.setFileId(fileId);
gaeaFile.setFilePath(fileObjectName);
gaeaFile.setUrlPath(urlPath);
gaeaFile.setFileType(suffixName.replace(".", ""));
gaeaFile.setFileInstruction(originalFilename);
insert(gaeaFile);
return gaeaFile;
}
private MultipartFile getMultipartFile(File file){
FileInputStream fileInputStream;
MultipartFile multipartFile;
try {
fileInputStream = new FileInputStream(file);
multipartFile = new MockMultipartFile(file.getName(),file.getName(),
ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream);
} catch (Exception e) {
log.error("file转MultipartFile失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
return multipartFile;
}
/**
*
*
* @param file
* @param customFileName
* @return
*/
@Override
public GaeaFile upload(File file, String customFileName) {
return upload(null, file, customFileName);
public GaeaFile upload(File file) {
return upload(getMultipartFile(file));
}
@Override
public ResponseEntity<byte[]> download(HttpServletRequest request, HttpServletResponse response, String fileId) {
try {
String userAgent = request.getHeader("User-Agent");
boolean isIeBrowser = userAgent.indexOf("MSIE") > 0;
//根据fileId从gaea_file中读出filePath
// fileId必填
if(StringUtils.isBlank(fileId)){
throw BusinessExceptionBuilder.build(ResponseCode.FILE_ONT_EXSIT);
}
// 根据fileId从gaea_file中读出filePath
LambdaQueryWrapper<GaeaFile> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(GaeaFile::getFileId, fileId);
GaeaFile gaeaFile = gaeaFileMapper.selectOne(queryWrapper);
if (null == gaeaFile) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_ONT_EXSIT);
}
//解析文件路径、文件名和后缀
String filePath = gaeaFile.getFilePath();
if (StringUtils.isBlank(filePath)) {
String userAgent = request.getHeader("User-Agent");
boolean isIEBrowser = userAgent.indexOf("MSIE") > 0;
// 在oss中存储的文件名 402b6193e70e40a9bf5b73a78ea1e8ab.png
String fileObjectName = gaeaFile.getFileId().concat(".").concat(gaeaFile.getFileType());
String originalFilename = gaeaFile.getFileInstruction();
if (StringUtils.isBlank(fileObjectName) || StringUtils.isBlank(originalFilename)) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_ONT_EXSIT);
}
String filename = filePath.substring(filePath.lastIndexOf(File.separator));
String fileSuffix = filename.substring(filename.lastIndexOf("."));
//根据文件后缀来判断,是显示图片\视频\音频,还是下载文件
File file = new File(filePath);
ResponseEntity.BodyBuilder builder = ResponseEntity.ok();
builder.contentLength(file.length());
if (StringPatternUtil.stringMatchIgnoreCase(fileSuffix, "(.png|.jpg|.jpeg|.bmp|.gif|.icon)")) {
builder.cacheControl(CacheControl.noCache()).contentType(MediaType.IMAGE_PNG);
} else if (StringPatternUtil.stringMatchIgnoreCase(fileSuffix, "(.flv|.swf|.mkv|.avi|.rm|.rmvb|.mpeg|.mpg|.ogg|.ogv|.mov|.wmv|.mp4|.webm|.wav|.mid|.mp3|.aac)")) {
builder.header("Content-Type", "video/mp4; charset=UTF-8");
} else {
//application/octet-stream 二进制数据流(最常见的文件下载)
builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
filename = URLEncoder.encode(filename, "UTF-8");
if (isIeBrowser) {
builder.header("Content-Disposition", "attachment; filename=" + filename);
} else {
builder.header("Content-Disposition", "attacher; filename*=UTF-8''" + filename);
}
if (!originalFilename.endsWith(".".concat(gaeaFile.getFileType()))) {
originalFilename = originalFilename.concat(".").concat(gaeaFile.getFileType());
}
return builder.body(FileUtils.readFileToByteArray(file));
// 调用文件存储工厂,读取文件,返回字节数组
byte[] fileBytes = gaeaOSSTemplate.downloadFile(fileObjectName);
// 根据文件后缀来判断,是显示图片\视频\音频,还是下载文件
return ResponseUtil.writeBody(originalFilename, fileBytes, isIEBrowser);
} catch (Exception e) {
log.error("file download error: {}", e);
return null;
log.error("file download error", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
/**
*
*
* @param fileId
* @return
*/
@Override
public byte[] getFile(String fileId) {
// fileId必填
if(StringUtils.isBlank(fileId)){
throw BusinessExceptionBuilder.build(ResponseCode.FILE_ONT_EXSIT);
}
// 根据fileId从gaea_file中读出filePath
LambdaQueryWrapper<GaeaFile> queryWrapper = Wrappers.lambdaQuery();
queryWrapper.eq(GaeaFile::getFileId, fileId);
GaeaFile gaeaFile = gaeaFileMapper.selectOne(queryWrapper);
if (null == gaeaFile) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_ONT_EXSIT);
}
// 在oss中存储的文件名 402b6193e70e40a9bf5b73a78ea1e8ab.png
String fileObjectName = gaeaFile.getFileId().concat(".").concat(gaeaFile.getFileType());
String originalFilename = gaeaFile.getFileInstruction();
if (StringUtils.isBlank(fileObjectName) || StringUtils.isBlank(originalFilename)) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_ONT_EXSIT);
}
// 调用文件存储工厂,读取文件,返回字节数组
return gaeaOSSTemplate.downloadFile(fileObjectName);
}
/**
*
*
@ -209,13 +209,7 @@ public class GaeaFileServiceImpl implements GaeaFileService {
public void processBatchAfterOperation(List<GaeaFile> entities, BaseOperationEnum operationEnum) throws BusinessException {
if (operationEnum.equals(BaseOperationEnum.DELETE_BATCH)) {
// 删除本地文件
entities.forEach(gaeaFile -> {
String filePath = gaeaFile.getFilePath();
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
});
entities.forEach(gaeaFile -> gaeaOSSTemplate.deleteFile(gaeaFile.getFileId().concat(".").concat(gaeaFile.getFileType())));
}
}

@ -7,6 +7,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
import com.anji.plus.gaea.constant.BaseOperationEnum;
import com.anji.plus.gaea.curd.mapper.GaeaBaseMapper;
import com.anji.plus.gaea.exception.BusinessException;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anji.plus.gaea.utils.GaeaAssert;
import com.anji.plus.gaea.utils.GaeaBeanUtils;
import com.anjiplus.template.gaea.business.code.ResponseCode;
@ -14,8 +15,7 @@ import com.anjiplus.template.gaea.business.enums.ExportTypeEnum;
import com.anjiplus.template.gaea.business.modules.dataset.controller.dto.DataSetDto;
import com.anjiplus.template.gaea.business.modules.dataset.controller.dto.OriginalDataDto;
import com.anjiplus.template.gaea.business.modules.dataset.service.DataSetService;
import com.anjiplus.template.gaea.business.modules.file.dao.GaeaFileMapper;
import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile;
import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService;
import com.anjiplus.template.gaea.business.modules.report.dao.ReportMapper;
import com.anjiplus.template.gaea.business.modules.report.dao.entity.Report;
import com.anjiplus.template.gaea.business.modules.reportexcel.controller.dto.ReportExcelDto;
@ -23,7 +23,6 @@ import com.anjiplus.template.gaea.business.modules.reportexcel.dao.ReportExcelMa
import com.anjiplus.template.gaea.business.modules.reportexcel.dao.entity.ReportExcel;
import com.anjiplus.template.gaea.business.modules.reportexcel.service.ReportExcelService;
import com.anjiplus.template.gaea.business.modules.reportexcel.util.CellType;
import com.anjiplus.template.gaea.business.modules.reportexcel.util.XlsSheetUtil;
import com.anjiplus.template.gaea.business.modules.reportexcel.util.XlsUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
@ -34,8 +33,15 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.*;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* TODO
@ -54,18 +60,17 @@ public class ReportExcelServiceImpl implements ReportExcelService {
@Autowired
private DataSetService dataSetService;
@Autowired
private GaeaFileService gaeaFileService;
@Autowired
private ReportMapper reportMapper;
@Value("${customer.file.dist-path:''}")
@Value("${customer.file.tmp-path:.}")
private String dictPath;
@Value("${customer.file.downloadPath:''}")
private String fileDownloadPath;
@Autowired
private GaeaFileMapper gaeaFileMapper;
private final static String ZIP_PATH = "/tmp_zip/";
@Override
@ -139,26 +144,30 @@ public class ReportExcelServiceImpl implements ReportExcelService {
reportExcelDto.setJsonStr(report.getJsonStr());
String jsonStr = analysisReportData(reportExcelDto);
List<JSONObject> lists=(List<JSONObject> ) JSON.parse(jsonStr);
OutputStream out;
OutputStream out = null;
File file = null;
try {
String fileId = UUID.randomUUID().toString();
String filePath = dictPath + File.separator + fileId + ".xlsx";
String urlPath = fileDownloadPath + java.io.File.separator + fileId;
GaeaFile gaeaFile = new GaeaFile();
gaeaFile.setFilePath(filePath);
gaeaFile.setFileId(fileId);
gaeaFile.setUrlPath(urlPath);
gaeaFile.setFileType("xlsx");
gaeaFile.setFileInstruction(reportCode + ".xlsx");
out = new FileOutputStream(filePath);
String fileName = report.getReportCode();
File dir = new File(dictPath + ZIP_PATH);
if (!dir.exists()){
dir.mkdirs();
}
String filePath = dir.getAbsolutePath() + File.separator + fileName + ".xlsx";
file = new File(filePath);
out = Files.newOutputStream(Paths.get(filePath));
XlsUtil.exportXlsFile(out, true, lists);
gaeaFileService.upload(file);
gaeaFileMapper.insert(gaeaFile);
logger.info("导出成功:{}", gaeaFile);
} catch (IOException e) {
logger.error("导出失败", e);
}finally {
try {
out.close();
file.delete();
} catch (IOException e) {
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
}
return true;

@ -1,7 +1,7 @@
package com.anjiplus.template.gaea.business.util;
import com.anji.plus.gaea.code.ResponseCode;
import com.anji.plus.gaea.exception.BusinessExceptionBuilder;
import com.anjiplus.template.gaea.business.code.ResponseCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
@ -42,7 +42,7 @@ public class FileUtil {
log.info("链接下载图片:{},临时路径:{}", urlPath, path);
} catch (IOException e) {
log.error("根据链接下载失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
@ -66,14 +66,14 @@ public class FileUtil {
outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
} catch (IOException e) {
log.error("复制文件失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
} finally {
try {
inputChannel.close();
outputChannel.close();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
}
@ -106,7 +106,7 @@ public class FileUtil {
outputStream.close();
} catch (Exception e) {
log.error("写入文件失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
@ -132,20 +132,20 @@ public class FileUtil {
return sbf.toString();
} catch (IOException e) {
log.error("读文件失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
} finally {
if (null != isr) {
try {
isr.close();
} catch (IOException e) {
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e1.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e1.getMessage());
}
}
}
@ -185,14 +185,14 @@ public class FileUtil {
compress(srcFile, zipOut, baseDir);
} catch (IOException e) {
log.error("压缩文件夹失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
} finally {
if (null != zipOut) {
try {
zipOut.close();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
out = null;
}
@ -201,7 +201,7 @@ public class FileUtil {
out.close();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
}
@ -246,14 +246,14 @@ public class FileUtil {
} catch (IOException e) {
log.error("压缩文件夹失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
} finally {
if (null != bis) {
try {
bis.close();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
}
@ -264,23 +264,26 @@ public class FileUtil {
decompress(new ZipFile(zipFile), dstPath);
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
public static void decompress(MultipartFile zipFile, String dstPath) {
try {
File file = new File(dstPath + File.separator + zipFile.getOriginalFilename());
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
File dir = new File(dstPath);
if (!dir.exists()){
dir.mkdirs();
}
String path = dir.getPath();
String absolutePath = dir.getAbsolutePath();
File file = new File(dir.getAbsolutePath() + File.separator + zipFile.getOriginalFilename());
zipFile.transferTo(file);
decompress(new ZipFile(file), dstPath);
//解压完删除
file.delete();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
@ -326,14 +329,14 @@ public class FileUtil {
}
} catch (IOException e) {
log.error("解压失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
} finally {
if (null != in) {
try {
in.close();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
@ -342,7 +345,7 @@ public class FileUtil {
out.close();
} catch (IOException e) {
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
}
@ -350,7 +353,7 @@ public class FileUtil {
zip.close();
} catch (IOException e) {
log.error("解压失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
@ -371,7 +374,7 @@ public class FileUtil {
ins.close();
} catch (Exception e) {
log.error("获取流文件失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
@ -399,8 +402,49 @@ public class FileUtil {
});
} catch (IOException e) {
log.error("删除文件失败", e);
throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage());
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
/**
* byte file
*/
public static File byte2File(byte[] buf, String filePath, String fileName){
BufferedOutputStream bos = null;
FileOutputStream fos = null;
File file = null;
try{
File dir = new File(filePath);
if (!dir.exists()){
dir.mkdirs();
}
file = new File(filePath + File.separator + fileName);
fos = new FileOutputStream(file);
bos = new BufferedOutputStream(fos);
bos.write(buf);
}catch (Exception e){
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
finally{
if (bos != null){
try{
bos.close();
}catch (IOException e){
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
if (fos != null){
try{
fos.close();
}catch (IOException e){
log.error("", e);
throw BusinessExceptionBuilder.build(ResponseCode.FILE_OPERATION_FAILED, e.getMessage());
}
}
}
return file;
}

@ -4,8 +4,17 @@ spring:
url: jdbc:mysql://10.108.26.197:3306/aj_report?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: appuser@anji
gaea:
subscribes:
oss: #文件存储
enabled: true
##允许上传的文件后缀
file-type-while-list: .png|.jpg|.gif|.icon|.pdf|.xlsx|.xls|.csv|.mp4|.avi|.jpeg
# 用于文件上传成功后生成文件的下载公网完整URL
downloadPath: http://127.0.0.1:9095/file/download
nfs:
path: D:\\aaa\\
customer:
file:
dist-path: D:\Workspace\AJ-Report\report-core\upload
downloadPath: http://127.0.0.1:9095/file/download

@ -4,7 +4,3 @@ spring:
url: jdbc:mysql://10.108.26.197:3306/aj_report?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: appuser@anji
customer:
file:
dist-path: /app/disk/upload/

@ -22,6 +22,14 @@ spring:
url: jdbc:mysql://10.108.26.197:3306/aj_report?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: appuser@anji
#如果要使用redis请参考report-core目录下的README.md文件中写的进行调整
# redis:
# host: 127.0.0.1
# port: 6379
# password: root
# database: 1
#数据源连接池配置
druid:
initial-size: 10 # 初始化时建立物理连接的个数。初始化发生在显示调用init方法或者第一次getConnection时
@ -46,6 +54,31 @@ spring:
placeholder-replacement: false
init-sqls:
- CREATE DATABASE IF NOT EXISTS `aj_report` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
gaea:
subscribes:
oss: #文件存储 都配置的情况下优先级minio->amazonS3->nfs
enabled: true
##允许上传的文件后缀
file-type-while-list: .png|.jpg|.gif|.icon|.pdf|.xlsx|.xls|.csv|.mp4|.avi|.jpeg|.aaa
# 用于文件上传成功后生成文件的下载公网完整URL
downloadPath: http://10.108.26.197:9095/file/download
nfs:
#上传对应本地全路径,目录必须是真实存在的,注意 Win是 \ 且有盘符linux是 / 无盘符
path: /app/disk/upload/
#若要使用minio文件存储请启用以下配置
#minio:
# url: http://127.0.0.1
# port: 9000
# access-key: minioreport
# secret-key: minioreport
# bucket-name: aj-report
#若要使用amazonS3文件存储请启用以下配置
#amazonS3:
# url: http://127.0.0.1
# access-key: access-key
# secret-key: secret-key
# bucket-name: AJ-Report
#若minio和amazonS3都没有使用服务器高可用的nfs共享盘
mybatis-plus:
configuration:
@ -64,18 +97,11 @@ logging:
# 本应用自定义参数
customer:
# 开发测试用本地文件,如果是生产,请考虑使用对象存储
file:
#上传对应本地全路径,目录必须是真实存在的,注意 Win是 \ 且有盘符linux是 / 无盘符
dist-path: /app/disk/upload/
#dist-path: D:\Download
white-list: .png|.jpg|.jpeg|.gif|.icon|.pdf|.xlsx|.xls|.csv|.mp4|.avi
excelSuffix: .xlsx|.xls|.csv
#上传对应下载的下载链接路径 http://serverip:9095/file/download
downloadPath: http://10.108.26.197:9095/file/download
# 跳过token验证和权限验证的url清单
skip-authenticate-urls: /gaeaDict/all, /login, /static, /file/download/, /index.html, /favicon.ico, /reportShare/detailByCode
file:
#导入导出临时文件夹 默认.代表当前目录,拼接/tmp_zip/目录
tmpPath: .
user:
##新增用户默认密码
default:

@ -9,8 +9,9 @@ user.old.password.error=user old password error
1013=The code does not allow duplication
2001=File names are not allowed to be empty
2002=Unsupported suffix type
2003=File upload failed
2003=File upload failed:{0}
2004=File does not exist
file.operation.failed=File operation failed\uFF1A{0}
field.not.null={} can not be null
field.not.empty={} can not be empty
@ -37,16 +38,16 @@ Rule.field.value.is.required=Rule field value is required
Rule.field.value.type.error=Rule field value type error
Rule.fields.check.error=Rule fields check error
Component.load.check.error={0} Component not load
4001=Data source connection failed
4001=Data source connection failed {0}
4002=Data source type is not currently supported
4003=execute sql error
4004=Incomplete parameter replacement values
4005=execute js error
4006=analysis data error
4003=execute sql error, {0}
4004=Incomplete parameter replacement values {0}
4005=execute js error {0}
4006=analysis data error {0}
4007=The report code does not allow duplication
4008=The set code does not allow duplication
4009=The source code does not allow duplication
4009=The source code does not allow duplication {0}
4010=Can't auto find match driver class
4011=execute javaBean error
4011=execute javaBean error {0}
report.share.link.invalid=report share link invalid

@ -8,8 +8,9 @@ user.old.password.error=\u65E7\u5BC6\u7801\u4E0D\u6B63\u786E
1013=\u7F16\u7801\u4E0D\u5141\u8BB8\u91CD\u590D
2001=\u6587\u4EF6\u540D\u4E0D\u5141\u8BB8\u4E3A\u7A7A
2002=\u6587\u4EF6\u7C7B\u578B\u4E0D\u652F\u6301
2003=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25
2003=\u6587\u4EF6\u4E0A\u4F20\u5931\u8D25\uFF1A{0}
2004=\u6587\u4EF6\u4E0D\u5B58\u5728
file.operation.failed=\u6587\u4EF6\u64CD\u4F5C\u5931\u8D25\uFF1A{0}
field.not.null={}\u4E0D\u80FD\u4E3Anull
field.not.empty={}\u4E0D\u80FD\u4E3A\u7A7A\u5B57\u7B26\u4E32
@ -38,17 +39,17 @@ Rule.field.value.type.error=\u89C4\u5219\u5B57\u6BB5\u503C\u7C7B\u578B\u9519\u8B
Rule.fields.check.error=\u89C4\u5219\u53C2\u6570\u6821\u9A8C\u4E0D\u901A\u8FC7
Component.load.check.error={0}\u7EC4\u4EF6\u672A\u52A0\u8F7D
4001=\u6570\u636E\u6E90\u8FDE\u63A5\u5931\u8D25
4001=\u6570\u636E\u6E90\u8FDE\u63A5\u5931\u8D25\uFF0C{0}
4002=\u6570\u636E\u6E90\u7C7B\u578B\u6682\u4E0D\u652F\u6301
4003=\u6267\u884Csql\u5931\u8D25
4004=\u53C2\u6570\u66FF\u6362\u503C\u4E0D\u5168
4005=\u6267\u884Cjs\u5931\u8D25
4006=\u89E3\u6790\u6570\u636E\u5931\u8D25
4003=\u6267\u884Csql\u5931\u8D25\uFF0C{0}
4004=\u53C2\u6570\u66FF\u6362\u503C\u4E0D\u5168\uFF0C{0}
4005=\u6267\u884Cjs\u5931\u8D25\uFF0C{0}
4006=\u89E3\u6790\u6570\u636E\u5931\u8D25\uFF0C{0}
4007=\u62A5\u8868\u7F16\u7801\u4E0D\u5141\u8BB8\u91CD\u590D
4008=\u6570\u636E\u96C6\u7F16\u7801\u4E0D\u5141\u8BB8\u91CD\u590D
4009=\u6570\u636E\u6E90\u7F16\u7801\u4E0D\u5141\u8BB8\u91CD\u590D
4010=\u9A71\u52A8\u5305\u4E0D\u5B58\u5728
4011=\u6267\u884CjavaBean\u5931\u8D25
4010=\u9A71\u52A8\u5305\u4E0D\u5B58\u5728\uFF0C{0}
4011=\u6267\u884CjavaBean\u5931\u8D25\uFF0C{0}
6001={0}
7001=\u89E3\u6790\u5931\u8D25

@ -27,8 +27,8 @@ service.interceptors.response.use(
* code为非20000是抛错 可结合自己业务进行修改
*/
const res = response.data
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
if (res.code == '50008' || res.code == '50012' || res.code == '50014') {
// User.credentials.expired:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
if (res.code == 'User.credentials.expired' || res.code == '50012' || res.code == '50014') {
MessageBox.confirm(
'你已被登出,可以取消继续留在该页面,或者重新登录',
'重新登录',

@ -25,7 +25,7 @@
<el-collapse-item :title="item.setName" :name="item.id">
<el-popconfirm
:title="'确定删除' + item.setName + '吗?'"
@onConfirm="del(item)"
@confirm="del(item)"
>
<el-button
slot="reference"

@ -90,14 +90,14 @@
width="34%"
center
>
<div style="font-size: 30px; line-height: 50px; margin-bottom: 50px">
<div style="font-size: 20px; line-height: 50px; margin-bottom: 50px">
AJ-Report由<a href="http://www.anji-plus.com/" target="_blank" style="text-decoration: underline"><b>安吉加加信息技术有限公司</b></a
>遵循 <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank" style="word-wrap: break-word"><strong style="color: orangered">Apache2.0开源协议</strong></a
>遵循 <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank" style="text-decoration: underline; word-wrap: break-word"><strong style="color: orangered" >Apache2.0开源协议</strong></a
><a href="https://gitee.com/explore" target="_blank" style="text-decoration: underline; word-wrap: break-word"><b>Gitee平台</b></a
>进行开源
</div>
<div style="font-size: 30px; line-height: 50px">
<strong style="color: orangered">个人/商业使用须遵循Apache2.0开源协议</strong>
<div style="font-size: 20px; line-height: 50px">
<strong> 个人/商业使用须遵循Apache2.0开源协议</strong>
<strong style="color: orangered">禁止将AJ-Report产品用于违法违规业务</strong>
</div>
<span slot="footer" class="dialog-footer">

@ -3,7 +3,7 @@
<div class="admin-title" @click="goBigScreen">
<div class="con">
<img src="../../../../../static/logo-dp.png" width="50" />
<span class="version">V0.9.8.1</span>
<span class="version">V0.9.8.5</span>
</div>
</div>
<el-menu

@ -133,14 +133,14 @@
width="34%"
center
>
<div style="font-size: 30px; line-height: 50px; margin-bottom: 50px">
<div style="font-size: 20px; line-height: 50px; margin-bottom: 50px">
AJ-Report由<a href="http://www.anji-plus.com/" target="_blank" style="text-decoration: underline"><b>安吉加加信息技术有限公司</b></a
>遵循 <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank" style="word-wrap: break-word"><strong style="color: orangered">Apache2.0开源协议</strong></a
>遵循 <a href="http://www.apache.org/licenses/LICENSE-2.0.html" target="_blank" style="text-decoration: underline; word-wrap: break-word"><strong style="color: orangered" >Apache2.0开源协议</strong></a
><a href="https://gitee.com/explore" target="_blank" style="text-decoration: underline; word-wrap: break-word"><b>Gitee平台</b></a
>进行开源
</div>
<div style="font-size: 30px; line-height: 50px">
<strong style="color: orangered">个人/商业使用须遵循Apache2.0开源协议</strong>
<div style="font-size: 20px; line-height: 50px">
<strong> 个人/商业使用须遵循Apache2.0开源协议</strong>
<strong style="color: orangered">禁止将AJ-Report产品用于违法违规业务</strong>
</div>
<span slot="footer" class="dialog-footer">

Loading…
Cancel
Save