资源库:SFTP上传下载删除

This commit is contained in:
曹磊 2024-05-17 18:39:17 +08:00
parent 47a8f5c20d
commit 32ab35ac8d
19 changed files with 3350 additions and 19 deletions

View File

@ -92,6 +92,7 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码
filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码
filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token
filterChainDefinitionMap.put("/zyk/zykInfo/static/**", "anon");//图片预览 &下载文件不限制token
filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览
filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件
filterChainDefinitionMap.put("/wxpay/**", "anon");//微信接口

View File

@ -80,8 +80,11 @@
<artifactId>hutool-http</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -0,0 +1,193 @@
package org.jeecg.modules.zyk.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.SymbolConstant;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.zyk.entity.ZykInfo;
import org.jeecg.modules.zyk.service.IZykService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.HandlerMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
/**
* @Description: 资源库信息
* @Author: jeecg-boot
* @Date: 2024-05-16
* @Version: V1.0
*/
@Api(tags="资源库信息")
@RestController
@RequestMapping("/zyk/zykInfo")
@Slf4j
public class ZykController extends JeecgController<ZykInfo, IZykService> {
@Autowired
private IZykService zykService;
@AutoLog(value = "资源库信息-分页列表查询")
@ApiOperation(value="资源库信息-分页列表查询", notes="资源库信息-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<ZykInfo>> queryPageList(ZykInfo zykInfo,
@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
HttpServletRequest req) {
Page<ZykInfo> pageList = zykService.findPage(zykInfo,new Page<ZykInfo>(pageNo, pageSize));
return Result.OK(pageList);
}
@AutoLog(value = "资源库信息-添加")
@ApiOperation(value="资源库信息-添加", notes="资源库信息-添加")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody ZykInfo zykInfo) {
String res = zykService.saveInfo(zykInfo);
return Result.OK(res);
}
/**
* 编辑
* @param zykInfo
* @return
*/
@AutoLog(value = "资源库信息-编辑")
@ApiOperation(value="资源库信息-编辑", notes="资源库信息-编辑")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST})
public Result<String> edit(@RequestBody ZykInfo zykInfo) {
String res = zykService.modifyInfo(zykInfo);
return Result.OK(res);
}
/**
* 通过id删除
* @param id
* @return
*/
@AutoLog(value = "资源库信息-通过id删除")
@ApiOperation(value="资源库信息-通过id删除", notes="资源库信息-通过id删除")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name="id",required=true) String id) {
String res = zykService.removeById(id);
return Result.OK(res);
}
/**
* 批量删除
* @param ids
* @return
*/
@AutoLog(value = "资源库信息-批量删除")
@ApiOperation(value="资源库信息-批量删除", notes="资源库信息-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
String res = zykService.removeByIds(Arrays.asList(ids.split(",")));
return Result.OK(res);
}
/**
* 预览图片&下载文件
* 请求地址http://localhost:8080/common/static/{user/20190119/e1fe9925bc315c60addea1b98eb1cb1349547719_1547866868179.jpg}
* @param request
* @param response
*/
// @GetMapping(value = "/static/**")
// public void view(HttpServletRequest request, HttpServletResponse response) {
// // ISO-8859-1 ==> UTF-8 进行编码转换
// String filePath = extractPathFromPattern(request);
// if(oConvertUtils.isEmpty(filePath) || CommonConstant.STRING_NULL.equals(filePath)){
// return;
// }
// // 其余处理略
// InputStream inputStream = null;
// OutputStream outputStream = null;
// try {
// filePath = filePath.replace("..", "").replace("../","");
// if (filePath.endsWith(SymbolConstant.COMMA)) {
// filePath = filePath.substring(0, filePath.length() - 1);
// }
// Map<String,String> map = zykService.downloadRemoteFile(filePath);
// if(!map.get("code").equals("0")){
// throw new RuntimeException(map.get("msg"));
// }
// String localFilePath = map.get("data");
// File file = new File(localFilePath);
// if(!file.exists()){
// response.setStatus(404);
// throw new RuntimeException("文件["+filePath+"]不存在..");
// }
// // 设置强制下载不打开
// 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 (IOException e) {
// log.error("预览文件失败" + e.getMessage());
// response.setStatus(404);
// e.printStackTrace();
// } finally {
// if (inputStream != null) {
// try {
// inputStream.close();
// } catch (IOException e) {
// log.error(e.getMessage(), e);
// }
// }
// if (outputStream != null) {
// try {
// outputStream.close();
// } catch (IOException e) {
// log.error(e.getMessage(), e);
// }
// }
// }
// }
@GetMapping(value = "/static/**")
public void view(HttpServletRequest request, HttpServletResponse response) {
// ISO-8859-1 ==> UTF-8 进行编码转换
String filePath = extractPathFromPattern(request);
if(oConvertUtils.isEmpty(filePath) || CommonConstant.STRING_NULL.equals(filePath)){
return;
}
try {
filePath = filePath.replace("..", "").replace("../","");
if (filePath.endsWith(SymbolConstant.COMMA)) {
filePath = filePath.substring(0, filePath.length() - 1);
}
zykService.downloadRes(filePath,response);
} catch (Exception e) {
log.error("预览文件失败" + e.getMessage());
e.printStackTrace();
}
}
/**
* 把指定URL后的字符串全部截断当成参数
* 这么做是为了防止URL中包含中文或者特殊字符/匹配不了的问题
* @param request
* @return
*/
private static String extractPathFromPattern(final HttpServletRequest request) {
String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
}
}

View File

