添加ftp功能
This commit is contained in:
parent
b3e7a4b63e
commit
697f45b0ad
|
|
@ -294,5 +294,12 @@
|
||||||
<groupId>org.jeecgframework.boot</groupId>
|
<groupId>org.jeecgframework.boot</groupId>
|
||||||
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
|
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jcraft</groupId>
|
||||||
|
<artifactId>jsch</artifactId>
|
||||||
|
<version>0.1.55</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -228,6 +228,7 @@ public interface CommonConstant {
|
||||||
String UPLOAD_TYPE_LOCAL = "local";
|
String UPLOAD_TYPE_LOCAL = "local";
|
||||||
String UPLOAD_TYPE_MINIO = "minio";
|
String UPLOAD_TYPE_MINIO = "minio";
|
||||||
String UPLOAD_TYPE_OSS = "alioss";
|
String UPLOAD_TYPE_OSS = "alioss";
|
||||||
|
String UPLOAD_TYPE_SFTP = "sftp";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文档上传自定义桶名称
|
* 文档上传自定义桶名称
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,14 @@ public class StrAttackFilter {
|
||||||
return m.replaceAll("").trim();
|
return m.replaceAll("").trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String filter2(String str) {
|
||||||
|
// 清除掉所有特殊字符
|
||||||
|
String regEx = "[`《》~!@#$%^&*()+=|{}':;',\\[\\]<>?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
|
||||||
|
Pattern p = Pattern.compile(regEx);
|
||||||
|
Matcher m = p.matcher(str);
|
||||||
|
return m.replaceAll("").trim();
|
||||||
|
}
|
||||||
|
|
||||||
// public static void main(String[] args) {
|
// public static void main(String[] args) {
|
||||||
// String filter = filter("@#jeecg/《》【bo】¥%……&*(o))))!@t<>,.,/?'\'~~`");
|
// String filter = filter("@#jeecg/《》【bo】¥%……&*(o))))!@t<>,.,/?'\'~~`");
|
||||||
// System.out.println(filter);
|
// System.out.println(filter);
|
||||||
|
|
|
||||||
|
|
@ -61,39 +61,39 @@ public class SyncJwxt extends BaseSync {
|
||||||
* @param param
|
* @param param
|
||||||
*/
|
*/
|
||||||
public void run(Map<String, Object> param){
|
public void run(Map<String, Object> param){
|
||||||
//查询数据
|
// //查询数据
|
||||||
List<JwxtJxrw> inDataList = expJxrwService.list();
|
// List<JwxtJxrw> inDataList = expJxrwService.list();
|
||||||
List<Xxhbjwxtjxrw> outDataList = Lists.newArrayList();
|
// List<Xxhbjwxtjxrw> outDataList = Lists.newArrayList();
|
||||||
|
//
|
||||||
//查询数据
|
// //查询数据
|
||||||
List<JwxtScwjxx> in1DataList = expScwjxxService.list();
|
// List<JwxtScwjxx> in1DataList = expScwjxxService.list();
|
||||||
List<Xxhbjwxtscwjxx> out1DataList = Lists.newArrayList();
|
// List<Xxhbjwxtscwjxx> out1DataList = Lists.newArrayList();
|
||||||
|
//
|
||||||
//查询数据
|
// //查询数据
|
||||||
List<JwxtXsmd> in2DataList = expXsmdService.list();
|
// List<JwxtXsmd> in2DataList = expXsmdService.list();
|
||||||
List<Xxhbjwxtxsmd> out2DataList = Lists.newArrayList();
|
// List<Xxhbjwxtxsmd> out2DataList = Lists.newArrayList();
|
||||||
|
//
|
||||||
//清洗数据
|
// //清洗数据
|
||||||
inDataList.forEach(x -> outDataList.add(BeanUtil.toBean(x, Xxhbjwxtjxrw.class)));
|
// inDataList.forEach(x -> outDataList.add(BeanUtil.toBean(x, Xxhbjwxtjxrw.class)));
|
||||||
in1DataList.forEach(x -> out1DataList.add(BeanUtil.toBean(x, Xxhbjwxtscwjxx.class)));
|
// in1DataList.forEach(x -> out1DataList.add(BeanUtil.toBean(x, Xxhbjwxtscwjxx.class)));
|
||||||
in2DataList.forEach(x -> out2DataList.add(BeanUtil.toBean(x, Xxhbjwxtxsmd.class)));
|
// in2DataList.forEach(x -> out2DataList.add(BeanUtil.toBean(x, Xxhbjwxtxsmd.class)));
|
||||||
|
//
|
||||||
//保存到胃
|
// //保存到胃
|
||||||
try {
|
// try {
|
||||||
QueryWrapper dqw = new QueryWrapper();
|
// QueryWrapper dqw = new QueryWrapper();
|
||||||
impJxrwService.remove(dqw);
|
// impJxrwService.remove(dqw);
|
||||||
impJxrwService.syncList(outDataList);
|
// impJxrwService.syncList(outDataList);
|
||||||
|
//
|
||||||
QueryWrapper dqw1 = new QueryWrapper();
|
// QueryWrapper dqw1 = new QueryWrapper();
|
||||||
impScwjxxService.remove(dqw1);
|
// impScwjxxService.remove(dqw1);
|
||||||
impScwjxxService.syncList(out1DataList);
|
// impScwjxxService.syncList(out1DataList);
|
||||||
|
//
|
||||||
QueryWrapper dqw2 = new QueryWrapper();
|
// QueryWrapper dqw2 = new QueryWrapper();
|
||||||
impXsmdService.remove(dqw2);
|
// impXsmdService.remove(dqw2);
|
||||||
impXsmdService.syncList(out2DataList);
|
// impXsmdService.syncList(out2DataList);
|
||||||
}catch (Exception e){
|
// }catch (Exception e){
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.demo.xxhbjwxtjxrw.service.impl;
|
package org.jeecg.modules.demo.xxhbjwxtjxrw.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
|
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
|
||||||
import org.jeecg.modules.demo.xxhbjwxtjxrw.mapper.XxhbjwxtjxrwMapper;
|
import org.jeecg.modules.demo.xxhbjwxtjxrw.mapper.XxhbjwxtjxrwMapper;
|
||||||
|
|
@ -19,6 +20,7 @@ import java.util.List;
|
||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("multi-datasource1")
|
||||||
public class XxhbjwxtjxrwServiceImpl extends ServiceImpl<XxhbjwxtjxrwMapper, Xxhbjwxtjxrw> implements IXxhbjwxtjxrwService {
|
public class XxhbjwxtjxrwServiceImpl extends ServiceImpl<XxhbjwxtjxrwMapper, Xxhbjwxtjxrw> implements IXxhbjwxtjxrwService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,10 @@ import java.io.Serializable;
|
||||||
public class JwxtScwjxx implements Serializable {
|
public class JwxtScwjxx implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**name*/
|
||||||
|
@Excel(name = "课程任务代码", width = 15)
|
||||||
|
@ApiModelProperty(value = "课程任务代码")
|
||||||
|
private String kcrwdm;
|
||||||
/**name*/
|
/**name*/
|
||||||
@Excel(name = "姓名", width = 15)
|
@Excel(name = "姓名", width = 15)
|
||||||
@ApiModelProperty(value = "姓名")
|
@ApiModelProperty(value = "姓名")
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ import lombok.experimental.Accessors;
|
||||||
public class Xxhbjwxtscwjxx implements Serializable {
|
public class Xxhbjwxtscwjxx implements Serializable {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/**name*/
|
||||||
|
@Excel(name = "课程任务代码", width = 15)
|
||||||
|
@ApiModelProperty(value = "课程任务代码")
|
||||||
|
private String kcrwdm;
|
||||||
/**name*/
|
/**name*/
|
||||||
@Excel(name = "姓名", width = 15)
|
@Excel(name = "姓名", width = 15)
|
||||||
@ApiModelProperty(value = "姓名")
|
@ApiModelProperty(value = "姓名")
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.demo.xxhbjwxtscwjxx.service.impl;
|
package org.jeecg.modules.demo.xxhbjwxtscwjxx.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
|
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
|
||||||
import org.jeecg.modules.demo.xxhbjwxtscwjxx.entity.Xxhbjwxtscwjxx;
|
import org.jeecg.modules.demo.xxhbjwxtscwjxx.entity.Xxhbjwxtscwjxx;
|
||||||
|
|
@ -20,6 +21,7 @@ import java.util.List;
|
||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("multi-datasource1")
|
||||||
public class XxhbjwxtscwjxxServiceImpl extends ServiceImpl<XxhbjwxtscwjxxMapper, Xxhbjwxtscwjxx> implements IXxhbjwxtscwjxxService {
|
public class XxhbjwxtscwjxxServiceImpl extends ServiceImpl<XxhbjwxtscwjxxMapper, Xxhbjwxtscwjxx> implements IXxhbjwxtscwjxxService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package org.jeecg.modules.demo.xxhbjwxtxsmd.service.impl;
|
package org.jeecg.modules.demo.xxhbjwxtxsmd.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
|
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
|
||||||
import org.jeecg.modules.demo.xxhbjwxtxsmd.entity.Xxhbjwxtxsmd;
|
import org.jeecg.modules.demo.xxhbjwxtxsmd.entity.Xxhbjwxtxsmd;
|
||||||
|
|
@ -20,6 +21,7 @@ import java.util.List;
|
||||||
* @Version: V1.0
|
* @Version: V1.0
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
|
@DS("multi-datasource1")
|
||||||
public class XxhbjwxtxsmdServiceImpl extends ServiceImpl<XxhbjwxtxsmdMapper, Xxhbjwxtxsmd> implements IXxhbjwxtxsmdService {
|
public class XxhbjwxtxsmdServiceImpl extends ServiceImpl<XxhbjwxtxsmdMapper, Xxhbjwxtxsmd> implements IXxhbjwxtxsmdService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
import org.jeecg.common.aspect.annotation.Dict;
|
||||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
|
@ -129,4 +130,11 @@ public class Vkczxzy0002 implements Serializable {
|
||||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
@ApiModelProperty(value = "考核材料上传时间")
|
@ApiModelProperty(value = "考核材料上传时间")
|
||||||
private Date khclTime;
|
private Date khclTime;
|
||||||
|
/**作业类型*/
|
||||||
|
@Excel(name = "作业类型", width = 15, dicCode = "zyLeixing")
|
||||||
|
@ApiModelProperty(value = "作业类型")
|
||||||
|
@Dict(dicCode = "zyLeixing")
|
||||||
|
private String zyLeixing;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -148,4 +148,10 @@ public class ZyHuizongXiangxi implements Serializable {
|
||||||
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
|
||||||
@ApiModelProperty(value = "考核材料上传时间")
|
@ApiModelProperty(value = "考核材料上传时间")
|
||||||
private java.util.Date khclTime;
|
private java.util.Date khclTime;
|
||||||
|
|
||||||
|
/**作业类型*/
|
||||||
|
@Excel(name = "作业类型", width = 15, dicCode = "zyLeixing")
|
||||||
|
@ApiModelProperty(value = "作业类型")
|
||||||
|
@Dict(dicCode = "zyLeixing")
|
||||||
|
private String zyLeixing;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,10 @@
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
<artifactId>drag-free</artifactId>
|
<artifactId>drag-free</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jcraft</groupId>
|
||||||
|
<artifactId>jsch</artifactId>
|
||||||
|
</dependency>
|
||||||
<!-- 积木报表 mongo redis 支持包
|
<!-- 积木报表 mongo redis 支持包
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jeecgframework.jimureport</groupId>
|
<groupId>org.jeecgframework.jimureport</groupId>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package org.jeecg.modules.system.controller;
|
package org.jeecg.modules.system.controller;
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.SymbolConstant;
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
|
|
@ -9,6 +10,9 @@ import org.jeecg.common.exception.JeecgBootException;
|
||||||
import org.jeecg.common.util.CommonUtils;
|
import org.jeecg.common.util.CommonUtils;
|
||||||
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
import org.jeecg.common.util.filter.SsrfFileTypeFilter;
|
||||||
import org.jeecg.common.util.oConvertUtils;
|
import org.jeecg.common.util.oConvertUtils;
|
||||||
|
import org.jeecg.modules.utils.SFTPUtil;
|
||||||
|
import org.jeecg.modules.utils.SftpConfig;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
|
@ -22,6 +26,8 @@ import org.springframework.web.servlet.ModelAndView;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
|
@ -45,6 +51,10 @@ public class CommonController {
|
||||||
@Value(value="${jeecg.uploadType}")
|
@Value(value="${jeecg.uploadType}")
|
||||||
private String uploadType;
|
private String uploadType;
|
||||||
|
|
||||||
|
|
||||||
|
@Value(value = "${jeecg.path.webapp}")
|
||||||
|
private String downloadpath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author 政辉
|
* @Author 政辉
|
||||||
* @return
|
* @return
|
||||||
|
|
@ -54,6 +64,10 @@ public class CommonController {
|
||||||
return Result.error("没有权限,请联系管理员授权后刷新缓存!");
|
return Result.error("没有权限,请联系管理员授权后刷新缓存!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
SftpConfig sftpConfig;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传统一方法
|
* 文件上传统一方法
|
||||||
* @param request
|
* @param request
|
||||||
|
|
@ -224,7 +238,46 @@ public class CommonController {
|
||||||
//update-begin---author:liusq ---date:20230912 for:检查下载文件类型--------------
|
//update-begin---author:liusq ---date:20230912 for:检查下载文件类型--------------
|
||||||
SsrfFileTypeFilter.checkDownloadFileType(imgPath);
|
SsrfFileTypeFilter.checkDownloadFileType(imgPath);
|
||||||
//update-end---author:liusq ---date:20230912 for:检查下载文件类型--------------
|
//update-end---author:liusq ---date:20230912 for:检查下载文件类型--------------
|
||||||
|
if(CommonConstant.UPLOAD_TYPE_SFTP.equals(uploadType)) {
|
||||||
|
try{
|
||||||
|
// SFTPUtil.writeFileToRes(sftpConfig,imgPath,response);
|
||||||
|
int index = imgPath.lastIndexOf("/");
|
||||||
|
String path = "temp";
|
||||||
|
if(index != -1){
|
||||||
|
path = imgPath.substring(0,index);
|
||||||
|
}
|
||||||
|
//TODO 不确定是否有问题,
|
||||||
|
Map<String,String> map = SFTPUtil.download(sftpConfig,imgPath,getDownloadPath(path));
|
||||||
|
if(!map.get("code").equals("0")){
|
||||||
|
response.setStatus(404);
|
||||||
|
throw new RuntimeException(map.get("msg"));
|
||||||
|
}
|
||||||
|
String localFilePath = map.get("fileName");
|
||||||
|
File file = new File(localFilePath);
|
||||||
|
if(!file.exists()){
|
||||||
|
response.setStatus(404);
|
||||||
|
throw new RuntimeException("文件["+imgPath+"]不存在..");
|
||||||
|
}
|
||||||
|
// 设置强制下载不打开
|
||||||
|
// response.setContentType("application/force-download");
|
||||||
|
response.addHeader("Content-Disposition", "attachment;fileName=" + new String(file.getName().getBytes("UTF-8"),"iso-8859-1"));
|
||||||
|
inputStream = new BufferedInputStream(new FileInputStream(localFilePath));
|
||||||
|
outputStream = response.getOutputStream();
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = inputStream.read(buf)) > 0) {
|
||||||
|
outputStream.write(buf, 0, len);
|
||||||
|
}
|
||||||
|
response.flushBuffer();
|
||||||
|
}catch (Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
SFTPUtil.disChannel();
|
||||||
|
SFTPUtil.disSession();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
|
||||||
|
}
|
||||||
String filePath = uploadpath + File.separator + imgPath;
|
String filePath = uploadpath + File.separator + imgPath;
|
||||||
File file = new File(filePath);
|
File file = new File(filePath);
|
||||||
if(!file.exists()){
|
if(!file.exists()){
|
||||||
|
|
@ -267,6 +320,24 @@ public class CommonController {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件真实路径
|
||||||
|
* @param path
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getDownloadPath(String path){
|
||||||
|
String filePath = "";
|
||||||
|
// if(StringUtils.isNotBlank(path)){
|
||||||
|
// return "";
|
||||||
|
// }
|
||||||
|
int idx = path.indexOf(downloadpath);
|
||||||
|
if(idx==-1){
|
||||||
|
filePath = downloadpath + File.separator + path;
|
||||||
|
}else{
|
||||||
|
filePath = path;
|
||||||
|
}
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
// /**
|
// /**
|
||||||
// * 下载文件
|
// * 下载文件
|
||||||
// * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
// * 请求地址:http://localhost:8080/common/download/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,806 @@
|
||||||
|
package org.jeecg.modules.utils;
|
||||||
|
|
||||||
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
|
import org.jeecg.common.util.CommonUtils;
|
||||||
|
import org.jeecg.common.util.filter.StrAttackFilter;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.*;
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class SFTPUtil {
|
||||||
|
private static long count = 3;
|
||||||
|
private static long count1 = 0;
|
||||||
|
private static long sleepTime = 1000;//1秒
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
|
||||||
|
private static Session sshSession = null;
|
||||||
|
private static ChannelSftp sftp = null;
|
||||||
|
|
||||||
|
public static void getSession(SftpConfig sftpConfig){
|
||||||
|
try {
|
||||||
|
if(sshSession == null ){
|
||||||
|
JSch jsch = new JSch();
|
||||||
|
sshSession = jsch.getSession(sftpConfig.getUsername(), sftpConfig.getHostname(), sftpConfig.getPort());
|
||||||
|
logger.info("Session created ... host=" + sftpConfig.getHostname() + ";port=" + sftpConfig.getPort()+";UserName=" + sftpConfig.getUsername() + ";Password="+sftpConfig.getPassword());
|
||||||
|
// jsch.addIdentity("e:/sftp_keys.ppk","");
|
||||||
|
sshSession.setPassword(sftpConfig.getPassword());
|
||||||
|
Properties sshConfig = new Properties();
|
||||||
|
sshConfig.put("StrictHostKeyChecking", "no");
|
||||||
|
sshSession.setConfig(sshConfig);
|
||||||
|
sshSession.setTimeout(sftpConfig.getTimeout());
|
||||||
|
sshSession.connect();
|
||||||
|
logger.info("Session connected ...");
|
||||||
|
logger.info("Opening Channel ...");
|
||||||
|
}
|
||||||
|
} catch (Exception e){
|
||||||
|
try{
|
||||||
|
count1 += 1;
|
||||||
|
if(count == count1){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
Thread.sleep(sleepTime);
|
||||||
|
logger.info("重新连接....");
|
||||||
|
getSession(sftpConfig);
|
||||||
|
} catch (InterruptedException e1){
|
||||||
|
throw new RuntimeException(e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void getChannelSftp(SftpConfig sftpConfig){
|
||||||
|
try {
|
||||||
|
if(sshSession == null){
|
||||||
|
getSession(sftpConfig);
|
||||||
|
Channel channel = sshSession.openChannel("sftp");
|
||||||
|
channel.connect();
|
||||||
|
sftp = (ChannelSftp) channel;
|
||||||
|
logger.info("登录成功");
|
||||||
|
}else{
|
||||||
|
Channel channel = sshSession.openChannel("sftp");
|
||||||
|
channel.connect();
|
||||||
|
sftp = (ChannelSftp) channel;
|
||||||
|
}
|
||||||
|
} catch (Exception e){
|
||||||
|
try{
|
||||||
|
count1 += 1;
|
||||||
|
if(count == count1){
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
Thread.sleep(sleepTime);
|
||||||
|
logger.info("重新连接....");
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
} catch (InterruptedException e1){
|
||||||
|
throw new RuntimeException(e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void mkdirs(String directory) throws SftpException {
|
||||||
|
String[] dics = directory.split("/");
|
||||||
|
for(int i=0;i< dics.length;i++){
|
||||||
|
try {
|
||||||
|
if(dics[i].equals("")){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sftp.cd(dics[i]);
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
sftp.mkdir(dics[i]);
|
||||||
|
sftp.cd(dics[i]);
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
throw new RuntimeException("打开文件夹错误,"+e2.getMessage(), e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* @param isConcat 是否拼接,true时拼接/kczx
|
||||||
|
* @param directory 上传的目录
|
||||||
|
* @param uploadFilePath 要上传的文件路径(文件真实路径+名称)
|
||||||
|
* @param uploadFileName 要上传的文件名称(重新定义的文件名称)
|
||||||
|
* @param
|
||||||
|
*/
|
||||||
|
public static Map<String,String> upload(SftpConfig sftpConfig,boolean isConcat, String directory, String uploadFilePath, String uploadFileName) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","上传成功");
|
||||||
|
try{
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(isConcat){
|
||||||
|
directory = getDirectory(sftpConfig.getUploadpath(),directory);
|
||||||
|
}
|
||||||
|
sftp.cd(directory);
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(directory);
|
||||||
|
// sftp.mkdir(directory);
|
||||||
|
// sftp.cd(directory);
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","ftp创建"+directory+"文件路径失败");
|
||||||
|
// throw new RuntimeException("ftp创建文件路径失败" + directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File file = new File(uploadFilePath);
|
||||||
|
InputStream inputStream=null;
|
||||||
|
try {
|
||||||
|
inputStream = new FileInputStream(file);
|
||||||
|
sftp.put(inputStream, uploadFileName);
|
||||||
|
map.put("data",directory.concat(uploadFileName));
|
||||||
|
} catch (Exception e3) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","上传文件异常:" + e3.getMessage());
|
||||||
|
// throw new RuntimeException("sftp异常" + e3);
|
||||||
|
} finally {
|
||||||
|
closeStream(inputStream,null);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String,String> upload(SftpConfig sftpConfig, MultipartFile file, String directory) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","上传成功");
|
||||||
|
try{
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(directory);
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(directory);
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","ftp创建"+directory+"文件路径失败");
|
||||||
|
// throw new RuntimeException("ftp创建文件路径失败" + directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String fileName = null;
|
||||||
|
// 获取文件名
|
||||||
|
String orgName = StrAttackFilter.filter2(file.getOriginalFilename());
|
||||||
|
orgName = CommonUtils.getFileName(orgName);
|
||||||
|
if(orgName.indexOf(SymbolConstant.SPOT)!=-1){
|
||||||
|
fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf("."));
|
||||||
|
}else{
|
||||||
|
fileName = orgName+ "_" + System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
InputStream inputStream=null;
|
||||||
|
try {
|
||||||
|
sftp.put(file.getInputStream(), fileName);
|
||||||
|
map.put("data",directory.concat("/").concat(fileName));
|
||||||
|
} catch (Exception e3) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","上传文件异常:" + e3.getMessage());
|
||||||
|
// throw new RuntimeException("sftp异常" + e3);
|
||||||
|
} finally {
|
||||||
|
closeStream(inputStream,null);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*
|
||||||
|
* @param directory 下载目录
|
||||||
|
* @param downloadFile 下载的文件
|
||||||
|
* @param saveFile 存在本地的路径
|
||||||
|
*/
|
||||||
|
public static Map<String,String> download(SftpConfig sftpConfig, String directory, String downloadFile, String saveFile) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","下载成功");
|
||||||
|
try{
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
OutputStream output = null;
|
||||||
|
try {
|
||||||
|
File localDirFile = new File(saveFile);
|
||||||
|
// 判断本地目录是否存在,不存在需要新建各级目录
|
||||||
|
if (!localDirFile.exists()) {
|
||||||
|
localDirFile.mkdirs();
|
||||||
|
}
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("开始获取远程文件:[{}]---->[{}]", new Object[]{directory, saveFile});
|
||||||
|
}
|
||||||
|
// sftp.cd(directory);
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("打开远程文件:[{}]", new Object[]{directory});
|
||||||
|
}
|
||||||
|
String newName = CommonUtils.getFileName(downloadFile);
|
||||||
|
String newDownloadFile = saveFile.concat(File.separator).concat(newName);
|
||||||
|
output = new FileOutputStream(new File(newDownloadFile));
|
||||||
|
sftp.get(directory, output);
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("文件下载成功");
|
||||||
|
}
|
||||||
|
map.put("fileName",newDownloadFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("文件下载出现异常,[{}]", e);
|
||||||
|
}
|
||||||
|
throw new RuntimeException("文件下载出现异常,[{}]", e);
|
||||||
|
} finally {
|
||||||
|
closeStream(null,output);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
* @param directory 下载目录
|
||||||
|
* @param saveFile 存在本地的路径
|
||||||
|
*/
|
||||||
|
public static Map<String,String> download(SftpConfig sftpConfig, String directory, String saveFile) {
|
||||||
|
Map<String,String> map = new HashMap<>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","下载成功");
|
||||||
|
directory = sftpConfig.getFullpath()+"/"+ directory;
|
||||||
|
String[] df = getDirectoryAndFileName(directory);
|
||||||
|
|
||||||
|
File localDirFile = new File(saveFile);
|
||||||
|
// 判断本地目录是否存在,不存在需要新建各级目录
|
||||||
|
if (!localDirFile.exists()) {
|
||||||
|
localDirFile.mkdirs();
|
||||||
|
}
|
||||||
|
saveFile = saveFile.replace("\\","/");
|
||||||
|
String newName = CommonUtils.getFileName(df[1]);
|
||||||
|
if(!newName.startsWith("/")){
|
||||||
|
newName = "/"+newName;
|
||||||
|
}
|
||||||
|
String newDownloadFile = saveFile.concat(newName);
|
||||||
|
|
||||||
|
File localFile = new File(newDownloadFile);
|
||||||
|
// 判断本地目录是否存在,不存在需要新建各级目录
|
||||||
|
if (localFile.exists()) {
|
||||||
|
map.put("fileName",newDownloadFile);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
if(sftp == null){
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp链接异常:");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
}
|
||||||
|
OutputStream output = null;
|
||||||
|
try {
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("开始获取远程文件:[{}]---->[{}]", new Object[]{directory, newDownloadFile});
|
||||||
|
}
|
||||||
|
// sftp.cd(directory);
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("打开远程文件:[{}]", new Object[]{directory});
|
||||||
|
}
|
||||||
|
output = new FileOutputStream(localFile);
|
||||||
|
sftp.get(directory, output);
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("文件下载成功");
|
||||||
|
}
|
||||||
|
map.put("fileName",newDownloadFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (logger.isInfoEnabled()) {
|
||||||
|
logger.info("文件下载出现异常,[{}]", e);
|
||||||
|
}
|
||||||
|
throw new RuntimeException("文件下载出现异常,[{}]", e);
|
||||||
|
} finally {
|
||||||
|
closeStream(null,output);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 网页下载文件
|
||||||
|
* @param response
|
||||||
|
* @param downloadFilePath
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void writeFileToRes(SftpConfig sftpConfig, String downloadFilePath, HttpServletResponse response) throws Exception {
|
||||||
|
String[] df = getDirectoryAndFileName(downloadFilePath);
|
||||||
|
String directory = df[0];
|
||||||
|
String downloadFile = df[1];
|
||||||
|
try{
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
InputStream inputStream = null;
|
||||||
|
ServletOutputStream outputStream=null;
|
||||||
|
try {
|
||||||
|
// sftp.cd(directory);
|
||||||
|
inputStream = sftp.get(downloadFilePath);
|
||||||
|
byte[] buf = new byte[1024 * 10];
|
||||||
|
outputStream = response.getOutputStream();
|
||||||
|
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(downloadFile, "UTF-8"));
|
||||||
|
int readLength;
|
||||||
|
while (((readLength = inputStream.read(buf)) != -1)) {
|
||||||
|
outputStream.write(buf, 0, readLength);
|
||||||
|
}
|
||||||
|
outputStream.flush();
|
||||||
|
} catch (Exception e1) {
|
||||||
|
// e1.printStackTrace();
|
||||||
|
// throw new Exception(StringUtils.format("sftp exception,sftp exception。 ", e1.getMessage()));
|
||||||
|
} finally {
|
||||||
|
closeStream(null,outputStream);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移动文件
|
||||||
|
* @param oldpath 原文件路径(文件路径+名称)
|
||||||
|
* @param directory 目的文件路径
|
||||||
|
* @param newname 目的文件名称
|
||||||
|
* @param
|
||||||
|
*/
|
||||||
|
public static Map<String,String> moveFile(SftpConfig sftpConfig, String oldpath, String directory, String newname) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","上传成功");
|
||||||
|
try {
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
directory = getDirectory(sftpConfig.getUploadpath(), directory);
|
||||||
|
sftp.cd(directory);
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(directory);
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "ftp创建" + directory + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Channel channel = null;
|
||||||
|
try {
|
||||||
|
if(!oldpath.startsWith("/")){
|
||||||
|
oldpath = "/"+oldpath;
|
||||||
|
}
|
||||||
|
String oldfullpath = sftpConfig.getFullpath().concat(oldpath);
|
||||||
|
String newpath = directory.concat(newname);
|
||||||
|
String newfullpath = sftpConfig.getFullpath().concat(newpath);
|
||||||
|
String moveCommand = "mv " + oldfullpath + " " + newfullpath; // 移动文件的命令
|
||||||
|
channel = sshSession.openChannel("exec");
|
||||||
|
((ChannelExec) channel).setCommand(moveCommand);
|
||||||
|
channel.setInputStream(null);
|
||||||
|
((ChannelExec) channel).setErrStream(System.err);
|
||||||
|
InputStream in = channel.getInputStream();
|
||||||
|
channel.connect();
|
||||||
|
byte[] tmp = new byte[1024];
|
||||||
|
while (true) {
|
||||||
|
while (in.available() > 0) {
|
||||||
|
int i = in.read(tmp, 0, 1024);
|
||||||
|
if (i < 0) break;
|
||||||
|
}
|
||||||
|
if (channel.isClosed()) {
|
||||||
|
System.out.println("exit-status: " + channel.getExitStatus());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(sleepTime);
|
||||||
|
} catch (Exception ee) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
channel.disconnect();
|
||||||
|
channel = null;
|
||||||
|
map.put("data",newpath);
|
||||||
|
} catch (Exception e1) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg",e1.getMessage());
|
||||||
|
// throw new RuntimeException("ftp创建文件路径失败" + directory);
|
||||||
|
}finally {
|
||||||
|
if(channel!=null){
|
||||||
|
channel.disconnect();
|
||||||
|
channel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String,String> moveFiles(SftpConfig sftpConfig, String directory, List<String[]> list) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","上传成功");
|
||||||
|
try {
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
directory = getDirectory(sftpConfig.getUploadpath(), directory);
|
||||||
|
sftp.cd(directory);
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(directory);
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + directory + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
Channel channel = null;
|
||||||
|
try {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
for(int item=0;item<list.size();item++){
|
||||||
|
String oldpath = list.get(item)[0];
|
||||||
|
if(!oldpath.startsWith("/")){
|
||||||
|
oldpath = "/"+oldpath;
|
||||||
|
}
|
||||||
|
String oldfullpath = sftpConfig.getFullpath().concat(oldpath);
|
||||||
|
String newname = list.get(item)[1];
|
||||||
|
String newpath = directory.concat(newname);
|
||||||
|
String newfullpath = sftpConfig.getFullpath().concat("/").concat(newpath);
|
||||||
|
String moveCommand = "cp " + oldfullpath + " " + newfullpath; // 移动文件的命令
|
||||||
|
channel = sshSession.openChannel("exec");
|
||||||
|
((ChannelExec) channel).setCommand(moveCommand);
|
||||||
|
channel.setInputStream(null);
|
||||||
|
((ChannelExec) channel).setErrStream(System.err);
|
||||||
|
InputStream in = channel.getInputStream();
|
||||||
|
channel.connect();
|
||||||
|
byte[] tmp = new byte[1024];
|
||||||
|
while (true) {
|
||||||
|
while (in.available() > 0) {
|
||||||
|
int i = in.read(tmp, 0, 1024);
|
||||||
|
if (i < 0) break;
|
||||||
|
}
|
||||||
|
if (channel.isClosed()) {
|
||||||
|
System.out.println("exit-status: " + channel.getExitStatus());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(1000);
|
||||||
|
} catch (Exception ee) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
channel.disconnect();
|
||||||
|
channel = null;
|
||||||
|
sb.append(newpath);
|
||||||
|
sb.append("|");
|
||||||
|
}
|
||||||
|
String path = sb.toString();
|
||||||
|
path = path.substring(0,path.length()-1);
|
||||||
|
map.put("data",path);
|
||||||
|
logger.info("移动文件成功....");
|
||||||
|
} catch (Exception e1) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg",e1.getMessage());
|
||||||
|
// throw new RuntimeException("ftp创建文件路径失败" + directory);
|
||||||
|
}finally {
|
||||||
|
if(channel!=null){
|
||||||
|
channel.disconnect();
|
||||||
|
channel = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除文件
|
||||||
|
* @param directory 要删除文件所在目录
|
||||||
|
* @param deleteFile 要删除的文件
|
||||||
|
*/
|
||||||
|
public static Map<String,String> delete(SftpConfig sftpConfig, String directory, String deleteFile) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","删除成功");
|
||||||
|
try{
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
directory = delDiagonalLines(directory);
|
||||||
|
sftp.cd(directory);
|
||||||
|
sftp.rm(deleteFile);
|
||||||
|
}catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDirectory(String uploadpath, String directory){
|
||||||
|
if(uploadpath.endsWith("/")){
|
||||||
|
return uploadpath + directory;
|
||||||
|
}else{
|
||||||
|
return uploadpath +"/"+ directory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String delDiagonalLines(String directory){
|
||||||
|
if(directory.startsWith("/")){
|
||||||
|
directory = directory.substring(directory.indexOf("/")+1);
|
||||||
|
delDiagonalLines(directory);
|
||||||
|
}
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 断掉连接
|
||||||
|
*/
|
||||||
|
public static void disChannel() {
|
||||||
|
try {
|
||||||
|
if(sftp!=null){
|
||||||
|
sftp.disconnect();
|
||||||
|
sftp=null;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void disSession() {
|
||||||
|
try {
|
||||||
|
if(sshSession!=null) {
|
||||||
|
sshSession.disconnect();
|
||||||
|
sshSession=null;
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭流
|
||||||
|
* @param outputStream
|
||||||
|
*/
|
||||||
|
private static void closeStream(InputStream inputStream,OutputStream outputStream) {
|
||||||
|
if (outputStream != null) {
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(inputStream != null){
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}finally {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getDirectoryAndFileName(String fileName) {
|
||||||
|
String[] ss = new String[2];
|
||||||
|
String path = fileName.substring(0,fileName.lastIndexOf("/"));
|
||||||
|
String name = fileName.substring(fileName.lastIndexOf("/")+1);
|
||||||
|
ss[0] = path;
|
||||||
|
ss[1] = name;
|
||||||
|
return ss;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************以下为预留方法*******************/
|
||||||
|
// /**
|
||||||
|
// * 下载远程文件夹下的所有文件
|
||||||
|
// * @param remoteFilePath
|
||||||
|
// * @param localDirPath
|
||||||
|
// * @throws Exception
|
||||||
|
// */
|
||||||
|
// public void getFileDir(String remoteFilePath, String localDirPath) throws Exception {
|
||||||
|
// File localDirFile = new File(localDirPath);
|
||||||
|
// // 判断本地目录是否存在,不存在需要新建各级目录
|
||||||
|
// if (!localDirFile.exists()) {
|
||||||
|
// localDirFile.mkdirs();
|
||||||
|
// }
|
||||||
|
// if (logger.isInfoEnabled()) {
|
||||||
|
// logger.info("sftp文件服务器文件夹[{}],下载到本地目录[{}]", new Object[]{remoteFilePath, localDirFile});
|
||||||
|
// }
|
||||||
|
// ChannelSftp channelSftp = connect();
|
||||||
|
// Vector<LsEntry> lsEntries = channelSftp.ls(remoteFilePath);
|
||||||
|
// if (logger.isInfoEnabled()) {
|
||||||
|
// logger.info("远程目录下的文件为[{}]", lsEntries);
|
||||||
|
// }
|
||||||
|
// for (LsEntry entry : lsEntries) {
|
||||||
|
// String fileName = entry.getFilename();
|
||||||
|
// if (checkFileName(fileName)) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// String remoteFileName = getRemoteFilePath(remoteFilePath, fileName);
|
||||||
|
// channelSftp.get(remoteFileName, localDirPath);
|
||||||
|
// }
|
||||||
|
// disConnect(channelSftp);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private boolean checkFileName(String fileName) {
|
||||||
|
// if (".".equals(fileName) || "..".equals(fileName)) {
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private String getRemoteFilePath(String remoteFilePath, String fileName) {
|
||||||
|
// if (remoteFilePath.endsWith("/")) {
|
||||||
|
// return remoteFilePath.concat(fileName);
|
||||||
|
// } else {
|
||||||
|
// return remoteFilePath.concat("/").concat(fileName);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * 列出目录下的文件
|
||||||
|
// * @param directory 要列出的目录
|
||||||
|
// * @return
|
||||||
|
// * @throws SftpException
|
||||||
|
// */
|
||||||
|
// public List<String> listFiles(String directory) throws SftpException {
|
||||||
|
// ChannelSftp sftp = connect();
|
||||||
|
// List fileNameList = new ArrayList();
|
||||||
|
// try {
|
||||||
|
// sftp.cd(directory);
|
||||||
|
// } catch (SftpException e) {
|
||||||
|
// return fileNameList;
|
||||||
|
// }
|
||||||
|
// Vector vector = sftp.ls(directory);
|
||||||
|
// for (int i = 0; i < vector.size(); i++) {
|
||||||
|
// if (vector.get(i) instanceof LsEntry) {
|
||||||
|
// LsEntry lsEntry = (LsEntry) vector.get(i);
|
||||||
|
// String fileName = lsEntry.getFilename();
|
||||||
|
// if (".".equals(fileName) || "..".equals(fileName)) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// fileNameList.add(fileName);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// disConnect(sftp);
|
||||||
|
// return fileNameList;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static Map<String,String> upload(SftpConfig sftpConfig, String localFile, String sftpFile) {
|
||||||
|
Map<String,String> map = new HashMap<String,String>();
|
||||||
|
map.put("code","0");
|
||||||
|
map.put("msg","上传成功");
|
||||||
|
try{
|
||||||
|
String allPath = sftpConfig.getFullpath() +"/"+sftpConfig.getUploadpath();
|
||||||
|
if(sftp == null){
|
||||||
|
getChannelSftp(sftpConfig);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(sftpConfig.getFullpath());
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
sftp.cd(sftpConfig.getUploadpath());
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(sftpConfig.getUploadpath());
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InputStream inputStream = null;
|
||||||
|
try {
|
||||||
|
inputStream = new FileInputStream(localFile);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
|
||||||
|
String aaa[] = sftpFile.split("/");
|
||||||
|
String wwqName = aaa[aaa.length -1];
|
||||||
|
for(int i=0;i<aaa.length -1;i++){
|
||||||
|
try {
|
||||||
|
sftp.cd(aaa[i]);
|
||||||
|
allPath = allPath+"/"+aaa[i];
|
||||||
|
} catch (SftpException e1) {
|
||||||
|
try {
|
||||||
|
mkdirs(aaa[i]);
|
||||||
|
} catch (SftpException e2) {
|
||||||
|
map.put("code", "1");
|
||||||
|
map.put("msg", "sftp创建" + sftpConfig.getUploadpath() + "文件路径失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sftp.put(inputStream, allPath+"/"+wwqName);
|
||||||
|
map.put("data",sftpConfig.getUploadpath().concat("/").concat(sftpFile));
|
||||||
|
} catch (Exception e3) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","上传文件异常:" + e3.getMessage());
|
||||||
|
// throw new RuntimeException("sftp异常" + e3);
|
||||||
|
} finally {
|
||||||
|
closeStream(inputStream,null);
|
||||||
|
}
|
||||||
|
}catch (Exception e) {
|
||||||
|
map.put("code","1");
|
||||||
|
map.put("msg","sftp异常:" + e.getMessage());
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.jeecg.modules.utils;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "sftp")
|
||||||
|
@Data
|
||||||
|
public class SftpConfig {
|
||||||
|
private String hostname;
|
||||||
|
private Integer port;
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private Integer timeout;
|
||||||
|
private String uploadpath;
|
||||||
|
private String fullpath;
|
||||||
|
|
||||||
|
public SftpConfig(String hostname, Integer port, String username, String password, Integer timeout, String uploadpath, String fullpath){
|
||||||
|
this.hostname = hostname;
|
||||||
|
this.port = port;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.timeout = timeout;
|
||||||
|
this.uploadpath = uploadpath;
|
||||||
|
this.fullpath = fullpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SftpConfig(){}
|
||||||
|
}
|
||||||
|
|
@ -207,8 +207,8 @@ jeecg:
|
||||||
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
||||||
#签名拦截接口
|
#签名拦截接口
|
||||||
signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys,/sys/sendChangePwdSms,/sys/user/sendChangePhoneSms,/sys/sms,/desform/api/sendVerifyCode
|
signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys,/sys/sendChangePwdSms,/sys/user/sendChangePhoneSms,/sys/sms,/desform/api/sendVerifyCode
|
||||||
# 本地:local、Minio:minio、阿里云:alioss
|
# 本地:local、Minio:minio、阿里云:alioss \sftp
|
||||||
uploadType: local
|
uploadType: sftp
|
||||||
# 前端访问地址
|
# 前端访问地址
|
||||||
domainUrl:
|
domainUrl:
|
||||||
pc: http://localhost:3100
|
pc: http://localhost:3100
|
||||||
|
|
@ -323,3 +323,12 @@ justauth:
|
||||||
type: default
|
type: default
|
||||||
prefix: 'demo::'
|
prefix: 'demo::'
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
|
#SFTP
|
||||||
|
sftp:
|
||||||
|
hostname: 192.168.2.200
|
||||||
|
port: 22
|
||||||
|
username: sftp
|
||||||
|
password: sftp
|
||||||
|
timeout: 1000
|
||||||
|
uploadpath: kczx
|
||||||
|
fullpath: /data
|
||||||
|
|
@ -207,8 +207,8 @@ jeecg:
|
||||||
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a
|
||||||
#签名拦截接口
|
#签名拦截接口
|
||||||
signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys,/sys/sendChangePwdSms,/sys/user/sendChangePhoneSms,/sys/sms,/desform/api/sendVerifyCode
|
signUrls: /sys/dict/getDictItems/*,/sys/dict/loadDict/*,/sys/dict/loadDictOrderByValue/*,/sys/dict/loadDictItem/*,/sys/dict/loadTreeData,/sys/api/queryTableDictItemsByCode,/sys/api/queryFilterTableDictInfo,/sys/api/queryTableDictByKeys,/sys/api/translateDictFromTable,/sys/api/translateDictFromTableByKeys,/sys/sendChangePwdSms,/sys/user/sendChangePhoneSms,/sys/sms,/desform/api/sendVerifyCode
|
||||||
# local\minio\alioss
|
# local\minio\alioss\sftp
|
||||||
uploadType: alioss
|
uploadType: sftp
|
||||||
# 前端访问地址
|
# 前端访问地址
|
||||||
domainUrl:
|
domainUrl:
|
||||||
pc: http://localhost:3100
|
pc: http://localhost:3100
|
||||||
|
|
@ -310,3 +310,13 @@ justauth:
|
||||||
type: default
|
type: default
|
||||||
prefix: 'demo::'
|
prefix: 'demo::'
|
||||||
timeout: 1h
|
timeout: 1h
|
||||||
|
|
||||||
|
#SFTP
|
||||||
|
sftp:
|
||||||
|
hostname: 210.47.29.99
|
||||||
|
port: 22
|
||||||
|
username: sftp
|
||||||
|
password: Nenujwc@99
|
||||||
|
timeout: 1000
|
||||||
|
uploadpath: kczx
|
||||||
|
fullpath: /data
|
||||||
|
|
@ -409,6 +409,7 @@
|
||||||
<artifactId>flyway-core</artifactId>
|
<artifactId>flyway-core</artifactId>
|
||||||
<version>7.15.0</version>
|
<version>7.15.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</dependencyManagement>
|
</dependencyManagement>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,23 +2,29 @@
|
||||||
<div class="p-2">
|
<div class="p-2">
|
||||||
<a-tabs v-model:activeKey="activeKey">
|
<a-tabs v-model:activeKey="activeKey">
|
||||||
<a-tab-pane key="1" tab="作业列表">
|
<a-tab-pane key="1" tab="作业列表">
|
||||||
<ZyHuizongList />
|
<ZyHuizongList @callback="handleZyXiangxi" />
|
||||||
<ZyHuizongXiangxiList />
|
|
||||||
</a-tab-pane>
|
<ZyHuizongXiangxiList v-show="zyhzxxShow" ref="zyxxRef"/>
|
||||||
<a-tab-pane key="2" tab="成绩列表">
|
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="2" tab="成绩列表"> </a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" name="zyHuizong-zyHuizong" setup>
|
<script lang="ts" name="zyHuizong-zyHuizong" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import ZyHuizongList from '/@/views/bl/zyHuizong/ZyHuizongList.vue'
|
import ZyHuizongList from '/@/views/bl/zyHuizong/ZyHuizongList.vue';
|
||||||
import ZyHuizongXiangxiList from '/@/views/bl/zyHuizongXiangxi/ZyHuizongXiangxiList.vue'
|
import ZyHuizongXiangxiList from '/@/views/bl/zyHuizongXiangxi/ZyHuizongXiangxiList.vue';
|
||||||
const activeKey = ref('1');
|
const activeKey = ref('1');
|
||||||
|
const zyxxRef = ref();
|
||||||
|
const zyhzxxShow = ref<boolean>(false);
|
||||||
|
|
||||||
|
function handleZyXiangxi(record) {
|
||||||
|
console.log('🤡', record);
|
||||||
|
zyxxRef.value.init(record);
|
||||||
|
zyhzxxShow.value = true;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ export const columns: BasicColumn[] = [
|
||||||
{
|
{
|
||||||
title: '学期学年',
|
title: '学期学年',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'xnxq_dictText'
|
dataIndex: 'xnxq'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '学院编号',
|
title: '学院编号',
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@
|
||||||
<BasicTable @register="registerTable">
|
<BasicTable @register="registerTable">
|
||||||
<!--操作栏-->
|
<!--操作栏-->
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
<TableAction :actions="getTableAction(record)" />
|
||||||
</template>
|
</template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
|
|
@ -80,6 +80,8 @@
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||||
|
|
||||||
|
const emit = defineEmits(['callback']);
|
||||||
|
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const queryParam = reactive<any>({});
|
const queryParam = reactive<any>({});
|
||||||
const toggleSearchStatus = ref<boolean>(false);
|
const toggleSearchStatus = ref<boolean>(false);
|
||||||
|
|
@ -113,13 +115,13 @@
|
||||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
||||||
const labelCol = reactive({
|
const labelCol = reactive({
|
||||||
xs:24,
|
xs:24,
|
||||||
sm:4,
|
sm:6,
|
||||||
xl:6,
|
xl:6,
|
||||||
xxl:4
|
xxl:6
|
||||||
});
|
});
|
||||||
const wrapperCol = reactive({
|
const wrapperCol = reactive({
|
||||||
xs: 24,
|
xs: 24,
|
||||||
sm: 20,
|
sm: 18,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 高级查询配置
|
// 高级查询配置
|
||||||
|
|
@ -155,8 +157,7 @@
|
||||||
* 详情
|
* 详情
|
||||||
*/
|
*/
|
||||||
function handleDetail(record: Recordable) {
|
function handleDetail(record: Recordable) {
|
||||||
registerModal.value.disableSubmit = true;
|
emit('callback',record)
|
||||||
registerModal.value.edit(record);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -186,32 +187,12 @@
|
||||||
function getTableAction(record) {
|
function getTableAction(record) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: '编辑',
|
label: '详情',
|
||||||
onClick: handleEdit.bind(null, record),
|
onClick: handleDetail.bind(null, record),
|
||||||
auth: 'zyHuizong:zy_huizong:edit'
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 下拉操作栏
|
|
||||||
*/
|
|
||||||
function getDropDownAction(record) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: '详情',
|
|
||||||
onClick: handleDetail.bind(null, record),
|
|
||||||
}, {
|
|
||||||
label: '删除',
|
|
||||||
popConfirm: {
|
|
||||||
title: '是否确认删除',
|
|
||||||
confirm: handleDelete.bind(null, record),
|
|
||||||
placement: 'topLeft',
|
|
||||||
},
|
|
||||||
auth: 'zyHuizong:zy_huizong:delete'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询
|
* 查询
|
||||||
|
|
|
||||||
|
|
@ -5,53 +5,64 @@ import { render } from '/@/utils/common/renderUtils';
|
||||||
import { getWeekMonthQuarterYear } from '/@/utils';
|
import { getWeekMonthQuarterYear } from '/@/utils';
|
||||||
//列表数据
|
//列表数据
|
||||||
export const columns: BasicColumn[] = [
|
export const columns: BasicColumn[] = [
|
||||||
{
|
// {
|
||||||
title: '学年学期',
|
// title: '学年学期',
|
||||||
align: "center",
|
// align: "center",
|
||||||
dataIndex: 'xnxq'
|
// dataIndex: 'xnxq',
|
||||||
},
|
// ifShow: false,
|
||||||
{
|
// },
|
||||||
title: '学院编号',
|
// {
|
||||||
align: "center",
|
// title: '学院编号',
|
||||||
dataIndex: 'xybh'
|
// align: "center",
|
||||||
},
|
// dataIndex: 'xybh',
|
||||||
{
|
// ifShow: false,
|
||||||
title: '学院名称',
|
// },
|
||||||
align: "center",
|
// {
|
||||||
dataIndex: 'xymc'
|
// title: '学院名称',
|
||||||
},
|
// align: "center",
|
||||||
{
|
// dataIndex: 'xymc',
|
||||||
title: '任务编号',
|
// ifShow: false,
|
||||||
align: "center",
|
// },
|
||||||
dataIndex: 'rwbh'
|
// {
|
||||||
},
|
// title: '任务编号',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'rwbh',
|
||||||
|
// ifShow: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '课程名称',
|
title: '课程名称',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'kcmc'
|
dataIndex: 'kcmc'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '教工号',
|
// title: '教工号',
|
||||||
align: "center",
|
// align: "center",
|
||||||
dataIndex: 'jgh'
|
// dataIndex: 'jgh',
|
||||||
},
|
// ifShow: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '授课教师',
|
title: '授课教师',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'skjs'
|
dataIndex: 'skjs'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '作业编号',
|
// title: '作业编号',
|
||||||
align: "center",
|
// align: "center",
|
||||||
dataIndex: 'zybh'
|
// dataIndex: 'zybh',
|
||||||
},
|
// ifShow: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '作业名称',
|
title: '作业名称',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'zymc'
|
dataIndex: 'zymc'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '占比',
|
title: '作业类型',
|
||||||
|
align: "center",
|
||||||
|
dataIndex: 'zyLeixing'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '占比(%)',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'qmzb'
|
dataIndex: 'qmzb'
|
||||||
},
|
},
|
||||||
|
|
@ -65,61 +76,69 @@ export const columns: BasicColumn[] = [
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'xsxm'
|
dataIndex: 'xsxm'
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: '维普检测率',
|
// title: '维普检测率',
|
||||||
align: "center",
|
// align: "center",
|
||||||
dataIndex: 'wpzyk'
|
// dataIndex: 'wpzyk',
|
||||||
},
|
// ifShow: false,
|
||||||
{
|
// },
|
||||||
title: '学校检测率',
|
// {
|
||||||
align: "center",
|
// title: '学校检测率',
|
||||||
dataIndex: 'xxzyk'
|
// align: "center",
|
||||||
},
|
// dataIndex: 'xxzyk',
|
||||||
{
|
// ifShow: false,
|
||||||
title: '本次检测率',
|
// },
|
||||||
align: "center",
|
// {
|
||||||
dataIndex: 'bczyk'
|
// title: '本次检测率',
|
||||||
},
|
// align: "center",
|
||||||
{
|
// dataIndex: 'bczyk',
|
||||||
title: 'aigc检测率',
|
// ifShow: false,
|
||||||
align: "center",
|
// },
|
||||||
dataIndex: 'aigc'
|
// {
|
||||||
},
|
// title: 'aigc检测率',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'aigc',
|
||||||
|
// ifShow: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '作业分数',
|
title: '作业分数',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'zyfs'
|
dataIndex: 'zyfs'
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// title: '作业',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'filePath'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: 'pdf内容',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'pdfPath',
|
||||||
|
// ifShow: false,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: '发布时间',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'publishTime',
|
||||||
|
// ifShow: false,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// title: '是否上传考核',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'sfsckhcl',
|
||||||
|
// ifShow: false,
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
title: '作业',
|
title: '存储路径',
|
||||||
align: "center",
|
align: "center",
|
||||||
dataIndex: 'filePath'
|
dataIndex: 'fwqPath',
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'pdf内容',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'pdfPath'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '发布时间',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'publishTime'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '是否上传考核',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'sfsckhcl'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '服务器附件地址',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'fwqPath'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '考核材料上传时间',
|
|
||||||
align: "center",
|
|
||||||
dataIndex: 'khclTime'
|
|
||||||
},
|
},
|
||||||
|
// {
|
||||||
|
// title: '考核材料上传时间',
|
||||||
|
// align: "center",
|
||||||
|
// dataIndex: 'khclTime',
|
||||||
|
// ifShow: false,
|
||||||
|
// },
|
||||||
];
|
];
|
||||||
|
|
||||||
// 高级查询数据
|
// 高级查询数据
|
||||||
|
|
|
||||||
|
|
@ -4,53 +4,27 @@
|
||||||
<div class="jeecg-basic-table-form-container">
|
<div class="jeecg-basic-table-form-container">
|
||||||
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="xnxq">
|
|
||||||
<template #label><span title="学期学年">学期学年</span></template>
|
|
||||||
<j-dict-select-tag placeholder="请选择学期学年" v-model:value="queryParam.xnxq" dictCode="xqxn" allow-clear />
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="xybh">
|
|
||||||
<template #label><span title="学院编号">学院编号</span></template>
|
|
||||||
<a-input placeholder="请输入学院编号" v-model:value="queryParam.xybh" allow-clear ></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<template v-if="toggleSearchStatus">
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="xymc">
|
|
||||||
<template #label><span title="学院名称">学院名称</span></template>
|
|
||||||
<a-input placeholder="请输入学院名称" v-model:value="queryParam.xymc" allow-clear ></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
|
||||||
<a-form-item name="kcmc">
|
|
||||||
<template #label><span title="课程名称">课程名称</span></template>
|
|
||||||
<a-input placeholder="请输入课程名称" v-model:value="queryParam.kcmc" allow-clear ></a-input>
|
|
||||||
</a-form-item>
|
|
||||||
</a-col>
|
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="jgh">
|
<a-form-item name="jgh">
|
||||||
<template #label><span title="教工号">教工号</span></template>
|
<template #label><span title="学生学号">学生学号</span></template>
|
||||||
<a-input placeholder="请输入教工号" v-model:value="queryParam.jgh" allow-clear ></a-input>
|
<j-input placeholder="请输入学生学号" v-model:value="queryParam.studentNo" allow-clear></j-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-form-item name="skjs">
|
<a-form-item name="skjs">
|
||||||
<template #label><span title="授课教师">授课教师</span></template>
|
<template #label><span title="学生姓名">学生姓名</span></template>
|
||||||
<a-input placeholder="请输入授课教师" v-model:value="queryParam.skjs" allow-clear ></a-input>
|
<j-input placeholder="请输入学生姓名" v-model:value="queryParam.studentName" allow-clear></j-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
</template>
|
|
||||||
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
<a-col :xl="6" :lg="7" :md="8" :sm="24">
|
||||||
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
|
||||||
<a-col :lg="6">
|
<a-col :lg="6">
|
||||||
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
|
<a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
|
||||||
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
|
<a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
|
||||||
<a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
|
<!-- <a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
|
||||||
{{ toggleSearchStatus ? '收起' : '展开' }}
|
{{ toggleSearchStatus ? '收起' : '展开' }}
|
||||||
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
|
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
|
||||||
</a>
|
</a> -->
|
||||||
</a-col>
|
</a-col>
|
||||||
</span>
|
</span>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
|
@ -61,7 +35,7 @@
|
||||||
<BasicTable @register="registerTable">
|
<BasicTable @register="registerTable">
|
||||||
<!--操作栏-->
|
<!--操作栏-->
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
|
<TableAction :actions="getTableAction(record)" />
|
||||||
</template>
|
</template>
|
||||||
</BasicTable>
|
</BasicTable>
|
||||||
<!-- 表单区域 -->
|
<!-- 表单区域 -->
|
||||||
|
|
@ -70,15 +44,19 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" name="zyHuizongXiangxi-zyHuizongXiangxi" setup>
|
<script lang="ts" name="zyHuizongXiangxi-zyHuizongXiangxi" setup>
|
||||||
import { ref, reactive } from 'vue';
|
import { ref, reactive ,defineExpose} from 'vue';
|
||||||
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
||||||
import { useListPage } from '/@/hooks/system/useListPage';
|
import { useListPage } from '/@/hooks/system/useListPage';
|
||||||
import { columns, superQuerySchema } from './ZyHuizongXiangxi.data';
|
import { columns, superQuerySchema } from './ZyHuizongXiangxi.data';
|
||||||
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './ZyHuizongXiangxi.api';
|
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './ZyHuizongXiangxi.api';
|
||||||
import { downloadFile } from '/@/utils/common/renderUtils';
|
import { downloadFile } from '/@/utils/common/renderUtils';
|
||||||
import ZyHuizongXiangxiModal from './components/ZyHuizongXiangxiModal.vue'
|
import ZyHuizongXiangxiModal from './components/ZyHuizongXiangxiModal.vue';
|
||||||
import { useUserStore } from '/@/store/modules/user';
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
|
||||||
|
import JInput from "/@/components/Form/src/jeecg/components/JInput.vue";
|
||||||
|
import { baseApiUrl } from '/@/utils/common/compUtils';
|
||||||
|
import { encryptByBase64 } from '/@/utils/cipher';
|
||||||
|
import { getFileAccessHttpUrl, getHeaders, getRandom } from '/@/utils/common/compUtils';
|
||||||
|
|
||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const queryParam = reactive<any>({});
|
const queryParam = reactive<any>({});
|
||||||
|
|
@ -101,25 +79,26 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
exportConfig: {
|
exportConfig: {
|
||||||
name: "作业汇总详细",
|
name: '作业汇总详细',
|
||||||
url: getExportUrl,
|
url: getExportUrl,
|
||||||
params: queryParam,
|
params: queryParam,
|
||||||
},
|
},
|
||||||
importConfig: {
|
importConfig: {
|
||||||
url: getImportUrl,
|
url: getImportUrl,
|
||||||
success: handleSuccess
|
success: handleSuccess,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
|
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
|
||||||
|
tableContext;
|
||||||
const labelCol = reactive({
|
const labelCol = reactive({
|
||||||
xs: 24,
|
xs: 24,
|
||||||
sm:4,
|
sm: 6,
|
||||||
xl: 6,
|
xl: 6,
|
||||||
xxl:4
|
xxl: 6,
|
||||||
});
|
});
|
||||||
const wrapperCol = reactive({
|
const wrapperCol = reactive({
|
||||||
xs: 24,
|
xs: 24,
|
||||||
sm: 20,
|
sm: 18,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 高级查询配置
|
// 高级查询配置
|
||||||
|
|
@ -180,38 +159,30 @@
|
||||||
(selectedRowKeys.value = []) && reload();
|
(selectedRowKeys.value = []) && reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleYulan(record){
|
||||||
|
var file = getFileAccessHttpUrl(record.fwqPath) ;
|
||||||
|
console.log('🤬', file);
|
||||||
|
window.open('https://fileview.jeecg.com/onlinePreview?url=' + encodeURIComponent(encryptByBase64(file)));
|
||||||
|
}
|
||||||
|
function handleDown(record){
|
||||||
|
downloadFile(record.filePath)
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 操作栏
|
* 操作栏
|
||||||
*/
|
*/
|
||||||
function getTableAction(record) {
|
function getTableAction(record) {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
label: '编辑',
|
label: '预览',
|
||||||
onClick: handleEdit.bind(null, record),
|
onClick: handleYulan.bind(null, record),
|
||||||
auth: 'zyHuizongXiangxi:zy_huizong_xiangxi:edit'
|
},
|
||||||
|
{
|
||||||
|
label: '下载',
|
||||||
|
onClick: handleDown.bind(null, record),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 下拉操作栏
|
|
||||||
*/
|
|
||||||
function getDropDownAction(record) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: '详情',
|
|
||||||
onClick: handleDetail.bind(null, record),
|
|
||||||
}, {
|
|
||||||
label: '删除',
|
|
||||||
popConfirm: {
|
|
||||||
title: '是否确认删除',
|
|
||||||
confirm: handleDelete.bind(null, record),
|
|
||||||
placement: 'topLeft',
|
|
||||||
},
|
|
||||||
auth: 'zyHuizongXiangxi:zy_huizong_xiangxi:delete'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询
|
* 查询
|
||||||
|
|
@ -230,9 +201,15 @@
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init(record) {
|
||||||
|
console.log('🧞', record);
|
||||||
|
queryParam.zybh = record.id;
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
init,
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|
@ -249,13 +226,14 @@
|
||||||
.query-group-split-cust {
|
.query-group-split-cust {
|
||||||
width: 30px;
|
width: 30px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-align: center
|
text-align: center;
|
||||||
}
|
}
|
||||||
.ant-form-item:not(.ant-form-item-with-help) {
|
.ant-form-item:not(.ant-form-item-with-help) {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
}
|
}
|
||||||
:deep(.ant-picker),:deep(.ant-input-number){
|
:deep(.ant-picker),
|
||||||
|
:deep(.ant-input-number) {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue