添加ftp功能

This commit is contained in:
yangjun 2024-09-05 15:12:34 +08:00
parent b3e7a4b63e
commit 697f45b0ad
23 changed files with 1325 additions and 366 deletions

View File

@ -294,5 +294,12 @@
<groupId>org.jeecgframework.boot</groupId>
<artifactId>jeecg-boot-starter-chatgpt</artifactId>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies>
</project>

View File

@ -228,6 +228,7 @@ public interface CommonConstant {
String UPLOAD_TYPE_LOCAL = "local";
String UPLOAD_TYPE_MINIO = "minio";
String UPLOAD_TYPE_OSS = "alioss";
String UPLOAD_TYPE_SFTP = "sftp";
/**
* 文档上传自定义桶名称

View File

@ -18,6 +18,14 @@ public class StrAttackFilter {
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) {
// String filter = filter("@#jeecg/《》【bo】¥%……&*o)))@t<>,.,/?'\'~~`");
// System.out.println(filter);

View File

@ -61,39 +61,39 @@ public class SyncJwxt extends BaseSync {
* @param param
*/
public void run(Map<String, Object> param){
//查询数据
List<JwxtJxrw> inDataList = expJxrwService.list();
List<Xxhbjwxtjxrw> outDataList = Lists.newArrayList();
//查询数据
List<JwxtScwjxx> in1DataList = expScwjxxService.list();
List<Xxhbjwxtscwjxx> out1DataList = Lists.newArrayList();
//查询数据
List<JwxtXsmd> in2DataList = expXsmdService.list();
List<Xxhbjwxtxsmd> out2DataList = Lists.newArrayList();
//清洗数据
inDataList.forEach(x -> outDataList.add(BeanUtil.toBean(x, Xxhbjwxtjxrw.class)));
in1DataList.forEach(x -> out1DataList.add(BeanUtil.toBean(x, Xxhbjwxtscwjxx.class)));
in2DataList.forEach(x -> out2DataList.add(BeanUtil.toBean(x, Xxhbjwxtxsmd.class)));
//保存到胃
try {
QueryWrapper dqw = new QueryWrapper();
impJxrwService.remove(dqw);
impJxrwService.syncList(outDataList);
QueryWrapper dqw1 = new QueryWrapper();
impScwjxxService.remove(dqw1);
impScwjxxService.syncList(out1DataList);
QueryWrapper dqw2 = new QueryWrapper();
impXsmdService.remove(dqw2);
impXsmdService.syncList(out2DataList);
}catch (Exception e){
e.printStackTrace();
}
// //查询数据
// List<JwxtJxrw> inDataList = expJxrwService.list();
// List<Xxhbjwxtjxrw> outDataList = Lists.newArrayList();
//
// //查询数据
// List<JwxtScwjxx> in1DataList = expScwjxxService.list();
// List<Xxhbjwxtscwjxx> out1DataList = Lists.newArrayList();
//
// //查询数据
// List<JwxtXsmd> in2DataList = expXsmdService.list();
// List<Xxhbjwxtxsmd> out2DataList = Lists.newArrayList();
//
// //清洗数据
// inDataList.forEach(x -> outDataList.add(BeanUtil.toBean(x, Xxhbjwxtjxrw.class)));
// in1DataList.forEach(x -> out1DataList.add(BeanUtil.toBean(x, Xxhbjwxtscwjxx.class)));
// in2DataList.forEach(x -> out2DataList.add(BeanUtil.toBean(x, Xxhbjwxtxsmd.class)));
//
// //保存到胃
// try {
// QueryWrapper dqw = new QueryWrapper();
// impJxrwService.remove(dqw);
// impJxrwService.syncList(outDataList);
//
// QueryWrapper dqw1 = new QueryWrapper();
// impScwjxxService.remove(dqw1);
// impScwjxxService.syncList(out1DataList);
//
// QueryWrapper dqw2 = new QueryWrapper();
// impXsmdService.remove(dqw2);
// impXsmdService.syncList(out2DataList);
// }catch (Exception e){
// e.printStackTrace();
// }
}

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.demo.xxhbjwxtjxrw.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
import org.jeecg.modules.demo.xxhbjwxtjxrw.mapper.XxhbjwxtjxrwMapper;
@ -19,6 +20,7 @@ import java.util.List;
* @Version: V1.0
*/
@Service
@DS("multi-datasource1")
public class XxhbjwxtjxrwServiceImpl extends ServiceImpl<XxhbjwxtjxrwMapper, Xxhbjwxtjxrw> implements IXxhbjwxtjxrwService {
@Override

View File

@ -24,6 +24,10 @@ import java.io.Serializable;
public class JwxtScwjxx implements Serializable {
private static final long serialVersionUID = 1L;
/**name*/
@Excel(name = "课程任务代码", width = 15)
@ApiModelProperty(value = "课程任务代码")
private String kcrwdm;
/**name*/
@Excel(name = "姓名", width = 15)
@ApiModelProperty(value = "姓名")

View File

@ -32,6 +32,10 @@ import lombok.experimental.Accessors;
public class Xxhbjwxtscwjxx implements Serializable {
private static final long serialVersionUID = 1L;
/**name*/
@Excel(name = "课程任务代码", width = 15)
@ApiModelProperty(value = "课程任务代码")
private String kcrwdm;
/**name*/
@Excel(name = "姓名", width = 15)
@ApiModelProperty(value = "姓名")

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.demo.xxhbjwxtscwjxx.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
import org.jeecg.modules.demo.xxhbjwxtscwjxx.entity.Xxhbjwxtscwjxx;
@ -20,6 +21,7 @@ import java.util.List;
* @Version: V1.0
*/
@Service
@DS("multi-datasource1")
public class XxhbjwxtscwjxxServiceImpl extends ServiceImpl<XxhbjwxtscwjxxMapper, Xxhbjwxtscwjxx> implements IXxhbjwxtscwjxxService {
@Override

View File

@ -1,5 +1,6 @@
package org.jeecg.modules.demo.xxhbjwxtxsmd.service.impl;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.jeecg.modules.demo.xxhbjwxtjxrw.entity.Xxhbjwxtjxrw;
import org.jeecg.modules.demo.xxhbjwxtxsmd.entity.Xxhbjwxtxsmd;
@ -20,6 +21,7 @@ import java.util.List;
* @Version: V1.0
*/
@Service
@DS("multi-datasource1")
public class XxhbjwxtxsmdServiceImpl extends ServiceImpl<XxhbjwxtxsmdMapper, Xxhbjwxtxsmd> implements IXxhbjwxtxsmdService {
@Override

View File

@ -9,6 +9,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
@ -129,4 +130,11 @@ public class Vkczxzy0002 implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "考核材料上传时间")
private Date khclTime;
/**作业类型*/
@Excel(name = "作业类型", width = 15, dicCode = "zyLeixing")
@ApiModelProperty(value = "作业类型")
@Dict(dicCode = "zyLeixing")
private String zyLeixing;
}

View File

@ -148,4 +148,10 @@ public class ZyHuizongXiangxi implements Serializable {
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "考核材料上传时间")
private java.util.Date khclTime;
/**作业类型*/
@Excel(name = "作业类型", width = 15, dicCode = "zyLeixing")
@ApiModelProperty(value = "作业类型")
@Dict(dicCode = "zyLeixing")
private String zyLeixing;
}

View File

@ -38,11 +38,15 @@
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>drag-free</artifactId>
</dependency>
<!-- 积木报表 mongo redis 支持包
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-nosql-starter</artifactId>
</dependency>-->
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
</dependency>
<!-- 积木报表 mongo redis 支持包
<dependency>
<groupId>org.jeecgframework.jimureport</groupId>
<artifactId>jimureport-nosql-starter</artifactId>
</dependency>-->
</dependencies>
</project>

View File

@ -1,6 +1,7 @@
package org.jeecg.modules.system.controller;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
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.filter.SsrfFileTypeFilter;
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.context.annotation.Lazy;
import org.springframework.util.AntPathMatcher;
@ -22,6 +26,8 @@ import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;
import java.util.Map;
/**
* <p>
@ -45,6 +51,10 @@ public class CommonController {
@Value(value="${jeecg.uploadType}")
private String uploadType;
@Value(value = "${jeecg.path.webapp}")
private String downloadpath;
/**
* @Author 政辉
* @return
@ -54,6 +64,10 @@ public class CommonController {
return Result.error("没有权限,请联系管理员授权后刷新缓存!");
}
@Autowired
SftpConfig sftpConfig;
/**
* 文件上传统一方法
* @param request
@ -224,7 +238,46 @@ public class CommonController {
//update-begin---author:liusq ---date:20230912 for检查下载文件类型--------------
SsrfFileTypeFilter.checkDownloadFileType(imgPath);
//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;
File file = new File(filePath);
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}

View File

@ -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;
}
}

View File

@ -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(){}
}

View File

@ -207,8 +207,8 @@ jeecg:
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
# 本地local、Miniominio、阿里云alioss
uploadType: local
# 本地local、Miniominio、阿里云alioss \sftp
uploadType: sftp
# 前端访问地址
domainUrl:
pc: http://localhost:3100
@ -323,3 +323,12 @@ justauth:
type: default
prefix: 'demo::'
timeout: 1h
#SFTP
sftp:
hostname: 192.168.2.200
port: 22
username: sftp
password: sftp
timeout: 1000
uploadpath: kczx
fullpath: /data

View File

@ -207,8 +207,8 @@ jeecg:
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
# local\minio\alioss
uploadType: alioss
# local\minio\alioss\sftp
uploadType: sftp
# 前端访问地址
domainUrl:
pc: http://localhost:3100
@ -310,3 +310,13 @@ justauth:
type: default
prefix: 'demo::'
timeout: 1h
#SFTP
sftp:
hostname: 210.47.29.99
port: 22
username: sftp
password: Nenujwc@99
timeout: 1000
uploadpath: kczx
fullpath: /data

View File

@ -409,6 +409,7 @@
<artifactId>flyway-core</artifactId>
<version>7.15.0</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -2,23 +2,29 @@
<div class="p-2">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane key="1" tab="作业列表">
<ZyHuizongList />
<ZyHuizongXiangxiList />
</a-tab-pane>
<a-tab-pane key="2" tab="成绩列表">
<ZyHuizongList @callback="handleZyXiangxi" />
<ZyHuizongXiangxiList v-show="zyhzxxShow" ref="zyxxRef"/>
</a-tab-pane>
<a-tab-pane key="2" tab="成绩列表"> </a-tab-pane>
</a-tabs>
</div>
</template>
<script lang="ts" name="zyHuizong-zyHuizong" setup>
import { ref } from 'vue';
import ZyHuizongList from '/@/views/bl/zyHuizong/ZyHuizongList.vue'
import ZyHuizongXiangxiList from '/@/views/bl/zyHuizongXiangxi/ZyHuizongXiangxiList.vue'
import { ref } from 'vue';
import ZyHuizongList from '/@/views/bl/zyHuizong/ZyHuizongList.vue';
import ZyHuizongXiangxiList from '/@/views/bl/zyHuizongXiangxi/ZyHuizongXiangxiList.vue';
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>
<style lang="less" scoped>
</style>

View File

@ -8,7 +8,7 @@ export const columns: BasicColumn[] = [
{
title: '学期学年',
align: "center",
dataIndex: 'xnxq_dictText'
dataIndex: 'xnxq'
},
{
title: '学院编号',

View File

@ -61,7 +61,7 @@
<BasicTable @register="registerTable">
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<!-- 表单区域 -->
@ -80,6 +80,8 @@
import { useUserStore } from '/@/store/modules/user';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
const emit = defineEmits(['callback']);
const formRef = ref();
const queryParam = reactive<any>({});
const toggleSearchStatus = ref<boolean>(false);
@ -113,13 +115,13 @@
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
const labelCol = reactive({
xs:24,
sm:4,
sm:6,
xl:6,
xxl:4
xxl:6
});
const wrapperCol = reactive({
xs: 24,
sm: 20,
sm: 18,
});
//
@ -155,8 +157,7 @@
* 详情
*/
function handleDetail(record: Recordable) {
registerModal.value.disableSubmit = true;
registerModal.value.edit(record);
emit('callback',record)
}
/**
@ -186,32 +187,12 @@
function getTableAction(record) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'zyHuizong:zy_huizong:edit'
label: '详情',
onClick: handleDetail.bind(null, record),
},
];
}
/**
* 下拉操作栏
*/
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'
}
]
}
/**
* 查询

View File

@ -5,53 +5,64 @@ import { render } from '/@/utils/common/renderUtils';
import { getWeekMonthQuarterYear } from '/@/utils';
//列表数据
export const columns: BasicColumn[] = [
{
title: '学年学期',
align: "center",
dataIndex: 'xnxq'
},
{
title: '学院编号',
align: "center",
dataIndex: 'xybh'
},
{
title: '学院名称',
align: "center",
dataIndex: 'xymc'
},
{
title: '任务编号',
align: "center",
dataIndex: 'rwbh'
},
// {
// title: '学年学期',
// align: "center",
// dataIndex: 'xnxq',
// ifShow: false,
// },
// {
// title: '学院编号',
// align: "center",
// dataIndex: 'xybh',
// ifShow: false,
// },
// {
// title: '学院名称',
// align: "center",
// dataIndex: 'xymc',
// ifShow: false,
// },
// {
// title: '任务编号',
// align: "center",
// dataIndex: 'rwbh',
// ifShow: false,
// },
{
title: '课程名称',
align: "center",
dataIndex: 'kcmc'
},
{
title: '教工号',
align: "center",
dataIndex: 'jgh'
},
// {
// title: '教工号',
// align: "center",
// dataIndex: 'jgh',
// ifShow: false,
// },
{
title: '授课教师',
align: "center",
dataIndex: 'skjs'
},
{
title: '作业编号',
align: "center",
dataIndex: 'zybh'
},
// {
// title: '作业编号',
// align: "center",
// dataIndex: 'zybh',
// ifShow: false,
// },
{
title: '作业名称',
align: "center",
dataIndex: 'zymc'
},
{
title: '占比',
title: '作业类型',
align: "center",
dataIndex: 'zyLeixing'
},
{
title: '占比(%)',
align: "center",
dataIndex: 'qmzb'
},
@ -65,61 +76,69 @@ export const columns: BasicColumn[] = [
align: "center",
dataIndex: 'xsxm'
},
{
title: '维普检测率',
align: "center",
dataIndex: 'wpzyk'
},
{
title: '学校检测率',
align: "center",
dataIndex: 'xxzyk'
},
{
title: '本次检测率',
align: "center",
dataIndex: 'bczyk'
},
{
title: 'aigc检测率',
align: "center",
dataIndex: 'aigc'
},
// {
// title: '维普检测率',
// align: "center",
// dataIndex: 'wpzyk',
// ifShow: false,
// },
// {
// title: '学校检测率',
// align: "center",
// dataIndex: 'xxzyk',
// ifShow: false,
// },
// {
// title: '本次检测率',
// align: "center",
// dataIndex: 'bczyk',
// ifShow: false,
// },
// {
// title: 'aigc检测率',
// align: "center",
// dataIndex: 'aigc',
// ifShow: false,
// },
{
title: '作业分数',
align: "center",
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",
dataIndex: 'filePath'
},
{
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'
dataIndex: 'fwqPath',
},
// {
// title: '考核材料上传时间',
// align: "center",
// dataIndex: 'khclTime',
// ifShow: false,
// },
];
// 高级查询数据

View File

@ -5,52 +5,26 @@
<a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam" :label-col="labelCol" :wrapper-col="wrapperCol">
<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 name="jgh">
<template #label><span title="学生学号">学生学号</span></template>
<j-input placeholder="请输入学生学号" v-model:value="queryParam.studentNo" allow-clear></j-input>
</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 name="skjs">
<template #label><span title="学生姓名">学生姓名</span></template>
<j-input placeholder="请输入学生姓名" v-model:value="queryParam.studentName" allow-clear></j-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-form-item name="jgh">
<template #label><span title="教工号">教工号</span></template>
<a-input placeholder="请输入教工号" v-model:value="queryParam.jgh" allow-clear ></a-input>
</a-form-item>
</a-col>
<a-col :lg="6">
<a-form-item name="skjs">
<template #label><span title="授课教师">授课教师</span></template>
<a-input placeholder="请输入授课教师" v-model:value="queryParam.skjs" allow-clear ></a-input>
</a-form-item>
</a-col>
</template>
<a-col :xl="6" :lg="7" :md="8" :sm="24">
<span style="float: left; overflow: hidden" class="table-page-search-submitButtons">
<a-col :lg="6">
<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 @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
<!-- <a @click="toggleSearchStatus = !toggleSearchStatus" style="margin-left: 8px">
{{ toggleSearchStatus ? '收起' : '展开' }}
<Icon :icon="toggleSearchStatus ? 'ant-design:up-outlined' : 'ant-design:down-outlined'" />
</a>
</a> -->
</a-col>
</span>
</a-col>
@ -58,10 +32,10 @@
</a-form>
</div>
<!--引用表格-->
<BasicTable @register="registerTable" >
<BasicTable @register="registerTable">
<!--操作栏-->
<template #action="{ record }">
<TableAction :actions="getTableAction(record)" :dropDownActions="getDropDownAction(record)"/>
<TableAction :actions="getTableAction(record)" />
</template>
</BasicTable>
<!-- 表单区域 -->
@ -70,193 +44,197 @@
</template>
<script lang="ts" name="zyHuizongXiangxi-zyHuizongXiangxi" setup>
import { ref, reactive } from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, superQuerySchema } from './ZyHuizongXiangxi.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './ZyHuizongXiangxi.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import ZyHuizongXiangxiModal from './components/ZyHuizongXiangxiModal.vue'
import { useUserStore } from '/@/store/modules/user';
import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue';
import { ref, reactive ,defineExpose} from 'vue';
import { BasicTable, useTable, TableAction } from '/@/components/Table';
import { useListPage } from '/@/hooks/system/useListPage';
import { columns, superQuerySchema } from './ZyHuizongXiangxi.data';
import { list, deleteOne, batchDelete, getImportUrl, getExportUrl } from './ZyHuizongXiangxi.api';
import { downloadFile } from '/@/utils/common/renderUtils';
import ZyHuizongXiangxiModal from './components/ZyHuizongXiangxiModal.vue';
import { useUserStore } from '/@/store/modules/user';
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 queryParam = reactive<any>({});
const toggleSearchStatus = ref<boolean>(false);
const registerModal = ref();
const userStore = useUserStore();
//table
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
api: list,
columns,
canResize:false,
useSearchForm: false,
actionColumn: {
width: 120,
fixed: 'right',
},
beforeFetch: async (params) => {
return Object.assign(params, queryParam);
},
const formRef = ref();
const queryParam = reactive<any>({});
const toggleSearchStatus = ref<boolean>(false);
const registerModal = ref();
const userStore = useUserStore();
//table
const { prefixCls, tableContext, onExportXls, onImportXls } = useListPage({
tableProps: {
api: list,
columns,
canResize: false,
useSearchForm: false,
actionColumn: {
width: 120,
fixed: 'right',
},
exportConfig: {
name: "作业汇总详细",
url: getExportUrl,
params: queryParam,
beforeFetch: async (params) => {
return Object.assign(params, queryParam);
},
importConfig: {
url: getImportUrl,
success: handleSuccess
},
});
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] = tableContext;
const labelCol = reactive({
xs:24,
sm:4,
xl:6,
xxl:4
});
const wrapperCol = reactive({
xs: 24,
sm: 20,
},
exportConfig: {
name: '作业汇总详细',
url: getExportUrl,
params: queryParam,
},
importConfig: {
url: getImportUrl,
success: handleSuccess,
},
});
const [registerTable, { reload, collapseAll, updateTableDataRecord, findTableDataRecord, getDataSource }, { rowSelection, selectedRowKeys }] =
tableContext;
const labelCol = reactive({
xs: 24,
sm: 6,
xl: 6,
xxl: 6,
});
const wrapperCol = reactive({
xs: 24,
sm: 18,
});
//
const superQueryConfig = reactive(superQuerySchema);
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
searchQuery();
}
//
const superQueryConfig = reactive(superQuerySchema);
/**
* 新增事件
*/
function handleAdd() {
registerModal.value.disableSubmit = false;
registerModal.value.add();
}
/**
* 高级查询事件
*/
function handleSuperQuery(params) {
Object.keys(params).map((k) => {
queryParam[k] = params[k];
});
searchQuery();
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
registerModal.value.disableSubmit = false;
registerModal.value.edit(record);
}
/**
* 新增事件
*/
function handleAdd() {
registerModal.value.disableSubmit = false;
registerModal.value.add();
}
/**
* 编辑事件
*/
function handleEdit(record: Recordable) {
registerModal.value.disableSubmit = false;
registerModal.value.edit(record);
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
registerModal.value.disableSubmit = true;
registerModal.value.edit(record);
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(selectedRowKeys.value = []) && reload();
}
/**
* 操作栏
*/
function getTableAction(record) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
auth: 'zyHuizongXiangxi:zy_huizong_xiangxi:edit'
},
];
}
/**
* 下拉操作栏
*/
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'
}
]
}
/**
* 详情
*/
function handleDetail(record: Recordable) {
registerModal.value.disableSubmit = true;
registerModal.value.edit(record);
}
/**
* 查询
*/
function searchQuery() {
reload();
}
/**
* 重置
*/
function searchReset() {
formRef.value.resetFields();
selectedRowKeys.value = [];
//
reload();
}
/**
* 删除事件
*/
async function handleDelete(record) {
await deleteOne({ id: record.id }, handleSuccess);
}
/**
* 批量删除事件
*/
async function batchHandleDelete() {
await batchDelete({ ids: selectedRowKeys.value }, handleSuccess);
}
/**
* 成功回调
*/
function handleSuccess() {
(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) {
return [
{
label: '预览',
onClick: handleYulan.bind(null, record),
},
{
label: '下载',
onClick: handleDown.bind(null, record),
},
];
}
/**
* 查询
*/
function searchQuery() {
reload();
}
/**
* 重置
*/
function searchReset() {
formRef.value.resetFields();
selectedRowKeys.value = [];
//
reload();
}
function init(record) {
console.log('🧞', record);
queryParam.zybh = record.id;
reload();
}
defineExpose({
init,
});
</script>
<style lang="less" scoped>
.jeecg-basic-table-form-container {
padding: 0;
.table-page-search-submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
.query-group-cust{
min-width: 100px !important;
}
.query-group-split-cust{
width: 30px;
display: inline-block;
text-align: center
}
.ant-form-item:not(.ant-form-item-with-help){
margin-bottom: 16px;
height: 32px;
}
:deep(.ant-picker),:deep(.ant-input-number){
width: 100%;
}
.jeecg-basic-table-form-container {
padding: 0;
.table-page-search-submitButtons {
display: block;
margin-bottom: 24px;
white-space: nowrap;
}
.query-group-cust {
min-width: 100px !important;
}
.query-group-split-cust {
width: 30px;
display: inline-block;
text-align: center;
}
.ant-form-item:not(.ant-form-item-with-help) {
margin-bottom: 16px;
height: 32px;
}
:deep(.ant-picker),
:deep(.ant-input-number) {
width: 100%;
}
}
</style>