@ -0,0 +1,71 @@
package org.jeecg.modules.zyk.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.Date;
@Data
@ApiModel(value="zyk_info对象", description="资源库信息")
public class ZykInfo implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
@ApiModelProperty(value = "id")
private String id;
@ApiModelProperty(value = "创建人")
private String createBy;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间")
private Date createTime;
@ApiModelProperty(value = "修改人")
private String updateBy;
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "修改时间")
private Date updateTime;
/**业务ID*/
@ApiModelProperty(value = "业务ID")
private String bizId;
/**业务表*/
@ApiModelProperty(value = "业务表")
private String bizTable;
/**学期学年*/
@ApiModelProperty(value = "学期学年")
private String xqxn;
/**开课单位*/
@ApiModelProperty(value = "开课单位")
private String kkdw;
/**课程名称*/
@ApiModelProperty(value = "课程名称")
private String kcmc;
/**授课教师*/
@ApiModelProperty(value = "授课教师")
private String skjs;
/**文件类型*/
@ApiModelProperty(value = "文件类型")
private String wjlx;
/**文件名称*/
@ApiModelProperty(value = "文件名称")
private String fileName;
/**学号*/
@TableField(exist = false)
private String xh;
/**次*/
@TableField(exist = false)
private String seq;
/**章*/
@TableField(exist = false)
private String chapter;
/**节*/
@TableField(exist = false)
private String section;
}

View File

@ -0,0 +1,22 @@
package org.jeecg.modules.zyk.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Param;
import org.jeecg.modules.zyk.entity.ZykInfo;
import java.util.List;
/**
* @Description: 资源库信息
* @Author: jeecg-boot
* @Date: 2024-05-16
* @Version: V1.0
*/
public interface ZykMapper extends BaseMapper<ZykInfo> {
List<ZykInfo> findPage(Page<ZykInfo> page, ZykInfo params);
ZykInfo getById(@Param("id")String id);
void addInfo(ZykInfo zykInfo);
void modifyInfo(ZykInfo zykInfo);
ZykInfo getByBiz(ZykInfo zykInfo);
}

View File

@ -0,0 +1,162 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.jeecg.modules.zyk.mapper.ZykMapper">
<select id="findPage" parameterType="org.jeecg.modules.zyk.entity.ZykInfo" resultType="org.jeecg.modules.zyk.entity.ZykInfo">
select
id,
create_by,
create_time,
update_by,
update_time,
biz_id,
biz_table,
xqxn,
kkdw,
kcmc,
skjs,
wjlx,
file_name,
xh,
seq,
chapter,
section
from zyk_info a
<where>
<if test="params.createBy != null and params.createBy != ''">
AND create_by = #{params.createBy}
</if>
<if test="params.bizId != null and params.bizId != ''">
AND biz_id = #{params.bizId}
</if>
<if test="params.bizTable != null and params.bizTable != ''">
AND biz_table = #{params.bizTable}
</if>
<if test="params.xqxn != null and params.xqxn != ''">
AND xqxn = #{params.xqxn}
</if>
<if test="params.kkdw != null and params.kkdw != ''">
AND kkdw = #{params.kkdw}
</if>
<if test="params.skjs != null and params.skjs != ''">
AND skjs = #{params.skjs}
</if>
<if test="params.wjlx != null and params.wjlx != ''">
AND wjlx = #{params.wjlx}
</if>
<if test="params.xh != null and params.xh != ''">
AND xh = #{params.xh}
</if>
<if test="params.seq != null and params.seq != ''">
AND seq = #{params.seq}
</if>
<if test="params.chapter != null and params.chapter != ''">
AND chapter = #{params.chapter}
</if>
<if test="params.section != null and params.section != ''">
AND section = #{params.section}
</if>
</where>
order by create_time
</select>
<select id="getById" parameterType="String" resultType="org.jeecg.modules.zyk.entity.ZykInfo">
SELECT
id,
create_by,
create_time,
update_by,
update_time,
biz_id,
biz_table,
xqxn,
kkdw,
kcmc,
skjs,
wjlx,
file_name,
xh,
seq,
chapter,
section
FROM zyk_info
where id = #{id}
</select>
<insert id="addInfo" parameterType="org.jeecg.modules.zyk.entity.ZykInfo">
insert into zyk_info(
id,
create_by,
create_time,
biz_id,
biz_table,
xqxn,
kkdw,
kcmc,
skjs,
wjlx,
file_name,
xh,
seq,
chapter,
section
)
value(
#{id},
#{createBy},
#{createTime},
#{bizId},
#{bizTable},
#{xqxn},
#{kkdw},
#{kcmc},
#{skjs},
#{wjlx},
#{fileName},
#{xh},
#{seq},
#{chapter},
#{section}
)
</insert>
<update id="modifyInfo" parameterType="org.jeecg.modules.zyk.entity.ZykInfo">
update zyk_info
set
update_by = #{updateBy},
update_time = #{updateTime},
file_name = #{fileName}
where id = #{id}
</update>
<delete id="deleteById" parameterType="String">
delete from zyk_info where id = #{id}
</delete>
<select id="getByBiz" parameterType="org.jeecg.modules.zyk.entity.ZykInfo" resultType="org.jeecg.modules.zyk.entity.ZykInfo">
SELECT
id,
create_by,
create_time,
update_by,
update_time,
biz_id,
biz_table,
xqxn,
kkdw,
kcmc,
skjs,
wjlx,
file_name,
xh,
seq,
chapter,
section
FROM zyk_info
where biz_id = #{bizId}
<if test="bizTable != null and bizTable != ''">
AND biz_table = #{bizTable}
</if>
</select>
</mapper>

View File

@ -0,0 +1,56 @@
package org.jeecg.modules.zyk.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.zyk.entity.ZykInfo;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
/**
* @Description: 资源库信息
* @Author: jeecg-boot
* @Date: 2024-05-16
* @Version: V1.0
*/
public interface IZykService extends IService<ZykInfo> {
Page<ZykInfo> findPage(ZykInfo zykInfo, Page<ZykInfo> page);
String saveInfo(ZykInfo zykInfo);
String modifyInfo(ZykInfo zykInfo);
String removeById(String id);
String removeByIds(List<String> list);
/**
* 下载远端文件预留
* @param filePath
* @return 下载结果
*/
// Map<String,String> downloadRemoteFile(String filePath);
/**
* 下载远端文件流含接口
* @param filePath
*/
void downloadRes(String filePath, HttpServletResponse response) throws Exception;
/**
* 更新到资源库接口
* @param zykInfo
* @return 上传结果
*/
Map<String,String> saveToZyk(ZykInfo zykInfo);
/**
* 删除资源库接口
* @param zykInfo
* @return 上传结果
*/
Map<String,String> deleteZyk(ZykInfo zykInfo);
}

View File

@ -0,0 +1,208 @@
package org.jeecg.modules.zyk.service.impl;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.zyk.entity.ZykInfo;
import org.jeecg.modules.zyk.mapper.ZykMapper;
import org.jeecg.modules.zyk.service.IZykService;
import org.jeecg.modules.zyk.utils.util.FileHandleUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description: 资源库信息
* @Author: jeecg-boot
* @Date: 2024-05-16
* @Version: V1.0
*/
@Service
public class ZykServiceImpl extends ServiceImpl<ZykMapper, ZykInfo> implements IZykService {
@Autowired
private FileHandleUtil fileHandleUtil;
@Autowired
private ZykMapper zykMapper;
@Override
public Page<ZykInfo> findPage(ZykInfo zykInfo, Page<ZykInfo> page){
List<ZykInfo> list = zykMapper.findPage(page,zykInfo);
page.setRecords(list);
return page;
}
@Override
public String saveInfo(ZykInfo zykInfo){
Map<String,String> map = fileHandleUtil.uploadFile(zykInfo);
if(!map.get("code").equals("0")){
return map.get("msg");
}
zykInfo.setFileName(map.get("data"));
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
zykInfo.setCreateBy(user.getUsername());
zykInfo.setCreateTime(new Date());
Long id = new DefaultIdentifierGenerator().nextId(new ZykInfo());
zykInfo.setId(id.toString());
zykMapper.addInfo(zykInfo);
return "添加成功!";
}
@Override
public String modifyInfo(ZykInfo zykInfo){
Map<String,String> map = fileHandleUtil.uploadFile(zykInfo);
if(!map.get("code").equals("0")){
return map.get("msg");
}
zykInfo.setFileName(map.get("data"));
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
zykInfo.setUpdateBy(user.getUsername());
zykInfo.setUpdateTime(new Date());
zykMapper.modifyInfo(zykInfo);
return "编辑成功!";
}
@Override
public String removeById(String id){
ZykInfo zykInfo = zykMapper.getById(id);
if(zykInfo.getFileName() != null && !zykInfo.getFileName().equals("")){
String[] df = fileHandleUtil.getDirectoryAndFileName(zykInfo.getFileName());
if(!df[0].equals("")&&!df[1].equals("")){
fileHandleUtil.delete(df[0],df[1]);
}
}
zykMapper.deleteById(id);
return "删除成功!";
}
@Override
public String removeByIds(List<String> list){
for(int i=0;i<list.size();i++){
String id = list.get(i);
ZykInfo zykInfo = zykMapper.getById(id);
if(zykInfo.getFileName() != null && !zykInfo.getFileName().equals("")){
String[] df = fileHandleUtil.getDirectoryAndFileName(zykInfo.getFileName());
if(!df[0].equals("")&&!df[1].equals("")){
fileHandleUtil.delete(df[0],df[1]);
}
}
zykMapper.deleteById(id);
}
return "批量删除成功!";
}
/**
* 文件下载预留
* @param filePath
* @return 下载结果
*/
// @Override
// public Map<String,String> downloadRemoteFile(String filePath){
// Map<String,String> map = new HashMap<String,String>();
// map.put("code","0");
// if(filePath == null || filePath.equals("")){
// map.put("code","1");
// map.put("msg","文件路径不能为空!");
// }
// if(filePath.lastIndexOf("/")==-1){
// map.put("code","1");
// map.put("msg","文件路径不存在!");
// }
// String[] df = fileHandleUtil.getDirectoryAndFileName(filePath);
// if(df[0].equals("")){
// map.put("code","1");
// map.put("msg","文件路径不存在!");
// }
// if(df[1].equals("")){
// map.put("code","1");
// map.put("msg","文件不存在!");
// }
// Map<String,String> downloadMap = fileHandleUtil.download(df[0],df[1]);
// if(!downloadMap.get("code").equals("0")){
// return downloadMap;
// }
// map.put("data",downloadMap.get("fileName"));
// return map;
// }
/**
* 下载远端文件流含接口
* @param filePath
*/
@Override
public void downloadRes(String filePath, HttpServletResponse response) throws Exception {
if(filePath == null || filePath.equals("")){
throw new RuntimeException("文件["+filePath+"]不存在!");
}
if(filePath.lastIndexOf("/")==-1){
throw new RuntimeException("文件路径不存在!");
}
String[] df = fileHandleUtil.getDirectoryAndFileName(filePath);
if(df[0].equals("")){
throw new RuntimeException("文件路径不存在!");
}
if(df[1].equals("")){
throw new RuntimeException("文件不存在!");
}
fileHandleUtil.downloadRes(df[0],df[1],response);
}
/**
* 更新到资源库接口
* @param zykInfo
* @return 上传结果
*/
@Override
public Map<String,String> saveToZyk(ZykInfo zykInfo){
Map<String,String> map = fileHandleUtil.uploadFile(zykInfo);
if(!map.get("code").equals("0")){
return map;
}
zykInfo.setFileName(map.get("data"));
ZykInfo entity = zykMapper.getByBiz(zykInfo);
LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
if(entity!=null){
zykInfo.setUpdateBy(user.getUsername());
zykInfo.setUpdateTime(new Date());
zykInfo.setId(entity.getId());
zykMapper.modifyInfo(zykInfo);
}else{
zykInfo.setCreateBy(user.getUsername());
zykInfo.setCreateTime(new Date());
Long id = new DefaultIdentifierGenerator().nextId(new ZykInfo());
zykInfo.setId(id.toString());
zykMapper.addInfo(zykInfo);
}
return map;
}
/**
* 删除资源库接口
* @param zykInfo
* @return 上传结果
*/
@Override
public Map<String,String> deleteZyk(ZykInfo zykInfo){
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
ZykInfo entity = zykMapper.getByBiz(zykInfo);
if(entity.getFileName() != null && !entity.getFileName().equals("")){
String[] df = fileHandleUtil.getDirectoryAndFileName(entity.getFileName());
if(!df[0].equals("")&&!df[1].equals("")){
fileHandleUtil.delete(df[0],df[1]);
}
}
zykMapper.deleteById(entity.getId());
map.put("msg","删除成功!");
return map;
}
}

View File

@ -0,0 +1,399 @@
package org.jeecg.modules.zyk.utils.sftp;
import com.jcraft.jsch.*;
import java.io.*;
import org.jeecg.common.util.CommonUtils;
import org.jeecg.modules.zyk.utils.text.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;
@Service
public class SFTPUtil {
private long count = 3;
private long count1 = 0;
private long sleepTime = 300000;//5分钟
private static final Logger logger = LoggerFactory.getLogger(SFTPUtil.class);
@Autowired
private SftpConfig sftpConfig;
public ChannelSftp connect(){
ChannelSftp sftp = null;
try {
JSch jsch = new JSch();
Session 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 ...");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
logger.info("登录成功");
} catch (Exception e){
try{
count1 += 1;
if(count == count1){
throw new RuntimeException(e);
}
Thread.sleep(sleepTime);
logger.info("重新连接....");
connect();
} catch (InterruptedException e1){
throw new RuntimeException(e1);
}
}
return sftp;
}
private void mkdirs(String directory,ChannelSftp sftp) 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);
}
}
}
}
/**
* 上传文件
* @param directory 上传的目录
* @param uploadFilePath 要上传的文件路径文件真实路径+名称
* @param uploadFileName 要上传的文件名称重新定义的文件名称
* @param
*/
public Map<String,String> upload(String directory, String uploadFilePath, String uploadFileName) {
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
map.put("msg","上传成功");
ChannelSftp sftp = null;
try{
sftp = connect();
try {
directory = getDirectory(directory);
sftp.cd(directory);
} catch (SftpException e1) {
try {
mkdirs(directory,sftp);
// 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());
}finally {
if(sftp!=null){
disConnect(sftp);
}
}
return map;
}
/**
* 下载文件
*
* @param directory 下载目录
* @param downloadFile 下载的文件
* @param saveFile 存在本地的路径
*/
public Map<String,String> download(String directory, String downloadFile, String saveFile) {
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
map.put("msg","删除成功");
ChannelSftp sftp = null;
try{
sftp = connect();
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(downloadFile, 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());
}finally {
if(sftp!=null){
disConnect(sftp);
}
}
return map;
}
/**
* 网页下载文件
* @param response
* @param directory
* @param downloadFile
* @throws Exception
*/
public void writeFileToRes(String directory, String downloadFile,HttpServletResponse response) throws Exception {
ChannelSftp sftp = null;
try{
sftp = connect();
InputStream inputStream = null;
ServletOutputStream outputStream=null;
try {
sftp.cd(directory);
inputStream = sftp.get(downloadFile);
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 (SftpException e1) {
e1.printStackTrace();
throw new Exception(StringUtils.format("sftp exception,sftp exception。 ", e1.getMessage()));
} catch (IOException e2) {
// e2.printStackTrace();
// throw new Exception(StringUtils.format("io exception,io exception 。 ", e2.getMessage()));
}finally {
closeStream(null,outputStream);
try {
if(inputStream!=null) {
inputStream.close();
}
} catch (IOException e3) {
e3.printStackTrace();
}
}
}catch (Exception e) {
e.printStackTrace();
throw new Exception(StringUtils.format("sftp exception,sftp exception。 ", e.getMessage()));
}finally {
if(sftp!=null){
disConnect(sftp);
}
}
}
/**
* 删除文件
* @param directory 要删除文件所在目录
* @param deleteFile 要删除的文件
*/
public Map<String,String> delete(String directory, String deleteFile) {
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
map.put("msg","删除成功");
ChannelSftp sftp = null;
try{
sftp = connect();
directory = delDiagonalLines(directory);
sftp.cd(directory);
sftp.rm(deleteFile);
}catch (Exception e) {
map.put("code","1");
map.put("msg","sftp异常" + e.getMessage());
}finally {
if(sftp!=null){
disConnect(sftp);
}
}
return map;
}
private String getDirectory(String directory){
String rootPath = sftpConfig.getUploadpath();
if(rootPath.endsWith("/")){
return sftpConfig.getUploadpath() + directory;
}else{
return sftpConfig.getUploadpath() +"/"+ directory;
}
}
private String delDiagonalLines(String directory){
if(directory.startsWith("/")){
directory = directory.substring(directory.indexOf("/")+1);
delDiagonalLines(directory);
}
return directory;
}
/**
* 断掉连接
*/
public void disConnect(ChannelSftp sftp) {
try {
sftp.disconnect();
sftp.getSession().disconnect();
} catch (Exception e) {
e.printStackTrace();
}
}
public SFTPUtil(long count, long sleepTime) {
this.count = count;
this.sleepTime = sleepTime;
}
public SFTPUtil() {
}
/**
* 关闭流
* @param outputStream
*/
private void closeStream(InputStream inputStream,OutputStream outputStream) {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(inputStream != null){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/*****************以下为预留方法*******************/
// /**
// * 下载远程文件夹下的所有文件
// * @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;
// }
}

View File

@ -0,0 +1,28 @@
package org.jeecg.modules.zyk.utils.sftp;
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;
public SftpConfig(String hostname,Integer port,String username,String password,Integer timeout,String uploadpath){
this.hostname = hostname;
this.port = port;
this.username = username;
this.password = password;
this.timeout = timeout;
this.uploadpath = uploadpath;
}
public SftpConfig(){}
}

View File

@ -0,0 +1,85 @@
package org.jeecg.modules.zyk.utils.text;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
/**
* 字符集工具类
*
* @author ruoyi
*/
public class CharsetKit
{
/** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */
public static final String UTF_8 = "UTF-8";
/** GBK */
public static final String GBK = "GBK";
/** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
* 转换为Charset对象
*
* @param charset 字符集为空则返回默认字符集
* @return Charset
*/
public static Charset charset(String charset)
{
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, String srcCharset, String destCharset)
{
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, Charset srcCharset, Charset destCharset)
{
if (null == srcCharset)
{
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset)
{
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
}
/**
* @return 系统字符集编码
*/
public static String systemCharset()
{
return Charset.defaultCharset().name();
}
}

View File

@ -0,0 +1,115 @@
package org.jeecg.modules.zyk.utils.text;
/**
* 通用常量信息
*
* @author ruoyi
*/
public class Constants
{
/**
* UTF-8 字符集
*/
public static final String UTF8 = "UTF-8";
/**
* GBK 字符集
*/
public static final String GBK = "GBK";
/**
* http请求
*/
public static final String HTTP = "http://";
/**
* https请求
*/
public static final String HTTPS = "https://";
/**
* 通用成功标识
*/
public static final String SUCCESS = "0";
/**
* 通用失败标识
*/
public static final String FAIL = "1";
/**
* 登录成功
*/
public static final String LOGIN_SUCCESS = "Success";
/**
* 注销
*/
public static final String LOGOUT = "Logout";
/**
* 注册
*/
public static final String REGISTER = "Register";
/**
* 登录失败
*/
public static final String LOGIN_FAIL = "Error";
/**
* 系统用户授权缓存
*/
public static final String SYS_AUTH_CACHE = "sys-authCache";
/**
* 参数管理 cache name
*/
public static final String SYS_CONFIG_CACHE = "sys-config";
/**
* 参数管理 cache key
*/
public static final String SYS_CONFIG_KEY = "sys_config:";
/**
* 字典管理 cache name
*/
public static final String SYS_DICT_CACHE = "sys-dict";
/**
* 字典管理 cache key
*/
public static final String SYS_DICT_KEY = "sys_dict:";
/**
* 资源映射路径 前缀
*/
public static final String RESOURCE_PREFIX = "/profile";
/**
* RMI 远程方法调用
*/
public static final String LOOKUP_RMI = "rmi:";
/**
* LDAP 远程方法调用
*/
public static final String LOOKUP_LDAP = "ldap:";
/**
* LDAPS 远程方法调用
*/
public static final String LOOKUP_LDAPS = "ldaps:";
/**
* 定时任务白名单配置仅允许访问的包名如其他需要可以自行添加
*/
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" };
/**
* 定时任务违规的字符
*/
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" };
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
package org.jeecg.modules.zyk.utils.text;
/**
* 字符串格式化
*
* @author ruoyi
*/
public class StrFormatter
{
public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}';
/**
* 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* <br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern 字符串模板
* @param argArray 参数列表
* @return 结果
*/
public static String format(final String strPattern, final Object... argArray)
{
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
{
return strPattern;
}
final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1)
{
if (handledPosition == 0)
{
return strPattern;
}
else
{ // 字符串模板剩余部分不再包含占位符加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
}
else
{
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{
// 转义符之前还有一个转义符占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
else
{
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
}
else
{
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2;
}
}
}
// 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}

View File

@ -0,0 +1,624 @@
package org.jeecg.modules.zyk.utils.text;
import org.springframework.util.AntPathMatcher;
import java.util.*;
/**
* 字符串工具类
*
* @author ruoyi
*/
public class StringUtils extends org.apache.commons.lang3.StringUtils
{
/** 空字符串 */
private static final String NULLSTR = "";
/** 下划线 */
private static final char SEPARATOR = '_';
/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public static <T> T nvl(T value, T defaultValue)
{
return value != null ? value : defaultValue;
}
/**
* * 判断一个Collection是否为空 包含ListSetQueue
*
* @param coll 要判断的Collection
* @return true为空 false非空
*/
public static boolean isEmpty(Collection<?> coll)
{
return isNull(coll) || coll.isEmpty();
}
/**
* * 判断一个Collection是否非空包含ListSetQueue
*
* @param coll 要判断的Collection
* @return true非空 false
*/
public static boolean isNotEmpty(Collection<?> coll)
{
return !isEmpty(coll);
}
/**
* * 判断一个对象数组是否为空
*
* @param objects 要判断的对象数组
** @return true为空 false非空
*/
public static boolean isEmpty(Object[] objects)
{
return isNull(objects) || (objects.length == 0);
}
/**
* * 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true非空 false
*/
public static boolean isNotEmpty(Object[] objects)
{
return !isEmpty(objects);
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true为空 false非空
*/
public static boolean isEmpty(Map<?, ?> map)
{
return isNull(map) || map.isEmpty();
}
/**
* * 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true非空 false
*/
public static boolean isNotEmpty(Map<?, ?> map)
{
return !isEmpty(map);
}
/**
* * 判断一个字符串是否为空串
*
* @param str String
* @return true为空 false非空
*/
public static boolean isEmpty(String str)
{
return isNull(str) || NULLSTR.equals(str.trim());
}
/**
* * 判断一个字符串是否为非空串
*
* @param str String
* @return true非空串 false空串
*/
public static boolean isNotEmpty(String str)
{
return !isEmpty(str);
}
/**
* * 判断一个对象是否为空
*
* @param object Object
* @return true为空 false非空
*/
public static boolean isNull(Object object)
{
return object == null;
}
/**
* * 判断一个对象是否非空
*
* @param object Object
* @return true非空 false
*/
public static boolean isNotNull(Object object)
{
return !isNull(object);
}
/**
* * 判断一个对象是否是数组类型Java基本型别的数组
*
* @param object 对象
* @return true是数组 false不是数组
*/
public static boolean isArray(Object object)
{
return isNotNull(object) && object.getClass().isArray();
}
/**
* 去空格
*/
public static String trim(String str)
{
return (str == null ? "" : str.trim());
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public static String substring(final String str, int start)
{
if (str == null)
{
return NULLSTR;
}
if (start < 0)
{
start = str.length() + start;
}
if (start < 0)
{
start = 0;
}
if (start > str.length())
{
return NULLSTR;
}
return str.substring(start);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public static String substring(final String str, int start, int end)
{
if (str == null)
{
return NULLSTR;
}
if (end < 0)
{
end = str.length() + end;
}
if (start < 0)
{
start = str.length() + start;
}
if (end > str.length())
{
end = str.length();
}
if (start > end)
{
return NULLSTR;
}
if (start < 0)
{
start = 0;
}
if (end < 0)
{
end = 0;
}
return str.substring(start, end);
}
/**
* 格式化文本, {} 表示占位符<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* <br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param template 文本模板被替换的部分用 {} 表示
* @param params 参数值
* @return 格式化后的文本
*/
public static String format(String template, Object... params)
{
if (isEmpty(params) || isEmpty(template))
{
return template;
}
return StrFormatter.format(template, params);
}
/**
* 是否为http(s)://开头
*
* @param link 链接
* @return 结果
*/
public static boolean ishttp(String link)
{
return StringUtils.startsWithAny(link, Constants.HTTP, Constants.HTTPS);
}
/**
* 字符串转set
*
* @param str 字符串
* @param sep 分隔符
* @return set集合
*/
public static final Set<String> str2Set(String str, String sep)
{
return new HashSet<String>(str2List(str, sep, true, false));
}
/**
* 字符串转list
*
* @param str 字符串
* @param sep 分隔符
* @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白
* @return list集合
*/
public static final List<String> str2List(String str, String sep, boolean filterBlank, boolean trim)
{
List<String> list = new ArrayList<String>();
if (StringUtils.isEmpty(str))
{
return list;
}
// 过滤空白字符串
if (filterBlank && StringUtils.isBlank(str))
{
return list;
}
String[] split = str.split(sep);
for (String string : split)
{
if (filterBlank && StringUtils.isBlank(string))
{
continue;
}
if (trim)
{
string = string.trim();
}
list.add(string);
}
return list;
}
/**
* 判断给定的set列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
*
* @param set 给定的集合
* @param array 给定的数组
* @return boolean 结果
*/
public static boolean containsAny(Collection<String> collection, String... array)
{
if (isEmpty(collection) || isEmpty(array))
{
return false;
}
else
{
for (String str : array)
{
if (collection.contains(str))
{
return true;
}
}
return false;
}
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*
* @param cs 指定字符串
* @param searchCharSequences 需要检查的字符串数组
* @return 是否包含任意一个字符串
*/
public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences)
{
if (isEmpty(cs) || isEmpty(searchCharSequences))
{
return false;
}
for (CharSequence testStr : searchCharSequences)
{
if (containsIgnoreCase(cs, testStr))
{
return true;
}
}
return false;
}
/**
* 驼峰转下划线命名
*/
public static String toUnderScoreCase(String str)
{
if (str == null)
{
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean curreCharIsUpperCase = true;
// 下一字符是否大写
boolean nexteCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if (i > 0)
{
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
}
else
{
preCharIsUpperCase = false;
}
curreCharIsUpperCase = Character.isUpperCase(c);
if (i < (str.length() - 1))
{
nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}
if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
{
sb.append(SEPARATOR);
}
else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
{
sb.append(SEPARATOR);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 是否包含字符串
*
* @param str 验证字符串
* @param strs 字符串组
* @return 包含返回true
*/
public static boolean inStringIgnoreCase(String str, String... strs)
{
if (str != null && strs != null)
{
for (String s : strs)
{
if (str.equalsIgnoreCase(trim(s)))
{
return true;
}
}
}
return false;
}
/**
* 删除最后一个字符串
*
* @param str 输入字符串
* @param spit 以什么类型结尾的
* @return 截取后的字符串
*/
public static String lastStringDel(String str, String spit)
{
if (!StringUtils.isEmpty(str) && str.endsWith(spit))
{
return str.subSequence(0, str.length() - 1).toString();
}
return str;
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式如果转换前的下划线大写方式命名的字符串为空则返回空字符串 例如HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String convertToCamelCase(String name)
{
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty())
{
// 没必要转换
return "";
}
else if (!name.contains("_"))
{
// 不含下划线仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels)
{
// 跳过原始字符串中开头结尾的下换线或双重下划线
if (camel.isEmpty())
{
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}
/**
* 驼峰式命名法
* 例如user_name->userName
*/
public static String toCamelCase(String s)
{
if (s == null)
{
return null;
}
if (s.indexOf(SEPARATOR) == -1)
{
return s;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c == SEPARATOR)
{
upperCase = true;
}
else if (upperCase)
{
sb.append(Character.toUpperCase(c));
upperCase = false;
}
else
{
sb.append(c);
}
}
return sb.toString();
}
/**
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
*
* @param str 指定字符串
* @param strs 需要检查的字符串数组
* @return 是否匹配
*/
public static boolean matches(String str, List<String> strs)
{
if (isEmpty(str) || isEmpty(strs))
{
return false;
}
for (String pattern : strs)
{
if (isMatch(pattern, str))
{
return true;
}
}
return false;
}
/**
* 判断url是否与规则配置:
* ? 表示单个字符;
* * 表示一层路径内的任意字符串不可跨层级;
* ** 表示任意层路径;
*
* @param pattern 匹配规则
* @param url 需要匹配的url
* @return
*/
public static boolean isMatch(String pattern, String url)
{
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
@SuppressWarnings("unchecked")
public static <T> T cast(Object obj)
{
return (T) obj;
}
/**
* 数字左边补齐0使之达到指定长度注意如果数字转换为字符串后长度大于size则只保留 最后size个字符
*
* @param num 数字对象
* @param size 字符串指定长度
* @return 返回数字的字符串格式该字符串为指定长度
*/
public static final String padl(final Number num, final int size)
{
return padl(num.toString(), size, '0');
}
/**
* 字符串左补齐如果原始字符串s长度大于size则只保留最后size个字符
*
* @param s 原始字符串
* @param size 字符串指定长度
* @param c 用于补齐的字符
* @return 返回指定长度的字符串由原字符串左补齐或截取得到
*/
public static final String padl(final String s, final int size, final char c)
{
final StringBuilder sb = new StringBuilder(size);
if (s != null)
{
final int len = s.length();
if (s.length() <= size)
{
for (int i = size - len; i > 0; i--)
{
sb.append(c);
}
sb.append(s);
}
else
{
return s.substring(len - size, len);
}
}
else
{
for (int i = size; i > 0; i--)
{
sb.append(c);
}
}
return sb.toString();
}
}

View File

@ -0,0 +1,212 @@
package org.jeecg.modules.zyk.utils.util;
import org.jeecg.modules.zyk.entity.ZykInfo;
import org.jeecg.modules.zyk.utils.sftp.SFTPUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
@Service
public class FileHandleUtil {
@Autowired
private SFTPUtil sftpUtil;
@Value(value = "${jeecg.path.upload}")
private String uploadpath;
@Value(value = "${jeecg.path.webapp}")
private String downloadpath;
public Map<String,String> uploadFile(ZykInfo zykInfo){
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
Map<String,String> directoryMap = getDirectory(zykInfo);
if(!directoryMap.get("code").equals("0")){
return directoryMap;
}
//资源库文件路径
String directory = directoryMap.get("directory");
//源文件路径
Map<String,String> fileNameMap = getFileName(zykInfo);
if(!fileNameMap.get("code").equals("0")){
return fileNameMap;
}
//上传文件
Map<String,String> uploadMap = sftpUtil.upload(directory,fileNameMap.get("filePath"),fileNameMap.get("fileName"));
if(!uploadMap.get("code").equals("0")){
return uploadMap;
}
map.put("data",uploadMap.get("data"));
return map;
}
public 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;
}
public Map<String,String> download(String directory, String downloadFile){
return sftpUtil.download(directory,downloadFile,getDownloadPath("temp"));
}
public void downloadRes(String directory, String downloadFile,HttpServletResponse response) throws Exception{
sftpUtil.writeFileToRes(directory,downloadFile,response);
}
public void delete(String directory, String downloadFile){
sftpUtil.delete(directory,downloadFile);
}
/**
* 资源库文件路径
* @param zykInfo
* @return
*/
private Map<String,String> getDirectory(ZykInfo zykInfo){
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
StringBuffer sb = new StringBuffer();
if(zykInfo.getXqxn()==null || zykInfo.getXqxn().equals("")){
map.put("code","1");
map.put("msg","学期学年不能为空!");
return map;
}
sb.append(zykInfo.getXqxn());
sb.append("/");
if(zykInfo.getKkdw()==null || zykInfo.getKkdw().equals("")){
map.put("code","1");
map.put("msg","开课单位不能为空!");
return map;
}
sb.append(zykInfo.getKkdw());
sb.append("/");
if(zykInfo.getKcmc()==null || zykInfo.getKcmc().equals("")){
map.put("code","1");
map.put("msg","课程名称不能为空!");
return map;
}
sb.append(zykInfo.getKcmc());
sb.append("/");
if(zykInfo.getSkjs()==null || zykInfo.getSkjs().equals("")){
map.put("code","1");
map.put("msg","授课教师不能为空!");
return map;
}
sb.append(zykInfo.getSkjs());
sb.append("/");
if(zykInfo.getWjlx()==null || zykInfo.getWjlx().equals("")){
map.put("code","1");
map.put("msg","文件类型不能为空!");
return map;
}
sb.append(zykInfo.getWjlx());
sb.append("/");
map.put("directory",sb.toString());
return map;
}
/**
* 获取文件路径和新文件名称
* @param zykInfo
* @return
*/
private Map<String,String> getFileName(ZykInfo zykInfo){
Map<String,String> map = new HashMap<String,String>();
map.put("code","0");
String uploadFileName = getRealFileFullPath(zykInfo.getFileName());
if(uploadFileName.equals("")){
map.put("code","1");
map.put("msg","文件路径不能为空!");
return map;
}
File file = new File(uploadFileName);
if(!file.exists()){
map.put("code","1");
map.put("msg","文件["+zykInfo.getFileName()+"]不存在..");
return map;
}
map.put("filePath",uploadFileName);
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf('/')+1, uploadFileName.indexOf("_"));
String suffix = uploadFileName.substring(uploadFileName.lastIndexOf("."));
fileName = fileName + suffix;
if(zykInfo.getWjlx().equals(WjlxEnum.JXDG.getType())){
String kcmc = zykInfo.getKcmc();
fileName = kcmc+"_"+WjlxEnum.JXDG.getType()+suffix;
}
if(zykInfo.getWjlx().equals(WjlxEnum.JXRL.getType())){
String kcmc = zykInfo.getKcmc();
fileName = kcmc+"_"+WjlxEnum.JXRL.getType()+suffix;
}
if(zykInfo.getWjlx().equals(WjlxEnum.KCLW.getType())){
String kcmc = zykInfo.getKcmc();
fileName = kcmc+"_要求"+suffix;
}
if(zykInfo.getWjlx().equals(WjlxEnum.XSLW.getType())){
String kcmc = zykInfo.getKcmc();
String xh = zykInfo.getXh();
String seq = zykInfo.getSeq();
fileName = kcmc+"_"+xh+"_"+seq+suffix;
}
if(zykInfo.getWjlx().equals(WjlxEnum.JXDY.getType())){
String kcmc = zykInfo.getKcmc();
String chapter = zykInfo.getChapter();
String section = zykInfo.getSection();
fileName = kcmc+"_第"+chapter+"章_第"+section+""+suffix;
}
if(zykInfo.getWjlx().equals(WjlxEnum.QT.getType())){
String kcmc = zykInfo.getKcmc();
fileName = kcmc+"_其他_"+fileName;
}
map.put("fileName",fileName);
return map;
}
/**
* 获取文件真实路径
* @param path
* @return
*/
private String getRealFileFullPath(String path){
String filePath = "";
if(path==null || path.equals("")){
return "";
}
path = path.replace("\\", "/");
int idx = path.indexOf(uploadpath);
if(idx==-1){
filePath = uploadpath + File.separator + path;
}else{
filePath = path;
}
return filePath;
}
/**
* 获取文件真实路径
* @param path
* @return
*/
private String getDownloadPath(String path){
String filePath = "";
if(path==null || path.equals("")){
return "";
}
int idx = path.indexOf(downloadpath);
if(idx==-1){
filePath = downloadpath + File.separator + path;
}else{
filePath = path;
}
return filePath;
}
}

View File

@ -0,0 +1,55 @@
package org.jeecg.modules.zyk.utils.util;
import org.apache.commons.lang3.StringUtils;
/**
* @Description: 文件类型枚举类
* @author: jeecg-boot
*/
public enum WjlxEnum {
/**教学大纲*/
JXDG("教学大纲"),
/**教学日历*/
JXRL("教学日历"),
/**课程论文*/
KCLW("课程论文"),
/**课程论文*/
XSLW("学生论文"),
/**教学单元*/
JXDY("教学单元"),
/**其他*/
QT("其他");
/**
* 类型
*/
private String type;
WjlxEnum(){}
WjlxEnum(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public static WjlxEnum toEnum(String type) {
if(StringUtils.isEmpty(type)){
return null;
}
for(WjlxEnum item : WjlxEnum.values()) {
if(item.getType().equals(type)) {
return item;
}
}
return null;
}
}

View File

@ -332,17 +332,16 @@ ffmpeg:
weipu:
userId: 765996
userKey: 330ed91f6c7e4600a454a6a5216723bf
#SFTP
#sftp:
# hostname: 210.47.29.18
# port: 22
# uername: nenujwc18
# password: hFvxJG%yRNZQ
# timeout: 1000
# uploadpath: /
#问卷星
wjx:
appid: 1321039
appkey: 55328ebd11964fc8b40c10011bcb425d
url: https://www.wjx.cn/openapi/default.aspx
url: https://www.wjx.cn/openapi/default.aspx
#SFTP
sftp:
hostname: 192.168.2.200
port: 22
username: sftp
password: sftp
timeout: 1000
uploadpath: /kczx

View File

@ -133,15 +133,15 @@ spring:
master:
url: jdbc:mysql://127.0.0.1:3306/course_information_center_jeecg_db?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai
username: root
# password: root
password: ABCabc@123
# password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# 多数据源配置
multi-oracle:
url: jdbc:oracle:thin:@202.198.129.24:1521:orcl
username: C##XSKC
password: mAPP2t2ABAfx7
driver-class-name: oracle.jdbc.OracleDriver
# multi-oracle:
# url: jdbc:oracle:thin:@202.198.129.24:1521:orcl
# username: C##XSKC
# password: mAPP2t2ABAfx7
# driver-class-name: oracle.jdbc.OracleDriver
#redis 配置
redis:
database: 0
@ -343,4 +343,12 @@ weipu:
wjx:
appid: 1321039
appkey: 55328ebd11964fc8b40c10011bcb425d
url: https://www.wjx.cn/openapi/default.aspx
url: https://www.wjx.cn/openapi/default.aspx
#SFTP
sftp:
hostname: 192.168.2.200
port: 22
username: sftp
password: sftp
timeout: 1000
uploadpath: /kczx