Преглед на файлове

添加附件接口类

master
zhangyulong преди 2 години
родител
ревизия
18467fa05b
променени са 28 файла, в които са добавени 5015 реда и са изтрити 7 реда
  1. +36
    -4
      smtweb-framework/bpm/pom.xml
  2. +38
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfigProperties.java
  3. +427
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/AttachController.java
  4. +71
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dataCacheInit/AttachFolderEntityBuffer.java
  5. +102
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFileWork.java
  6. +222
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFtpWork.java
  7. +283
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachHelper.java
  8. +135
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachUtil.java
  9. +28
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/IAttachTraceIntf.java
  10. +115
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/IAttachWorkIntf.java
  11. +27
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/initPlugin/RunDataInit.java
  12. +135
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilDownloadFile.java
  13. +1178
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilFile.java
  14. +66
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilLogger.java
  15. +465
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilMath.java
  16. +504
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilString.java
  17. +6
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpTask.java
  18. +255
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpTaskManager.java
  19. +393
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpUtil.java
  20. +6
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IDownloadFileWorker.java
  21. +16
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpServerConfig.java
  22. +59
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpUtil.java
  23. +396
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/SFtpUtil.java
  24. +13
    -3
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/attach/AttachInfo.java
  25. +16
    -0
      smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/attachFolder/pojo/AttachFolderPojo.java
  26. +16
    -0
      smtweb-framework/bpm/src/main/resources/config/application.yaml
  27. +6
    -0
      smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java
  28. +1
    -0
      smtweb-framework/pom.xml

+ 36
- 4
smtweb-framework/bpm/pom.xml Целия файл

@@ -129,6 +129,38 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.6</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.53</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
</dependencies>

<build>
@@ -176,22 +208,22 @@
<resources>
<!-- 界面设计器 -->
<resource>
<directory>E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-ui-design-vue/dist/</directory>
<directory>E:/jujia/source/sw-ui-design-vue/dist/</directory>
<targetPath>${basedir}/target/classes/static/design/ui</targetPath>
</resource>
<!-- DB设计器 -->
<resource>
<directory>E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-db-design-vue/dist/</directory>
<directory>E:/jujia/source/sw-db-design-vue/dist/</directory>
<targetPath>${basedir}/target/classes/static/design/db</targetPath>
</resource>
<!-- 流程设计器 -->
<resource>
<directory>E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-flow-design-vue/dist/</directory>
<directory>E:/jujia/source/sw-flow-design-vue/dist/</directory>
<targetPath>${basedir}/target/classes/static/design/flow</targetPath>
</resource>
<!-- 预览脚手架 -->
<resource>
<directory>E:/WORKSPACE/JJKJ-GIT/CODE/smtweb/sw-framework-widget-vue/dist/</directory>
<directory>E:/jujia/source/sw-framework-widget-vue/dist/</directory>
<targetPath>${basedir}/target/classes/static/design/preview</targetPath>
</resource>
<!-- 设定主资源目录,入口跳转页等 -->


+ 38
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/config/FileConfigProperties.java Целия файл

@@ -0,0 +1,38 @@
package cc.smtweb.system.bpm.spring.config;

import cc.smtweb.framework.core.util.JsonUtil;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "smtweb.file")
public class FileConfigProperties {

/**
* 系统底层附件保存路径和访问路径
*/
private String localPath;
private String url;

/**
* 自建的附件上传路径和访问路径,支持ftp
*/
private String attachTempPath;//临时文件保存路径
private String attachPath;//保存路径
private String attachHttpPath;//文件访问地址
private String attachType;//上传类型sftp/ftp/local

private String attachFtpIp;//ftp IP地址
private int attachFtpPort;//ftp 端口
private String attachFtpUser;//ftp 用户名
private String attachFtpPwd;//ftp 密码


@Override
public String toString() {
return JsonUtil.encodeString(this);
}

}

+ 427
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/controller/AttachController.java Целия файл

@@ -0,0 +1,427 @@
package cc.smtweb.system.bpm.spring.controller;

import cc.smtweb.framework.core.common.R;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.util.Consts;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.spring.file.attach.AttachHelper;
import cc.smtweb.system.bpm.spring.file.attach.AttachUtil;
import cc.smtweb.system.bpm.util.UtilDownloadFile;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilLogger;
import cc.smtweb.system.bpm.util.UtilMath;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
* Created by AKmm at 11-6-14 上午10:44
* 附件管理
*/
@Slf4j
@RestController
@RequestMapping("/api/attach")
public class AttachController {
private static Logger logger = LoggerFactory.getLogger(AttachController.class);
@Autowired
private FileConfigProperties properties;
@Autowired
private AttachHelper attachHelper;
@Autowired
private AttachUtil attachUtil;
@Autowired
private DbEngine dbEngine;
private BASE64Decoder decoder = new BASE64Decoder();

/**
*
* @param request
* @param type 类型,如idcard:身份证、headImg:头像
* @param ownerId 拥有者ID
* @param path 存储目录路径名,如:idcard
* @param attachIsTemp 是否临时文件:true/false 字符串
* @param attachName 附件名称,如:XXXXX.jpg
* @param savePath 保存路径,指定文件保存目录,可为空
* @return
* @throws Exception
*/
@PostMapping({"/upload"})
public R upload(HttpServletRequest request, @RequestParam(value = "type", required = false) String type,
@RequestParam(value = "ownerId", required = false) Long ownerId,
@RequestParam(value = "path", required = false) String path,
@RequestParam(value = "attachIsTemp", required = false) String attachIsTemp,
@RequestParam(value = "attachName", required = false) String attachName,
@RequestParam(value = "savePath", required = false) String savePath) throws Exception {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
//判断是否多文件上传
if (!multipartResolver.isMultipart(request)) {
return R.error("文件不存在");
}
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
Iterator<String> itr = multiRequest.getFileNames();
MultipartFile file = null;
while (itr.hasNext()) {
file = multiRequest.getFile(itr.next());
AttachInfo attach = new AttachInfo();
attach.setId(dbEngine.nextId());
attach.setType(type);//附件类别
if(null !=ownerId) {
attach.setOwnerId(ownerId);//附件拥有者id
}
attach.setPath(path);//附件路径
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setUserId(-1l);
attach.setIsTemp("true".equals(attachIsTemp) ? 1 : 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
// 上传文件名
final int i = file.getOriginalFilename().lastIndexOf(".");
if (i >= 0) {
attach.setSuffix(file.getOriginalFilename().substring(i));
}
if (PubUtil.isEmptyStr(attachName)) {
attachName = file.getOriginalFilename();
}
else {
attachName = attachName + attach.getSuffix();
}
attach.setName(attachName);
Map<String, Object> ret = new HashMap<>();
try {
// 上传文件域对象
File upload = new File(attachHelper.getAttachTmpPath() + attach.getId() + attach.getSuffix());
attach.setSize((long) FileCopyUtils.copy(file.getInputStream(), new BufferedOutputStream(new FileOutputStream(upload))));
if (PubUtil.isEmpty(savePath)) {
localSaveAttach(attach, upload);
} else {//复制到指定目录
String filePath;
if ("-".equals(savePath)) filePath = upload.getAbsolutePath();
else {
filePath = savePath + DateUtil.nowDateTimeString() + UtilFile.FSChar + attach.getName();
UtilFile.copy(upload, filePath, true);
}
}
} catch (Exception e) {
logger.error("上传文件失败", e);
return R.error("上传文件失败");
}
return R.success(attach.getId());
}
// 上传文件类型
//String uploadContentType = file.getContentType();
return R.error("上传文件失败");
}

/**
*
* @param request
* @param response
* @param base64File 文件base64编码
* @param attachId 附件ID,可为空,如果有,则替换此附件ID对应数据
* @param type 类型,如idcard:身份证、headImg:头像
* @param ownerId 拥有者ID
* @param path 存储目录路径名,如:idcard
* @param attachIsTemp 是否临时文件:true/false 字符串
* @param attachName 附件名称,如:XXXXX.jpg
* @param savePath 保存路径,指定文件保存目录,可为空
* @param suffix 文件后缀,如.jpg
* @return
* @throws Exception
*/
@RequestMapping(value = "/uploadBase64", method = RequestMethod.POST)
public R uploadBase64(HttpServletRequest request, HttpServletResponse response,
@RequestParam(value = "base64File", required = false) String base64File,
@RequestParam(value = "attachId", required = false) Long attachId,
@RequestParam(value = "type", required = false) String type,
@RequestParam(value = "ownerId", required = false) Long ownerId,
@RequestParam(value = "path", required = false) String path,
@RequestParam(value = "attachIsTemp", required = false) String attachIsTemp,
@RequestParam(value = "attachName", required = false) String attachName,
@RequestParam(value = "savePath", required = false) String savePath,
@RequestParam(value = "suffix", required = false) String suffix
) throws Exception {
// UtilLogger.error("上传文件接收base64", base64File);
if (null == base64File || "".equals(base64File)){
return R.error("文件不能为空");
}
String str[]=base64File.split(",");
if(str.length>1){
base64File=str[1];
}
// 上传文件类型
//String uploadContentType = file.getContentType();
AttachInfo attach = null;
boolean isNew = PubUtil.isEmpty(attachId+"");
if (isNew) {
attach = new AttachInfo();
}
else {
attach = dbEngine.findDao(AttachInfo.class).queryEntity(attachId);
if (attach == null) {
attach = new AttachInfo();
isNew = true;
} else isNew = attach.isNew();
}
attach.setId(attachId);
if (PubUtil.isEmpty(attachId+"")) attach.setId(dbEngine.nextId());

attach.setType(type);//附件类别
if(null !=ownerId) {
attach.setOwnerId(ownerId);//附件拥有者id
}
attach.setPath(path);//附件路径
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setUserId(-1l);
attach.setIsTemp("true".equals(attachIsTemp) ? 1 : 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
attach.setTime(DateUtil.nowDateTimeLong());
attach.setIsTemp("true".equals(attachIsTemp) ? 1 : 0);//暂时没有有效拥有者标记 方便定时任务清除垃圾附件
// 上传文件名
attach.setSuffix(suffix);
attach.setName(attachName);
Map<String, Object> ret = new HashMap<>();
try {
//将base64转图片存到临时目录
// 上传文件域对象
//保存文件
byte[] byt = decoder.decodeBuffer(base64File);
for (int i = 0, len = byt.length; i < len; ++i) {
if (byt[i] < 0) {
byt[i] += 256;
}
}
//创建保存目录,格式 类型目录/年月/日
File upload = new File(attachHelper.getAttachTmpPath() + attach.getId() + attach.getSuffix());
FileUtils.writeByteArrayToFile(upload, byt);
attach.setSize(upload.length());
if (PubUtil.isEmpty(savePath)) {
localSaveAttach(attach, upload);
} else {//复制到指定目录
String filePath;
if (Consts.NULL_STRING.equals(savePath)) filePath = upload.getAbsolutePath();
else {
filePath = savePath + DateUtil.nowDateTimeString() + UtilFile.FSChar + attach.getName();
UtilFile.copy(upload, filePath, true);
}
}
} catch (Exception e) {
UtilLogger.error("上传文件失败", e);
return R.error("上传文件失败");
}
return R.success(attach.getId());
}
@PostMapping({"/copyupload"})
public R copyupload(HttpServletRequest request) throws Exception {
String type=request.getParameter("type");
String attachId=request.getParameter("attachId");
if(PubUtil.isEmpty(attachId)){
return R.success("");
}
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if(null ==attach){
return R.success("");
}
String remoteName =attach.getId()+attach.getName().substring(attach.getName().lastIndexOf("."));
String remotePath = attach.getPath();
String filePath =attachHelper.getAttachTmpPath()+"tempFiles/";
UtilFile.makeDir(filePath);
Map<String, String> map = null;
try {
attachUtil.downloadAttach(remotePath, remoteName, filePath);
String filePaths=filePath+remoteName;

attach.setId(dbEngine.nextId());
attach.setType(type);//附件类别
attach.setOwnerId(-1l);//附件拥有者id
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setUserId(-1l);
attach.setName(attach.getId()+attach.getSuffix());
// 上传文件域对象
File upload = new File(filePaths);
// attach.setSize((long) FileCopyUtils.copy(file.getInputStream(), new BufferedOutputStream(new FileOutputStream(upload))));
localSaveAttach(attach, upload);
}catch (Exception e){
logger.error("上传文件失败", e);
return R.error("上传文件失败");
}
return R.success(attach.getId());
}


//保存处理附件
private void localSaveAttach(final AttachInfo attach, final File upload) throws Exception {
try {
//一般附件,上传到服务器,并记录附件
//传到ftp服务器上
attachUtil.saveAttach(attach, upload.getPath(), false);
//写入数据库
dbEngine.insertEntity(attach);
// String sql="insert into "+AttachInfo.ENTITY_NAME+" (attach_id,attach_name,attach_suffix,attach_owner_id,attach_path,attach_type,attach_size,attach_is_temp,attach_party_id,attach_time,attach_user_id,attach_count,attach_ref_id)"
} finally {
UtilFile.delFile(upload.getAbsolutePath());
}

}

//将附件上传到ftp服务器上
@RequestMapping(value = "/download", method = {RequestMethod.GET, RequestMethod.POST})
public R down(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "attachId", required = false) Long attachId) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
if (null == attach) {
return R.error("附件不存在");
}
final String remoteFileName = attach.getName();
final String fileName = attach.getName();
final String remotePath = attach.getPath();
logger.info("下载附件:filePath:" + remotePath + ",fileName:" + fileName);
try {
attachUtil.downloadAttach(remotePath, remoteFileName, fileName, response);
attach.setCount(attach.getCount() + 1);
dbEngine.updateEntity(attach,"attach_count");
} catch (Exception e) {
logger.error("附件下载失败",e);
R.error("附件下载失败");

}
return null;
}

//图片附件显示路径
@RequestMapping(value = "/showImg", method = {RequestMethod.GET, RequestMethod.POST})
public R showImg(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "attachId", required = false) Long attachId) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
if (null == attach) {
return R.error("附件不存在");
}
final String remoteFileName = attach.getName();
final String fileName = attach.getName();
final String remotePath = attach.getPath();
try {
attachUtil.downloadAttach(remotePath, remoteFileName, fileName, response);
} catch (Exception e) {
logger.error("附件下载失败",e);
R.error("附件下载失败");
}
return null;
}

//图片附件显示路径
@RequestMapping(value = "/showImgThumb", method = {RequestMethod.GET, RequestMethod.POST})
public R showImgThumb(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "attachId", required = false) Long attachId,
@RequestParam(value = "width", required = false,defaultValue = "100") String width,
@RequestParam(value = "heigh", required = false,defaultValue = "100") String heigh) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
if (null == attach) {
return R.error("附件不存在");
}
final String remoteFileName = attach.getName();
final String tempPath = System.getProperty("java.io.tmpdir");
final String remotePath = attach.getPath();
try {
String lfo = tempPath + "/" + remoteFileName;
String lfd = tempPath + "/thumb_" + attach.getId() + attach.getSuffix();
attachUtil.downloadAttach(remotePath, remoteFileName, tempPath);
int w=Integer.valueOf(width);
int h=Integer.valueOf(heigh);
if (w <= 0) w = 100;
if (h <= 0) h = 100;
getImgThumb(lfo, lfd, w, h);
if (UtilFile.isFileExist(lfd)) {
UtilDownloadFile.downfileEx(response, lfd, attach.getName());
} else if (UtilFile.isFileExist(lfo)) {
UtilDownloadFile.downfileEx(response, lfo, attach.getName());
}
} catch (Exception e) {
logger.error("附件下载失败",e);
R.error("附件下载失败");
}
return null;
}

private static boolean getImgThumb(String orgFile, String dstFile, int width, int height) {
BufferedImage bufferedImage;
try {
//read image file
bufferedImage = ImageIO.read(new File(orgFile));

// create a blank, RGB, same width and height, and a white background
int w = bufferedImage.getWidth(), h = bufferedImage.getHeight();
double r = 1;
if (w > width) {
r = 1.0 * width / w;
}

if (h > height) {
r = Math.min(1.0 * height / h, r);
}
if (!UtilMath.isEqualsZero(r - 1)) {
w = (int) Math.round(w * r);
h = (int) Math.round(h * r);
}
BufferedImage newBufferedImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

//TYPE_INT_RGB:创建一个RBG图像,24位深度,成功将32位图转化成24位
newBufferedImage.createGraphics().drawImage(bufferedImage.getScaledInstance(w, h, Image.SCALE_SMOOTH), 0, 0, Color.WHITE, null);
// write to jpeg file
ImageIO.write(newBufferedImage, "jpg", new File(dstFile));
return true;
} catch (IOException e) {
logger.error("转换jpg错误:" + orgFile);
return false;
}
}

//删除附件
@PostMapping({"/delete"})
public R del(HttpServletRequest request, @RequestParam(value = "attachId", required = false) Long attachId) throws Exception {
try {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class,attachId);
if (null == attach) {
return R.error("附件不存在");
}
attachHelper.deleteOneAttach(attach);
return R.success("附件删除成功");
} catch (Exception e) {
logger.error("删除附件失败", e);
return R.error("删除附件失败");
}
}

//按拥有者删除附件
@PostMapping({"/deleteByOwnerId"})
public R delByOwnerId(HttpServletRequest request, @RequestParam(value = "ownerId", required = false) String ownerId) throws Exception {
try {
attachHelper.deleteAttachByOwnerId(ownerId);
return R.success("附件删除成功");
} catch (Exception e) {
logger.error("删除附件失败", e);
return R.error("删除附件失败");
}
}


}

+ 71
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/dataCacheInit/AttachFolderEntityBuffer.java Целия файл

@@ -0,0 +1,71 @@
package cc.smtweb.system.bpm.spring.dataCacheInit;

import cc.smtweb.framework.core.cache.redis.RedisManager;
import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.system.bpm.web.sys.base.attachFolder.AttachFolder;
import cc.smtweb.system.bpm.web.sys.base.attachFolder.pojo.AttachFolderPojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;


/**
* 实体【[附件目录表](TB_SYS_ATTACH_FOLDER)】的缓存Buffer类
*/
@Component
public final class AttachFolderEntityBuffer {
@Autowired
private RedisManager redisManager;
@Autowired
private DbEngine dbEngine;

public static final String cacheKey="attach_folder_";


//根据附件路径和期间获取对象
public AttachFolderPojo getByPath(String attachPath, String period) {

return redisManager.get(cacheKey+attachPath + "_" + period, AttachFolderPojo.class);

}

//根据附件路径和期间获取当前最大序号
public int getMaxSeq(String attachPath, String period) {
AttachFolderPojo bean = getByPath(attachPath, period);
if (bean == null) return 0;
return bean.getFolderMaxSeq();
}

//根据附件路径和期间获取当前文件数
public int getFileCount(String attachPath, String period) {
AttachFolderPojo bean = getByPath(attachPath, period);
if (bean == null) return 0;
return bean.getFolderFileCount().intValue();
}

//初始化数据
public void initData(){
//查询所有数据
String sql="select folder_id,folder_path,folder_period,folder_max_seq,folder_file_count from "+ AttachFolder.ENTITY_NAME;
List<AttachFolder> returnList = dbEngine.query(sql,AttachFolder.class);
if(null !=returnList && returnList.size()>0){
for(AttachFolder pojo:returnList){
AttachFolderPojo p=new AttachFolderPojo();
p.setFolderId(pojo.getId());
p.setFolderAttachPath(pojo.getPath());
p.setFolderFileCount(pojo.getFileCount());
p.setFolderPeriod(pojo.getPeriod());
p.setFolderMaxSeq(pojo.getMaxSeq());
redisManager.set(cacheKey+pojo.getPath()+"_"+pojo.getPeriod(),p,0);
}
}
}

//写入一个数据
public void putOneData(AttachFolderPojo pojo){
//查询所有数据
redisManager.set(cacheKey+pojo.getFolderAttachPath()+"_"+pojo.getFolderPeriod(),pojo,0);
}

}

+ 102
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFileWork.java Целия файл

@@ -0,0 +1,102 @@
package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.util.UtilDownloadFile;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

@Component
public final class AttachFileWork implements IAttachWorkIntf {
@Autowired
private FileConfigProperties properties;
private String getPath(String remoteFolderPath) {
String path =properties.getAttachPath();
if (PubUtil.isNotEmpty(remoteFolderPath) && !path.endsWith("/") && !remoteFolderPath.startsWith("/"))
path = path + "/" + remoteFolderPath;
else path = path + remoteFolderPath;
path = path.replaceAll("-","");
UtilFile.makeDir(path);
if (!path.endsWith("/")) path = path + "/";
return path;
}

private String getFileName(String remoteFolderPath, String fileName) {
return getPath(remoteFolderPath) + fileName;
}

public void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception {
String dstFile = getFileName(remoteFolderPath, remoteAttachName);
if (isDelLocal) UtilFile.renameTo(localAttach, dstFile);
else UtilFile.copy(localAttach,dstFile);
}

@Override
public void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception {
String srcFile = getFileName(remoteFolderPath, srcFileName);
String dstFile = getFileName(remoteFolderPath, desFileName);
if (isDelSrc) UtilFile.renameTo(srcFile, dstFile);
else UtilFile.copy(srcFile, dstFile);
}


public void deletePath(final String remotePath) throws Exception {
UtilFile.delFile(getPath(remotePath));
}

public void deleteAttach(final String remotePath, final String remoteName) throws Exception {
UtilFile.delFile(getFileName(remotePath, remoteName));
}

public void downloadAttach(final String remotePath, final String remoteName, final String fileName, final HttpServletResponse response) throws Exception {
UtilDownloadFile.downfileEx(response, getFileName(remotePath, remoteName), fileName);
}

public void downloadAttach(final String remotePath, final String remoteName, final String localPath) throws Exception {
UtilFile.copy(getFileName(remotePath, remoteName), localPath + "/" + remoteName);
}

@Override
public void downloadAttach(String remotePath, String remoteName, String localPath, String localName) throws Exception {
UtilFile.copy(getFileName(remotePath, remoteName), localPath + "/" + localName);
}

public void showAttachImg(final String remotePath, final String remoteName, final HttpServletResponse response) throws Exception {
UtilDownloadFile.sendImgFile(response, remoteName);
}

public List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType, final String localRoot) throws Exception {
final List<String> files = new ArrayList<>();
String localPath = localRoot + "/" + ownerType + "/";
UtilFile.makeDir(localPath);
String fileName;
File file;
for (AttachInfo attach : attachlist) {
fileName = localPath + attach.getName();
file = new File(fileName);
if (!file.exists())
UtilFile.copy(getFileName(attach.getPath(), attach.getName()), fileName);
files.add(fileName);
}
return files;
}

public void makeRemoteDir(String path) throws Exception {
UtilFile.makeDir(getPath(path));
}

@Override
public Path getAttachPath(String remotePath, String remoteName) {
String path = getFileName(remotePath, remoteName);
return Paths.get(path);
}
}

+ 222
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachFtpWork.java Целия файл

@@ -0,0 +1,222 @@
package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.util.UtilDownloadFile;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.ftp.FtpTask;
import cc.smtweb.system.bpm.util.ftp.FtpTaskManager;
import cc.smtweb.system.bpm.util.ftp.IFtpServerConfig;
import cc.smtweb.system.bpm.util.ftp.IFtpUtil;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;

/**
* Created by AKmm at 2011-2-23 16:35:49
* ftp工作服务
*/
@Component
public final class AttachFtpWork implements IAttachWorkIntf {
Logger logger = LoggerFactory.getLogger(AttachFtpWork.class);
@Autowired
private FileConfigProperties properties;
private String getPath(String remoteFolderPath) {
String path = properties.getAttachPath();
if (PubUtil.isNotEmpty(remoteFolderPath) && !path.endsWith("/") && !remoteFolderPath.startsWith("/"))
path = path + "/" + remoteFolderPath;
else path = path + remoteFolderPath;
path = path.replaceAll("-", "");
UtilFile.makeDir(path);
if (!path.endsWith("/")) path = path + "/";
logger.info("远程附件路径:" + path);
return path;
}

public FtpTaskManager getFtpManager() {
return FtpTaskManager.getInstance("ATTACH_FTP", new IFtpServerConfig() {
@Override
public boolean isSFTP() {
return "sftp".equalsIgnoreCase(properties.getAttachType());
}

@Override
public String getServerIp() {
return properties.getAttachFtpIp();
}

@Override
public Integer getPort() {
return properties.getAttachFtpPort();
}

@Override
public String getUserName() {
return properties.getAttachFtpUser();
}

@Override
public String getPassword() {
return properties.getAttachFtpPwd();
}
});
}

public void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception {
getFtpManager().uploadToFtp(remoteAttachName, getPath(remoteFolderPath), localAttach, isDelLocal);
}

@Override
public void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
if (!ftp.existsFile(srcFileName, getPath(remoteFolderPath))) return null;
ftp.setRemoteDir("/");
ftp.mkdir(remoteFolderPath);
ftp.rename(remoteFolderPath, srcFileName, desFileName);
return null;
}
});
}


public void deletePath(final String remotePath) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
ftp.deleteFolder(remotePath);
return null;
}
});
}

public void deleteAttach(final String remotePath, final String remoteName) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
ftp.deleteFile(getPath(remotePath), remoteName);
return null;
}
});
}

public void downloadAttach(final String remotePath, final String remoteName, final String fileName, final HttpServletResponse response) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
InputStream in;
in = ftp.downloadFile(getPath(remotePath), remoteName);

if (in == null) return null;
try {
UtilDownloadFile.downfileStream(response, fileName, 0, in);
} finally {
IOUtils.closeQuietly(in);
ftp.completePendingCommand();
}

return null;
}
});
}

@Override
public void showAttachImg(final String remotePath, final String remoteName, final HttpServletResponse response) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
InputStream in = null;
try {
in = ftp.downloadFile(getPath(remotePath), remoteName);
} catch (Exception e) {
e.printStackTrace();
}
if (in == null) return null;
try {
UtilDownloadFile.sendImgStream(response, in);
} finally {
IOUtils.closeQuietly(in);
ftp.completePendingCommand();
}

return null;
}
});
}


public void downloadAttach(final String remotePath, final String remoteName, final String localPath) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
try {
ftp.downloadFile(getPath(remotePath), remoteName, localPath);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}

@Override
public void downloadAttach(String remotePath, String remoteName, String localPath, String localName) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
try {
ftp.downloadFileEx(getPath(remotePath), remoteName,localPath + File.separator + localName );
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
});
}

public List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType, final String localRoot) throws Exception {
final List<String> files = new ArrayList<String>();
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
String localPath = localRoot + UtilFile.FSChar + ownerType + UtilFile.FSChar;
File file = new File(localPath);
if (!file.exists()) {
file.mkdirs();
}
String fileName;
for (AttachInfo attach : attachlist) {
fileName = localPath + attach.getName();
file = new File(fileName);
if (!file.exists())
try {
ftp.downloadFileEx(getPath(attach.getPath()), attach.getName(), fileName);
} catch (Exception e) {
e.printStackTrace();
}
files.add(fileName);
}

return null;
}
});
return files;
}

public void makeRemoteDir(final String path) throws Exception {
getFtpManager().execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
ftp.setRemoteDir(path);
return null;
}
});
}

@Override
public Path getAttachPath(String remotePath, String remoteName) {
throw new UnsupportedOperationException("FTP的还没用到,没开发,暂不支持");
}
}

+ 283
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachHelper.java Целия файл

@@ -0,0 +1,283 @@
package cc.smtweb.system.bpm.spring.file.attach;

import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilMath;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Created by AKmm at 11-6-15 下午3:32
* 附件管理
*/
@Component
public final class AttachHelper {
Logger logger = LoggerFactory.getLogger(AttachHelper.class);
@Autowired
private FileConfigProperties properties;
@Autowired
private DbEngine dbEngine;
@Autowired
private AttachUtil attachUtil;
//得到附件临时目录
public String getAttachTmpPath() {
String tmp_attach = properties.getAttachTempPath();
if (!tmp_attach.endsWith("/")) tmp_attach += "/";
File file = new File(tmp_attach);
if (!file.exists()) {
file.mkdirs();
}
return tmp_attach;
}

//删除ftp服务器的文件
public boolean deleteOneAttach(String attachId) throws Exception {
if (PubUtil.isEmpty(attachId)) return true;
AttachInfo attachInfo = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if(null == attachInfo){
return true;
}
boolean deleteSuccess = deleteAttachInFtpServer(attachInfo.getPath(), attachInfo.getName());
if (deleteSuccess) {
dbEngine.deleteEntity(attachInfo);
}
return deleteSuccess;
}

//删除ftp服务器的文件
public boolean deleteOneAttach(AttachInfo bean) throws Exception {
boolean deleteSuccess = deleteAttachInFtpServer(bean.getPath(), bean.getName());
if (deleteSuccess) {
dbEngine.deleteEntity(bean);
}
return deleteSuccess;
}

//删除ftp服务器的文件夹
public void deleteFolder(final String remotePath) throws Exception {
attachUtil.deletePath(remotePath);
}

public List<AttachInfo> getAttachListByOwnerId(String ownerId) throws Exception {
return dbEngine.query("select * from "+AttachInfo.ENTITY_NAME+" where attach_owner_id=? ",AttachInfo.class,ownerId);
}

public List<AttachInfo> listAttachListByOwnerIdAndType(String ownerId, String attach_type) throws Exception {
return dbEngine.query("select * from "+AttachInfo.ENTITY_NAME+" where attach_owner_id=? and attach_type=? ",AttachInfo.class,ownerId,attach_type);
}

public int getAttachCountByOwnerId(String ownerId) throws Exception {
return dbEngine.queryInt("select count(0) from "+AttachInfo.ENTITY_NAME+" where attach_owner_id=? ",ownerId);
}

//根据附件拥有者和附件类型删除
public boolean deleteAttachByOwnerIdAndType(String ownerId, String attachType) throws Exception {
final List<AttachInfo> list = listAttachListByOwnerIdAndType(ownerId, attachType);
return deleteAttachListEx(list);
}

public boolean deleteAttachByOwnerId(String ownerId) throws Exception {
final List<AttachInfo> list = getAttachListByOwnerId(ownerId);
return deleteAttachListEx(list);
}

//批量删除
public boolean deleteAttachList(List<String> attachIdList) throws Exception {
if (PubUtil.isEmpty(attachIdList)) return false;
dbEngine.update("delete from "+AttachInfo.ENTITY_NAME+" where attach_id in(" + PubUtil.getSqlInIds(attachIdList) + ")");
return true;
}

public boolean deleteAttachListEx(List<AttachInfo> list) throws Exception {
boolean result = true;
for (AttachInfo bean : list) {
if (!deleteAttachInFtpServer(bean.getPath(), bean.getName())) {
result = false;
break;
}
}
if (result) {
for (AttachInfo bean : list) {
dbEngine.deleteEntity(bean);
}
}
return result;
}

//删除在ftp服务器上的附件
public boolean deleteAttachInFtpServer(String remotePath, String remoteName) {
try {
attachUtil.deleteAttach(remotePath, remoteName);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}

/**
* 下载附件
*
* @param attachId 附件id
* @param localPath 要下载到的本地路径
* @return 返回文件名
* @throws Exception
*/
public String getAttachFromFtp(final String attachId, final String localPath) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if (null == attach) throw new Exception("附件不存在!");

final String remoteFileName = attach.getName();
final String remotePath = attach.getPath();

attachUtil.downloadAttach(remotePath, remoteFileName, localPath);
return remoteFileName;

}

/**
* 下载附件
*
* @param attachId 附件id
* @param localPath 要下载到的本地路径
* @return 返回文件名
* @throws Exception
*/
public String getAttachFromFtp(final String attachId, final String localPath, String localName) throws Exception {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, Long.valueOf(attachId));
if (null == attach) throw new Exception("附件不存在!");
final String remoteFileName = attach.getName();
final String remotePath = attach.getPath();

attachUtil.downloadAttach(remotePath, remoteFileName, localPath, localName);
return remoteFileName;

}

/**
* 下载附件
*
* @param attachlist 附件列表
* @param ownerType 附件类别
* @return 返回文件名列表,本地有此文件将不再下载
* @throws Exception
*/
private List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType) throws Exception {
return attachUtil.getAttachListFromFtp(attachlist, ownerType, getAttachTmpPath());
}

/**
* 下载附件
*
* @param ownerId 附件拥有者id
* @param ownerType 附件类别
* @return 返回文件名列表,本地有此文件将不再下载
* @throws Exception
*/
public List<String> getAttachsFromFtp(final String ownerId, final String ownerType) throws Exception {
final List<AttachInfo> attachlist = getAttachListByOwnerId(ownerId);

return getAttachListFromFtp(attachlist, ownerType);

}

/**
* 下载附件
*
* @param attachIds 附件id
* @param ownerType 附件类别
* @return 返回文件名列表,本地有此文件将不再下载
* @throws Exception
*/
public List<String> getAttachsFromFtp(final List<String> attachIds, final String ownerType) throws Exception {
List<Object> paras = new ArrayList<Object>();
if (PubUtil.isNotEmpty(attachIds)) {
StringBuilder sb = new StringBuilder(128);
for(int i=0;i<attachIds.size();i++){
if(i==0){
sb.append(" attach_id=? ");
}else{
sb.append(" or attach_id=? ");
}
paras.add(attachIds.get(i));
}
final List<AttachInfo> attachlist =dbEngine.queryWhere(AttachInfo.class,sb.toString(),paras.toArray());
if (null == attachlist || attachlist.size()<1) throw new Exception("附件不存在!");
return getAttachListFromFtp(attachlist, ownerType);
}
return new ArrayList<>();
}

/**
* 得到文件大小
*
* @return
*/
public String getSizeStr(long fileSize) {
if (fileSize < 1024) return fileSize + "B";
double n = fileSize * 1.0 / 1024;
if (UtilMath.compare(n, 1024) < 0) return UtilMath.toStdNumberString(n, 0) + "KB";
n = n / 1024;
return UtilMath.toStdNumberString(n) + "MB";
}

/**
* 清除临时标志
*
* @param attach_owner_id 拥有者
* @throws Exception
*/
public void removeTempTag(String attach_owner_id) throws Exception {
dbEngine.update("update "+AttachInfo.ENTITY_NAME+" set attach_is_temp=0 WHERE attach_owner_id=? AND attach_is_temp=1 ",attach_owner_id);
}

public String copyupload(String type,Long attachId) {
AttachInfo attach = dbEngine.queryEntity(AttachInfo.class, attachId);
if(attach==null){
return "";
}
String remoteName =attach.getId()+attach.getName().substring(attach.getName().lastIndexOf("."));
String remotePath = attach.getPath();
String filePath =getAttachTmpPath()+"tempFiles/";
UtilFile.makeDir(filePath);
Map<String, String> map = null;
try {
attachUtil.downloadAttach(remotePath, remoteName, filePath);
String filePaths=filePath+remoteName;

attach.setId(dbEngine.nextId());
attach.setType(type);//附件类别
attach.setOwnerId(-1l);//附件拥有者id
attach.setPartyId(-1l);
attach.setTime(PubUtil.getLastTime());
attach.setUserId(-1l);
attach.setName(attach.getId()+attach.getSuffix());
// 上传文件域对象
File upload = new File(filePaths);
// attach.setAttachSize((long) FileCopyUtils.copy(file.getInputStream(), new BufferedOutputStream(new FileOutputStream(upload))));
try {
//一般附件,上传到服务器,并记录附件
//传到ftp服务器上
attachUtil.saveAttach(attach, upload.getPath(), false);
//写入数据库
dbEngine.insertEntity(attach);
} finally {
UtilFile.delFile(upload.getAbsolutePath());
}
}catch (Exception e){
logger.error("复制文件失败", e);
return "";
}
return attach.getId()+"";
}
}

+ 135
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/AttachUtil.java Целия файл

@@ -0,0 +1,135 @@
package cc.smtweb.system.bpm.spring.file.attach;


import cc.smtweb.framework.core.db.DbEngine;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.spring.config.FileConfigProperties;
import cc.smtweb.system.bpm.spring.dataCacheInit.AttachFolderEntityBuffer;
import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;
import cc.smtweb.system.bpm.web.sys.base.attachFolder.AttachFolder;
import cc.smtweb.system.bpm.web.sys.base.attachFolder.pojo.AttachFolderPojo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.nio.file.Path;
import java.util.List;

/**
* Created by AKmm at 2011-2-23 15:06:56
* 附件存储工具,按存储方式决定保存在
*/
@Component
public final class AttachUtil {
//一个文件夹下最多允许多少文件
private final static int MAX_FILE_COUNT = 1000;
private static IAttachWorkIntf worker;
@Autowired
private FileConfigProperties properties;
@Autowired
private AttachFolderEntityBuffer attachFolderEntityBuffer;
@Autowired
private DbEngine dbEngine;
@Autowired
private AttachFtpWork attachFtpWork;
@Autowired
private AttachFileWork attachFileWork;
static {
// init();
}

public void init() {
final String at = PubUtil.checkNull(properties.getAttachType()).toLowerCase();
if ("ftp".equals(at) || "sftp".equals(at))
worker = attachFtpWork;
else worker = attachFileWork;
}

private void checkAttachFolder(final AttachInfo attach) throws Exception {
final String period = DateUtil.getNowYm();
AttachFolderPojo folder = attachFolderEntityBuffer.getByPath(attach.getPath(), period);

AttachFolder entity=new AttachFolder();
boolean isNew = false;
if (folder == null) {
isNew = true;
folder = new AttachFolderPojo();
folder.setFolderId(dbEngine.nextId());
folder.setFolderAttachPath(attach.getPath());
folder.setFolderPeriod(period);
folder.setFolderMaxSeq(1);

entity.setPath(attach.getPath());
entity.setPeriod(period);
entity.setMaxSeq(1);
}
if (folder.getFolderFileCount() >= MAX_FILE_COUNT) {
folder.setFolderMaxSeq(folder.getFolderMaxSeq() + 1);
folder.setFolderFileCount(0l);

entity.setMaxSeq(folder.getFolderMaxSeq() + 1);
entity.setFileCount(0);
}
folder.setFolderFileCount(folder.getFolderFileCount() + 1);
entity.setFileCount(folder.getFolderFileCount() + 1);
entity.setId(folder.getFolderId());
//检查并确定远程目录
if (isNew) {
// dbEngine.update("insert into "+AttachFolderEntity.ENTITY_NAME+" (folder_id,attach_path,folder_period,max_seq,file_count)values(?,?,?,?,?)",entity.getFolderId(),entity.getAttachPath(),entity.getFolderPeriod(),entity.getMaxSeq(),entity.getFileCount());
dbEngine.insertEntity(entity, "folder_id,folder_path,folder_period,folder_max_seq,folder_file_count");
} else {
// dbEngine.update("update "+AttachFolderEntity.ENTITY_NAME+" set max_seq=?,file_count=? where folder_id=?",new Object[]{entity.getMaxSeq(),entity.getFileCount(),entity.getFolderId()});
dbEngine.updateEntity(entity, "folder_max_seq,folder_file_count");
}
attach.setPath(attach.getPath() + "/" + period + "/" + folder.getFolderMaxSeq());
attachFolderEntityBuffer.putOneData(folder);
}

public void saveAttach(final AttachInfo attach, String localAttach, boolean isDelLocal) throws Exception {
synchronized (attach.getPath()) {
checkAttachFolder(attach);
saveAttach(attach.getName(), attach.getPath(), localAttach, false);
}
}

public void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception {
worker.saveAttach(remoteAttachName, remoteFolderPath, localAttach, isDelLocal);
}

public void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception {
worker.copyAttach(srcFileName, desFileName, remoteFolderPath, isDelSrc);
}

public void deletePath(String remotePath) throws Exception {
worker.deletePath(remotePath);
}

public void deleteAttach(String remotePath, String remoteName) throws Exception {
worker.deleteAttach(remotePath, remoteName);
}

public void downloadAttach(String remotePath, String remoteName, String fileName, HttpServletResponse response) throws Exception {
worker.downloadAttach(remotePath, remoteName, fileName, response);
}

public void downloadAttach(String remotePath, String remoteName, String localPath) throws Exception {
worker.downloadAttach(remotePath, remoteName, localPath);
}

public void downloadAttach(String remotePath, String remoteName, String localPath, String localName) throws Exception {
worker.downloadAttach(remotePath, remoteName, localPath, localName);
}

public List<String> getAttachListFromFtp(final List<AttachInfo> attachlist, final String ownerType, final String localRoot) throws Exception {
return worker.getAttachListFromFtp(attachlist, ownerType, localRoot);
}

public void makeRemoteDir(String path) throws Exception {
worker.makeRemoteDir(path);
}

public Path getAttachPath(String remotePath, String remoteName) throws Exception {
return worker.getAttachPath(remotePath, remoteName);
}
}

+ 28
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/IAttachTraceIntf.java Целия файл

@@ -0,0 +1,28 @@
package cc.smtweb.system.bpm.spring.file.attach;


import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;

/**
* Created by Akmm at 13-5-4 下午3:02
* 附件处理跟踪
*/
public interface IAttachTraceIntf {
/**
* 附件上传后
*
* @param filePath
* @param attach
* @throws Exception
*/
void afterUpload(String filePath, AttachInfo attach) throws Exception;

/**
* 附件删除后
*
* @param attach
* @throws Exception
*/
void afterDel(AttachInfo attach) throws Exception;

}

+ 115
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/file/attach/IAttachWorkIntf.java Целия файл

@@ -0,0 +1,115 @@
package cc.smtweb.system.bpm.spring.file.attach;



import cc.smtweb.system.bpm.web.sys.base.attach.AttachInfo;

import javax.servlet.http.HttpServletResponse;
import java.nio.file.Path;
import java.util.List;

/**
* Created by AKmm at 2011-2-23 16:22:20
* 附件存储操作接口
*/
public interface IAttachWorkIntf {
/**
* 保存附件
*
* @param remoteAttachName 远程附件名
* @param remoteFolderPath 远程路径
* @param localAttach 本地文件名
* @param isDelLocal 保存后是否删除本地
* @throws Exception
*/
void saveAttach(String remoteAttachName, String remoteFolderPath, String localAttach, boolean isDelLocal) throws Exception;


/**
* 复制附件
*
* @param srcFileName 源文件
* @param desFileName 新文件
* @param remoteFolderPath 文件路径
* @param isDelSrc 保存后是否删除源文件
* @throws Exception
*/
void copyAttach(String srcFileName, String desFileName, String remoteFolderPath, boolean isDelSrc) throws Exception;


/**
* 删除路径
*
* @param remotePath 远程路径
* @throws Exception
*/
void deletePath(String remotePath) throws Exception;

/**
* 删除附件
*
* @param remotePath 远程路径
* @param remoteName 远程文件名
* @return
*/
void deleteAttach(String remotePath, String remoteName) throws Exception;

/**
* 下载附件到文件流
*
* @param remotePath
* @param remoteName
* @param response
* @throws Exception
*/
void downloadAttach(String remotePath, String remoteName, String fileName, HttpServletResponse response) throws Exception;

/**
* 下载到本地
*
* @param remotePath 远端路径
* @param remoteName 远端文件
* @param localPath 本地路径
* @throws Exception
*/
void downloadAttach(String remotePath, String remoteName, String localPath) throws Exception;

/**
* 下载到本地
*
* @param remotePath 远端路径
* @param remoteName 远端文件
* @param localPath 本地路径
* @throws Exception
*/
void downloadAttach(String remotePath, String remoteName, String localPath, String localName) throws Exception;

/**
* img显示
*
* @param remotePath 远端路径
* @param remoteName 远端文件
* @param response
* @throws Exception
*/
void showAttachImg(final String remotePath, final String remoteName, final HttpServletResponse response) throws Exception;

/**
* 批量下载文件到本地
*
* @param attachlist
* @param ownerType
* @param localRoot
* @return
* @throws Exception
*/
List<String> getAttachListFromFtp(List<AttachInfo> attachlist, String ownerType, String localRoot) throws Exception;

void makeRemoteDir(String path) throws Exception;

/**
* 获取文件路径
*
*/
Path getAttachPath(String remotePath, String remoteName);
}

+ 27
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/spring/initPlugin/RunDataInit.java Целия файл

@@ -0,0 +1,27 @@
package cc.smtweb.system.bpm.spring.initPlugin;

import cc.smtweb.system.bpm.spring.dataCacheInit.AttachFolderEntityBuffer;
import cc.smtweb.system.bpm.spring.file.attach.AttachUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/**
* @Author: zhangyulong
* @Date: 2021/9/17 15:31
*/

@Component
public class RunDataInit implements ApplicationRunner {
@Autowired
private AttachFolderEntityBuffer attachFolderEntityBuffer;
@Autowired
private AttachUtil attachUtil;
@Override
public void run(ApplicationArguments args) throws Exception {
attachFolderEntityBuffer.initData();//附件目录缓存
attachUtil.init();//附件上传方式初始化

}
}

+ 135
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilDownloadFile.java Целия файл

@@ -0,0 +1,135 @@
package cc.smtweb.system.bpm.util;

import org.apache.commons.io.IOUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;

public abstract class UtilDownloadFile {
public static void writePdf(HttpServletResponse response, InputStream inputStream) throws IOException {
InputStream bufIn = new BufferedInputStream(inputStream, 8192);
try {
OutputStream output = response.getOutputStream();
response.setContentType("application/pdf");
byte[] bs = new byte[8192];
while (true) {
int nLen = bufIn.read(bs);
if (nLen <= 0) break;
output.write(bs, 0, nLen);
}
output.flush();
} finally {
IOUtils.closeQuietly(bufIn);
}
}

/**
* Akmm 2008.8.29 增加,原方法在大文件时,必须先读完整个文件才开始下载,
* 新加方法边读边写response.getOutputStream,让客户端及时看到进度条
*
* @param response r
* @param fileSrc 源文件名
* @param fileOrigName 显示在reponse中的文件名称.
*/
public static void downfileEx(HttpServletResponse response, String fileSrc, String fileOrigName) {
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(fileSrc), 8192);
downfileStream(response, fileOrigName, in.available(), in);
} catch (Exception e) {
// ignore
} finally {
IOUtils.closeQuietly(in);
}
}

/**
* Akmm 2008.8.29 增加,原方法在大文件时,必须先读完整个文件才开始下载,
* 新加方法边读边写response.getOutputStream,让客户端及时看到进度条
*/
public static void downfileStream(HttpServletResponse response, String fileName, int totalSize, InputStream in) {
OutputStream out = null;
try {
writeResponseHeader(response, fileName, totalSize);

out = response.getOutputStream();
byte[] bs = new byte[8192];
while (true) {
int nLen = in.read(bs);
if (nLen <= 0) break;
out.write(bs, 0, nLen);
}
out.flush();
} catch (IOException e) {
UtilLogger.error("客户端下载过程取消或中断!", e);
} finally {
IOUtils.closeQuietly(out);
}
}

public static void sendImgFile(HttpServletResponse response, String fileSrc) {
InputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(fileSrc), 8192);
sendImgStream(response, in);
} catch (Exception e) {
// ignore
} finally {
IOUtils.closeQuietly(in);
}
}

/**
* Akmm 图片显示,
*/
public static void sendImgStream(HttpServletResponse response, InputStream in) {
OutputStream out = null;
try {
out = response.getOutputStream();
byte[] bs = new byte[8192];
while (true) {
int nLen = in.read(bs);
if (nLen <= 0) break;
out.write(bs, 0, nLen);
}
out.flush();
} catch (IOException e) {
UtilLogger.error("图片显示", e);
} finally {
IOUtils.closeQuietly(out);
}
}

public static void writeResponseHeader(HttpServletResponse response, String fileName, int totalSize) {
try {
/*解决中文文件名乱码的问题*/
fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
} catch (Exception ex) {
// ignore
}
/*
例1.内嵌显示一个文件
Content-disposition: inline; filename=foobar.pdf
例2.往response里附加一个文件
Content-disposition: attachment; filename=foobar.pdf
*/
//返回文件下载
response.setContentType("APPLICATION/OCTET-STREAM");
response.setCharacterEncoding("UTF-8");
response.setHeader("GATM-Attch-Name", fileName);
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
if (totalSize > 0) response.setContentLength(totalSize);
}

/**
* 写空长度的内容到输出流.
*/
public static void writeZeroLengthResponse(HttpServletResponse response, String fileName) {
try {
writeResponseHeader(response, fileName, 0);
response.flushBuffer();
} catch (IOException e) {
// ignore e;
}
}
}

+ 1178
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilFile.java
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 66
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilLogger.java Целия файл

@@ -0,0 +1,66 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.util.PubUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;

@SuppressWarnings("UnusedDeclaration")
public class UtilLogger {
private static final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);

private static String getOrigMsg(String message, Throwable e) {
if (message != null) return message;
return PubUtil.getOrigMsg(e);
}

public static void debug(String message) {
logger.debug(message);
}

public static void debug(String message, String module) {
logger.debug(MessageFormat.format("[{0}]{1}", module, message));
}

public static void debug(String message, Throwable e) {
logger.debug(getOrigMsg(message, e), e);
}

public static void info(String message) {
logger.info(message);
}

public static void info(String message, String module) {
logger.info(MessageFormat.format("[{0}]{1}", module, message));
}

public static void info(String message, Throwable e) {
logger.info(getOrigMsg(message, e), e);
}

public static void warn(String message) {
logger.warn(message);
}

public static void warn(String message, String module) {
logger.warn(MessageFormat.format("[{0}]{1}", module, message));
}

public static void warn(String message, Throwable e) {
logger.warn(getOrigMsg(message, e), e);
}

public static void error(String message) {
logger.error(message);
}

public static void error(String message, String module) {
logger.error(MessageFormat.format("[{0}]{1}", module, message));
}

public static void error(String message, Throwable e) {
if (e instanceof Exception) logger.info(message + PubUtil.getOrigMsg(e));
else logger.error(getOrigMsg(message, e), e);
}
}

+ 465
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilMath.java Целия файл

@@ -0,0 +1,465 @@
package cc.smtweb.system.bpm.util;

import cc.smtweb.framework.core.util.PubUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;

/**
* Created with IntelliJ IDEA.
* User: AKhh
* Date: 12-12-25 下午1:02
* To change this template use File | Settings | File Templates.
*/
public class UtilMath {
//整数
private static DecimalFormat dfLng = new DecimalFormat("##############0");
private static DecimalFormat dfLong = new DecimalFormat("###,###,###,###,##0");
//一位小数
private static DecimalFormat df1 = new DecimalFormat("##############0.0");
private static DecimalFormat df1Format = new DecimalFormat("###,###,###,###,##0.0");
//两位小数
private static DecimalFormat df2 = new DecimalFormat("##############0.00");
private static DecimalFormat df2Format = new DecimalFormat("###,###,###,###,##0.00");
//四位小数
private static DecimalFormat df4 = new DecimalFormat("###,###,###,###,##0.0000");
//六位小数
private static DecimalFormat df6Number = new DecimalFormat("#######################0.000000");
private static DecimalFormat df6NumberF = new DecimalFormat("#,###,###,###,###,###,##0.000000");

public final static DecimalFormat stdAmountFormat = new DecimalFormat("###,###,###,###,##0.00");
public final static DecimalFormat stdNumberFormat = new DecimalFormat("#0.00");
public final static String DEF_NUM_TEN_THOUSAND = "10000";//万
public static final double MAX_VALUE = 9999999999999.99D;
public static final double MIN_VALUE = -9999999999999.99D;

private final static BigDecimal ONE_BIG = new BigDecimal(1.00D);
private static final String UNIT = "万仟佰拾亿仟佰拾万仟佰拾元角分";
private static final String DIGIT = "零壹贰叁肆伍陆柒捌玖";

/**
* 4舍5入double,2位小数
*/
public static double roundDouble(double src) {
return roundDouble(src, 2);
}

/**
* 4舍5入double,N 位小数
* @param src
* @param scale 小数位数
* @return
*/
public static double roundDouble(Object src, int scale) {
if (src == null) return 0.0;
String v = src.toString();
if (PubUtil.isEmpty(v)) return 0.0;
if (scale < 0) scale = 2;

BigDecimal src_b = new BigDecimal(v);
BigDecimal src_v = src_b.divide(ONE_BIG, scale + 2, BigDecimal.ROUND_HALF_UP);// 4舍5入
src_v = src_v.divide(ONE_BIG, scale, BigDecimal.ROUND_HALF_UP);// 4舍5入
return src_v.doubleValue();
}

/**
* 舍位处理,原生floor有坑,部分浮点数记录为.99999999999形式,导致floor结果错误
* @param d
* @return
*/
public static double floor(double d) {
return Math.floor(UtilMath.roundDouble(d, 2));
}

/**
* 比较两Double是否相等,将会吧他们专程BigDecimal进行比较;
*
* @param src double1
* @param tag double2
* @return src > tag 返回1, src < tag 返回-1, 否则返回0
*/
public static int compare(double src, double tag) {
BigDecimal src_b = new BigDecimal(src);
BigDecimal src_v = src_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入

BigDecimal tag_b = new BigDecimal(tag);
BigDecimal tag_v = tag_b.divide(ONE_BIG, 2, BigDecimal.ROUND_HALF_UP);// 4舍5入

return src_v.compareTo(tag_v);
}

/**
* 自动过滤金额中的逗号转换为double,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return double
*/
public static Double toDouble(String s) {
return todouble(s);
}

/**
* 自动过滤金额中的逗号转换为double,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return double
*/
public static double todouble(String s) {
try {
return Double.parseDouble(s.replaceAll(",", ""));
} catch (Exception e) {
return 0.00;
}
}

/**
* 获取double,主要过滤d为null的情况;
*
* @param d Double对象;
* @return double
*/
public static double todouble(Double d) {
if (d == null) return 0.0d;
return d.doubleValue();
}

/**
* 自动过滤金额中的逗号转换为float,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return Float
*/
public static Float toFloat(String s) {
return tofloat(s);
}

/**
* 自动过滤金额中的逗号转换为float,如果出错,则返回0
*
* @param s 源串,可能为带逗号的金额串;
* @return Float
*/
public static float tofloat(String s) {
try {
return Float.parseFloat(s.replaceAll(",", ""));
} catch (Exception e) {
return 0.0f;
}
}

public static long tolong(String src, long defaultvalue) {
try {
return Long.parseLong(src);
} catch (Exception e) {
return defaultvalue;
}
}

public static int toint(String src, int defaultvalue) {
try {
return Integer.parseInt(src);
} catch (Exception e) {
return defaultvalue;
}
}

/**
* 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001
*
* @param value double类型
* @return boolean
*/
public static boolean isBigThanZero(double value) {
return (value > 0.00001);
}

/**
* 考虑使用中的精度,判断一个Value是否>0,实际是>0.00001
*
* @param value String类型
* @return boolean
*/
public static boolean isBigThanZero(String value) {
return !PubUtil.isEmpty(value) && isBigThanZero(toDouble(value));
}

/**
* 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。
*
* @param value double类型
* @return boolean
*/
public static boolean isEqualsZero(double value) {
return (-0.00001 < value && value < 0.00001);
}

/**
* 考虑使用中的精度,判断一个Value是否=0,实际是给出一个值范围。
*
* @param value String类型
* @return boolean
*/
public static boolean isEqualsZero(String value) {
return PubUtil.isEmpty(value) || isEqualsZero(toDouble(value));
}

/**
* 是否是负数
*
* @param db_val 要判断的double
* @return 负数则返回true;
*/
public static boolean isNegative(double db_val) {
return (compare(db_val, 0.00D) == -1);
}

/**
* 是否是正数
*
* @param db_val 要判断的double
* @return 正数则返回true;
*/
public static boolean isPlus(double db_val) {
return (compare(db_val, 0.00D) == 1);
}

/**
* 得到金额字符串,保持小数点2位
*
* @param db 将double转换为金额字符串;
* @return 金额字符串#0.00;
*/
public static String toStdNumberString(double db) {
try {
return stdNumberFormat.format(db);
} catch (Exception e) {
return "0.00";
}
}

public static String toStdNumberStringEx(double db) {
try {
if (compare(db, -1d) == 0) return "-";
return stdNumberFormat.format(db);
} catch (Exception e) {
return "0.00";
}
}

/**
* 将金额格式字符串,如23,333,093.01 去掉逗号
*
* @param s 金额串
* @return String 去掉逗号后的串,如果amount为空,则返回0.00
*/
public static String toStdNumberString(String s) {
if (PubUtil.isEmpty(s))
return "0.00";
return stdNumberFormat.format(UtilMath.todouble(s));
}

/**
* 将数据转换为两位小数的数字格式;
*
* @param d 数据
* @param isZeroToEmpty 如果未0,是否返回“”;
* @return 两位小数的字符串;
*/
public static String toStdNumberString(double d, boolean isZeroToEmpty) {
if (isEqualsZero(d)) {
return isZeroToEmpty ? "": "0.00";
}
return stdNumberFormat.format(d);
}

public static String toStdNumberString(String s, boolean isZeroToEmpty) {
return toStdNumberString(UtilMath.todouble(s), isZeroToEmpty);
}

public static String toStdNumberString(double d, int scale) {
DecimalFormat dfn = null;
if (scale == 1) dfn = df1Format;
if (scale == 2) dfn = df2Format;
else if (scale == 4) dfn = df4;
else if (scale == 6) dfn = df6NumberF;
else if (scale <= 0) dfn = dfLong;
else {
StringBuilder sb = new StringBuilder("###,###,###,###,##0.");
for (int i = 0; i < scale; i++) sb.append("0");
dfn = new DecimalFormat(sb.toString());
}
return dfn.format(d);
}

/**
* 将数字乘100,保留小数点后两位, 然后后面添加%
*
* @param d 值
* @param isZeroToEmpty,如果值为0,是否返回空;
* @return 字符串;
*/
public static String toStdPercentNumberStr(double d, boolean isZeroToEmpty) {
if (d > -0.00000000001 && d < 0.00000000001) {
return isZeroToEmpty ? "": "0.00%";
}
return toStdNumberString(d * 100) + "%";
}


public static String toStdAmountString(double d) {
return toStdAmountString(d, false);
}

/**
* 将数据转换为两位小数的金额格式,带逗号;
*
* @param d 数据
* @param isZeroToEmpty 如果未0,是否返回“”;
* @return 金额格式的字符串;
*/
public static String toStdAmountString(double d, boolean isZeroToEmpty) {
if (isEqualsZero(d)) {
return isZeroToEmpty ? "": "0.00";
}
return stdAmountFormat.format(d);
}

public static String toStdAmountString(String s) {
return toStdAmountString(UtilMath.todouble(s), false);
}

public static String toStdAmountString(String s, boolean isZeroToEmpty) {
return toStdAmountString(UtilMath.todouble(s), isZeroToEmpty);
}


/**
* 将小写金额转换为人民币大写金额
*
* @param s 金额格式的串
* @return String 转换结果
*/
public static String toCapsAmountString(String s) {
if (PubUtil.isEmpty(s)) return "";
return toCapsAmountString(todouble(s));
}

/**
* 将小写金额转换为人民币大写金额
*
* @param v double
* @return String 转换结果
*/
public static String toCapsAmountString(double v) {
if (v < MIN_VALUE || v > MAX_VALUE) return "参数非法!";

boolean negative = isNegative(v);

if (negative) v = Math.abs(v);
long l = Math.round(v * 100);
if (l == 0) return "零元整";

String strValue = String.valueOf(l);
// i用来控制数
int i = 0;
// j用来控制单位
int j = UNIT.length() - strValue.length();
StringBuilder rs = new StringBuilder(32);
boolean isZero = false;
for (; i < strValue.length(); i++, j++) {
char ch = strValue.charAt(i);
if (ch == '0') {
isZero = true;
if (UNIT.charAt(j) == '亿' || UNIT.charAt(j) == '万' || UNIT.charAt(j) == '元') {
rs.append(UNIT.charAt(j));
isZero = false;
}
} else {
if (isZero) {
rs.append('零');
isZero = false;
}
rs.append(DIGIT.charAt(ch - '0')).append(UNIT.charAt(j));
}
}
if (rs.charAt(rs.length() - 1) != '分')
rs.append('整');

i = rs.indexOf("亿万");
if (i > 0) rs.delete(i + 1, i + 2); // i+1 ->万

if (negative)
return rs.insert(0, '负').toString();
else
return rs.toString();
}

/**
* 返回0 到 maxvalue的随机数
*
* @param maxvalue 随机数的最大值
* @return int
*/
public static int rnd(int maxvalue) {
return (int) (Math.random() * (maxvalue + 1));
}


public static double chkDbNull(Double v) {
return v == null ? 0: v;
}

public static double max(double d1, double d2) {
return compare(d1, d2) < 0 ? d2 : d1;
}

public static double min(double d1, double d2) {
return compare(d1, d2) < 0 ? d1 : d2;
}


public static void main(String[] args) {
double aa=123456789.345678900005;
System.out.println("args0 = " + upDouble(aa,0));
System.out.println("args1 = " + upDouble(aa,1));
System.out.println("args2 = " + upDouble(aa,2));
System.out.println("args3 = " + upDouble(aa,3));
System.out.println("args4 = " + upDouble(aa,4));
System.out.println("args5 = " + upDouble(aa,5));
System.out.println("args5 = " + upDouble(aa,6));
System.out.println("args5 = " + upDouble(aa,7));
System.out.println("args5 = " + upDouble(aa,8));

}

/**
* double 去尾法
* @param src 待处理数据
* @param scale 保留小数位数
* @return
*/
public static double cutDouble(double src, int scale){
String v = toStdNumberString(src, 6);//先到6位小数,再去计算,否则容易出错,如8.3成8.29999999999,舍位就成了8.29了
DecimalFormat formater = new DecimalFormat();
formater.setMaximumFractionDigits(scale);
formater.setGroupingSize(0);
formater.setRoundingMode(RoundingMode.FLOOR);
return new BigDecimal(formater.format(toDouble(v))).doubleValue();
}

/**
* double 进位法
* @param src 待处理数据
* @param scale 保留小数位数
* @return
*/
public static double upDouble(double src, int scale){
String v = toStdNumberString(src, 6);//先到6位小数,再去计算
DecimalFormat formater = new DecimalFormat();
formater.setMaximumFractionDigits(scale);
formater.setGroupingSize(0);
formater.setRoundingMode(RoundingMode.UP);
return new BigDecimal(formater.format(toDouble(v))).doubleValue();
}
}

+ 504
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/UtilString.java Целия файл

@@ -0,0 +1,504 @@
package cc.smtweb.system.bpm.util;


import cc.smtweb.framework.core.util.PubUtil;

import java.text.Collator;
import java.util.*;

/**
* Created with IntelliJ IDEA.
* User: AKhh
* Date: 12-12-24 下午5:09
* To change this template use File | Settings | File Templates.
*/
@SuppressWarnings("UnusedDeclaration")
public class UtilString {
private static Collator chineseCollator = Collator.getInstance(Locale.CHINA);

/**
* strSrc中寻找第一个strSe并且返回以其分隔的Left部分,汉字长度也为1
*
* @param strSrc 源字符串
* @param strSe 分割字符
* @return String 返回
*/
public static String getLeft(String strSrc, String strSe) {
if (PubUtil.isEmpty(strSrc))
return "";
if (PubUtil.isEmpty(strSe))
strSe = " ";

String result = "";
int pos = strSrc.indexOf(strSe);
if (pos >= 0)
result = strSrc.substring(0, pos);
return result;
}

/**
* 返回字符串的左边部分,汉字长度也为1
*
* @param strSrc 源串,如果为空,则返回“”;
* @param count 要获取的右边字符串长度,负数将返回“”,如果count>字符串长度,则返回整个字符串;
* @return String return
*/
public static String getLeft(String strSrc, int count) {
if (PubUtil.isEmpty(strSrc) || count <= 0) {
return "";
}
if (strSrc.length() < count) {
return strSrc;
} else {
return strSrc.substring(0, count);
}
}

/**
* strSrc中寻找第一个strSe并且返回以其分隔的Right部分,汉字长度也为1
*
* @param strSrc 源串
* @param strSe 分隔符,一个字符
* @return String right部分
*/
public static String getRight(String strSrc, String strSe) {
if (PubUtil.isEmpty(strSrc))
return "";
if (PubUtil.isEmpty(strSe))
strSe = " ";

String result = strSrc;
int pos = strSrc.indexOf(strSe);
if (pos >= 0)
result = strSrc.substring(pos + strSe.length());
return result;
}

/**
* 返回字符串的右边部分,汉字长度也为1
*
* @param strSrc 源串
* @param count 要获取的右边字符串长度,负数将返回“”,如果count>字符串长度,则返回整个字符串;
* @return String return
*/
public static String getRight(String strSrc, int count) {
if (PubUtil.isEmpty(strSrc) || count <= 0) {
return "";
}
int l = strSrc.length();
if (l <= count) {
return strSrc;
}
return strSrc.substring(l - count);
}

/**
* 左边补齐字符
*
* @param src 源串
* @param pad 补齐字符
* @param length 最终长度
* @return 补齐后的字符串
*/
public static String padLeft(String src, String pad, int length) {
StringBuilder sb = new StringBuilder(repeatString(pad, length));
sb.append(src);
return sb.substring(sb.length() - length);
}

public static String padLeft(long src, String pad, int length) {
StringBuilder sb = new StringBuilder(repeatString(pad, length));
sb.append(src);
return sb.substring(sb.length() - length);
}

public static String padRight(String src, String pad, int length) {
StringBuilder sb = new StringBuilder(length * pad.length() + src.length());
sb.append(src).append(repeatString(pad, length));
return sb.substring(0, length);
}

public static String padRight(long src, String pad, int length) {
StringBuilder sb = new StringBuilder(length * pad.length());
sb.append(src).append(repeatString(pad, length));
return sb.substring(0, length);
}

/**
* 由于jdk1.3提供的replace函数不能满足替换要求,自己写一个
*
* @param src 源串
* @param oldS 将...
* @param newS 替换成...
* @return 替换后的字符串
*/
public static String replaceString(String src, String oldS, String newS) {
StringBuilder ret = new StringBuilder(64);
int pos = src.indexOf(oldS);
while (pos >= 0) {
ret.append(src, 0, pos).append(newS);
src = src.substring(pos + oldS.length());
pos = src.indexOf(oldS);
}
ret.append(src);
return ret.toString();
}

/**
* 取得指定字符串左边的有效数字,首先去掉两边空格
*
* @param s 源串
* @return 串左边的有效数字
*/
public static String getStringLeftNumber(String s) {
String ret = "";
int dotCount = 0;
s = s.trim();
char[] carr = s.toCharArray();
for (char aCarr : carr) {
if (Character.isDigit(aCarr)) {
ret += aCarr;
} else if (aCarr == '.' && dotCount == 0) {
ret += aCarr;
dotCount++;
} else {
break;
}
}
if (ret.endsWith(".")) {
ret = ret.substring(0, ret.length() - 1);
}
return ret;
}

/**
* 取得重复字串
*
* @param repeatString 重复字串
* @param count 重复次数
* @return String
*/
public static String repeatString(String repeatString, int count) {
if (count <= 0) return "";
StringBuilder ret = new StringBuilder(repeatString.length() * count);
for (int i = 1; i <= count; i++) {
ret.append(repeatString);
}
return ret.toString();
}

/**
* 去除字符串左边的指定字符串
*
* @param src 源字符串
* @param cut 要去掉的字符串;
* @return 处理结果
*/
public static String cutStringLeft(String src, String cut) {
if (PubUtil.isEmpty(src) || PubUtil.isEmpty(cut)) {
return "";
}
if (src.startsWith(cut)) {
return cutStringLeft(src.substring(cut.length()), cut);
} else {
return src;
}
}

public static String cutStringRight(String src, String cut) {
if (PubUtil.isEmpty(src) || PubUtil.isEmpty(cut)) {
return "";
}
while (src.endsWith(cut))
src = src.substring(0, src.length() - cut.length());

return src;
}

/**
* Removes all spaces from a string
* 可以替换大部分空白字符, 不限于空格,\s 可以匹配空格、制表符、换页符等空白字符的其中任意一个
*/
public static String removeSpaces(String str) {
return str.replaceAll("\\s*", "");
}

/**
* Creates a single string from a List of strings seperated by a delimiter.
*
* @param list a list of strings to join
* @param delim the delimiter character(s) to use. (null value will join with no delimiter)
* @return a String of all values in the list seperated by the delimiter
*/
public static String join(List<String> list, String delim) {
if (list == null || list.size() < 1)
return null;
StringBuffer buf = new StringBuffer();
Iterator i = list.iterator();

while (i.hasNext()) {
buf.append((String) i.next());
if (i.hasNext())
buf.append(delim);
}
return buf.toString();
}

/**
* Splits a String on a delimiter into a List of Strings.
*
* @param str the String to split
* @param delim the delimiter character(s) to join on (null will split on whitespace)
* @return a list of Strings
*/
public static List<String> split(String str, String delim) {
List<String> splitList = new ArrayList<>();
StringTokenizer st;
if (str == null)
return splitList;

if (delim != null)
st = new StringTokenizer(str, delim);
else
st = new StringTokenizer(str);

while (st.hasMoreTokens()) {
splitList.add(st.nextToken());
}
return splitList;
}

//是否为true,(1,y,true,yes)
public static boolean toBoolean(String v) {
return "1".equals(v) || "y".equalsIgnoreCase(v) || "true".equalsIgnoreCase(v) || "yes".equalsIgnoreCase(v);
}

public static int chineseCompare(String s1, String s2) {
return chineseCollator.compare(s1, s2);
}

/**
* 按照编码级次,得到类型的真实编码,主要用于like 'parentCode%'
* getSplitTypeCode('GF82000',2, 2, 1) == GF82
* getSplitTypeCode('GF82100',3, 2, 1) == GF821
* getSplitTypeCode('82100' ,3, 0, 1) == 821
*
* @param curLevel 当前编码的所在层次
* @param startIndex 数字编码的开始选项
* @param perSize 每层的数字编码长度
*/
public static String getRealCode(String code, int curLevel, int startIndex, int perSize) {
StringBuilder sb = new StringBuilder(code.length());
if (startIndex > 0) sb.append(code, 0, startIndex);
for (int i = startIndex, l = 0; i < code.length(); i += perSize) {
if (l < curLevel) {
sb.append(code, i, i + perSize);
++l;
} else {
break;
}
}
return sb.toString();
}

//函数功能: 正整数
public static boolean isPureNumber(String inputString) {
return inputString.matches("^[1-9]\\d*$");
}

//函数功能: 整数
public static boolean isNumber(String inputString) {
return inputString.matches("^[-+][0-9]\\d*$");
}

//函数功能: 浮点数
public static boolean isAmount(String inputString) {
return inputString.matches("^[-+]?[\\d,]+(\\.\\d+)?$");
}

//函数功能: 带千分号的整数
public static boolean isFormatNumber(String inputString) {
return inputString.matches("^[-+]?[\\d,]+(\\d+)?$");
}


//首字母大写
public static String upFirst(String s) {
return s.substring(0, 1).toUpperCase() + s.substring(1);
}

public static String padRightBytes(String src, String pad, int length) {
length -= src.replaceAll("[^\\x00-\\xff]", "**").length();
return src + repeatString(pad, length);
}

//按字节数取子串,begin不是按字节的
public static String substrByte(String src, int begin, int len) {
StringBuilder sb = new StringBuilder(32);
char c;
int tl = src.length();
for (int i = begin; i < len + begin && i < tl; i++) {

c = src.charAt(i);
sb.append(c);
if (String.valueOf(c).replaceAll("[^\\x00-\\xff]", "**").length() > 1) {
// 遇到中文汉字,截取字节总数减1
--len;
}
}
return sb.toString();
}

/**
* 通配符算法。 可以匹配"*"和"?"
* 如a*b?d可以匹配aAAAbcd
*
* @param pattern 匹配表达式
* @param str 匹配的字符串
* @return
*/
public static boolean match(String pattern, String str) {
if (pattern == null || str == null)
return false;

boolean result = false;
char c; // 当前要匹配的字符串
boolean beforeStar = false; // 是否遇到通配符*
int back_i = 0;// 回溯,当遇到通配符时,匹配不成功则回溯
int back_j = 0;
int i, j;
for (i = 0, j = 0; i < str.length(); ) {
if (pattern.length() <= j) {
if (back_i != 0) {// 有通配符,但是匹配未成功,回溯
beforeStar = true;
i = back_i;
j = back_j;
back_i = 0;
back_j = 0;
continue;
}
break;
}

if ((c = pattern.charAt(j)) == '*') {
if (j == pattern.length() - 1) {// 通配符已经在末尾,返回true
result = true;
break;
}
beforeStar = true;
j++;
continue;
}

if (beforeStar) {
if (str.charAt(i) == c) {
beforeStar = false;
back_i = i + 1;
back_j = j;
j++;
}
} else {
if (c != '?' && c != str.charAt(i)) {
result = false;
if (back_i != 0) {// 有通配符,但是匹配未成功,回溯
beforeStar = true;
i = back_i;
j = back_j;
back_i = 0;
back_j = 0;
continue;
}
break;
}
j++;
}
i++;
}

if (i == str.length() && j == pattern.length())// 全部遍历完毕
result = true;
return result;
}

//填充变量
public static String myReplaceStrEx(String express, String b, String e, IStrHanlder hanlder) {
if (null == express) return express;
int keyBegin = 0, keyEnd = 0;
int lb = b.length(), le = e.length();
String fn;
while (true) {
keyBegin = express.indexOf(b, keyBegin);
if (keyBegin < 0) break;
keyEnd = express.indexOf(e, keyBegin);
if (keyEnd <= keyBegin) break;
keyBegin++;
fn = express.substring(keyBegin + lb - 1, keyEnd);
fn = hanlder.work(fn);
if (fn != null) {
express = express.substring(0, keyBegin - 1) + fn + express.substring(keyEnd + le);
}
}
return express;
}

//填充变量
public static String myReplaceStrEx(String express, String b, String e, final Map<String, String> mapVals) {
return myReplaceStrEx(express, b, e, new IStrHanlder() {
@Override
public String work(String src) {
return PubUtil.checkNull(mapVals.get(src));
}
});
}

/*Blob转String*/
// public static String blob2Str(Blob blob) {
// if (blob == null) return "";
// ByteArrayOutputStream outStream = null;
// try {
// long len = blob.length();
// if (len == 0L) return "";
// byte[] bytes;
// long i = 1L;
// outStream = new ByteArrayOutputStream();
// while (i < len) {
// bytes = blob.getBytes(i, 1024);
// i += 1024L;
// outStream.write(bytes);
// }
//
// return UtilEncode.base64EncodeB(outStream.toByteArray());
// } catch (Exception e) {
// e.printStackTrace();
// return "";
// } finally {
// IOUtils.closeQuietly(outStream);
// }
// }


public interface IStrHanlder {
String work(String src);
}

public static int[] splitStr(String src, String ch) {
String[] ss = src.split(ch);
int[] ret = new int[ss.length];
for (int i = 0, len = ss.length; i < len; i++) {
ret[i] = PubUtil.getIntIgnoreErr(ss[i]);
}
return ret;
}

public static void main(String[] args) {
String s = "a[#[#123#]bcde[aaa]bcd";
s = UtilString.myReplaceStrEx(s, "[#", "#]", new UtilString.IStrHanlder() {
@Override
public String work(String src) {
if (src.equals("123")) return "1";
return null;
}
});
System.out.println(s);
}
}

+ 6
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpTask.java Целия файл

@@ -0,0 +1,6 @@
package cc.smtweb.system.bpm.util.ftp;

//FTP执行接口
public interface FtpTask {
Object execute(IFtpUtil ftp) throws Exception;
}

+ 255
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpTaskManager.java Целия файл

@@ -0,0 +1,255 @@
package cc.smtweb.system.bpm.util.ftp;



import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.util.UtilLogger;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//ftp管理类
public class FtpTaskManager {
private static Map<String, FtpTaskManager> mapInstance = null;

static {
mapInstance = new HashMap<>();
}

//多线程
private Map<Thread, IFtpUtil> mapThreadFtp = new HashMap<>();

public static FtpTaskManager getInstance(String key, IFtpServerConfig ftpConfig) {
key = key + "_" + (ftpConfig.isSFTP() ? 1 : 0) + ftpConfig.getServerIp() + "_" + ftpConfig.getPort() + "_" + ftpConfig.getUserName();
FtpTaskManager instance = mapInstance.get(key);
if (instance == null) {
synchronized (FtpTaskManager.class) {
instance = mapInstance.get(key);
if (instance == null) {
FtpTaskManager inst = new FtpTaskManager();
inst.init(ftpConfig);
instance = inst;
mapInstance.put(key, instance);
}
}
}
return instance;
}

private IFtpServerConfig ftpConfig = null;

public FtpTaskManager() {
}

//初始化配置信息
public void init(IFtpServerConfig ftpConfig) {
this.ftpConfig = ftpConfig;
}

//获取一个ftp客户端
public IFtpUtil getFtpUtil() {
IFtpUtil ftp = mapThreadFtp.get(Thread.currentThread());
if (ftp != null) return ftp;

ftp = ftpConfig.isSFTP() ? new SFtpUtil() : new FtpUtil();
boolean isConnect = ftp.login(ftpConfig);
if (isConnect) {
UtilLogger.info("FTP连接成功!");
} else {
UtilLogger.info("FTP连接失败!" + ftpConfig.getServerIp() + " " + ftpConfig.getPort() + " " + ftpConfig.getUserName() + " " + ftpConfig.getPassword());
}
return ftp;
}

//获取并加到线程中备用
public IFtpUtil getThreadFtpUtil() {
IFtpUtil ftp = getFtpUtil();
ftp.setAutoFree(false);
mapThreadFtp.put(Thread.currentThread(), ftp);
return ftp;
}

//释放,和getThreadFtpUtil配对
public void dispose() {
IFtpUtil ftp = mapThreadFtp.remove(Thread.currentThread());
if (ftp == null) return;
ftp.setAutoFree(true);
ftp.disconnect();
}

/**
* 直接执行一个Ftp任务
*/
public Object execute(FtpTask ftpTask) throws Exception {
IFtpUtil ftp = getFtpUtil();
if (!ftp.isConnected())
throw new Exception("FTP连接失败(" + ftpConfig.getServerIp() + "/" + ftpConfig.getUserName() + "/" + (ftpConfig.isSFTP() ? "sftp" : "ftp") + ")。");
try {
return ftpTask.execute(ftp);
} finally {
ftp.disconnect();
}
}

//上传文件到Ftp服务器。传完后,根据设置删除本地文件
public void uploadToFtp(final String remoteAttachName,
final String remoteFolderPath, final String localAttach,
final boolean isDelLocal) throws Exception {
uploadToFtp(remoteAttachName, remoteFolderPath, new File(localAttach), isDelLocal);
}

public void uploadToFtp(final String remoteAttachName,
final String remoteFolderPath, final File localFile,
final boolean isDelLocal) throws Exception {
this.execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
if (ftp.uploadFile(remoteFolderPath, remoteAttachName, localFile)) {
if (isDelLocal) {//删除本地服务器的相应附件
localFile.delete();
}
}
return null;
}
});
}

private String getBakPath(String path) {
path = PubUtil.isEmpty(path) ? DateUtil.getNowYm() : path;
return "bak/" + path + "/";
}

//上传文件到Ftp服务器。传完后,根据设置删除本地文件
public void downloadFile(final String remoteAttachName,
final String remoteFolderPath, final String localFile, final boolean isDelLocal) throws Exception {
this.execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
if (!ftp.existsFile(remoteFolderPath, remoteAttachName)) {
throw new Exception("服务器文件【" + remoteFolderPath + "/" + remoteAttachName + "】不存在!");
}
ftp.downloadFileEx(remoteFolderPath, remoteAttachName, localFile);
if (isDelLocal) {
ftp.setRemoteDir("/");
final String bakPath = getBakPath(null);
ftp.mkdir(remoteFolderPath + "/" + bakPath);
ftp.rename(remoteFolderPath, remoteAttachName, bakPath + remoteAttachName);
}
return null;
}
});
}

public void delAndBakFile(String remoteFolderPath, String remoteAttachName) throws Exception {
delAndBakFile(remoteFolderPath, remoteAttachName, null);

}

public void delAndBakFile(String remoteFolderPath, String remoteAttachName, String bakPath) throws Exception {
this.execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
if (!ftp.existsFile(remoteFolderPath, remoteAttachName)) return null;

String path = getBakPath(bakPath);
ftp.setRemoteDir("/");
ftp.mkdir(remoteFolderPath + "/" + path);
ftp.rename(remoteFolderPath, remoteAttachName, path + remoteAttachName);

return null;
}
});
}
public void delFile(String delPath, String fileName) throws Exception {
this.execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
if (!ftp.existsFile(delPath, fileName)) return null;
ftp.deleteFile(delPath,fileName );
return null;
}
});
}
//从服务器下载文件到本地。传完后,根据设置删除远程目录文件
public String[] listFileNames(final String remotePath) throws Exception {
IFtpUtil ftp = getFtpUtil();
if (!ftp.isConnected()) return new String[0];
String[] fileNames;
try {
fileNames = ftp.listFileNames(remotePath);
} finally {
ftp.disconnect();
}
return fileNames;
}

public String[] downFolder(final String remotePath, final String localPath, final boolean isDelLocal, final IDownloadFileWorker worker, final String fileNamePrefix) throws Exception {
final String[] files = listFileNames(remotePath);
List<String> list = new ArrayList<>();
this.execute(new FtpTask() {
public Object execute(IFtpUtil ftp) throws Exception {
for (String file : files) {
if (worker != null && !worker.isDownload(file, fileNamePrefix)) continue;
if (PubUtil.isNotEmptyId(fileNamePrefix) && !file.startsWith(fileNamePrefix)) continue;
ftp.downloadFileEx(remotePath, file, localPath + "/" + file);
if (isDelLocal) {
ftp.setRemoteDir("/");
final String bakPath = getBakPath(null);
ftp.mkdir(remotePath + "/" + bakPath);
ftp.rename(remotePath, file, bakPath + file);
}
list.add(file);
}
return null;
}
});
return list.toArray(new String[list.size()]);
}

public static void main(String[] args) throws Exception {
FtpTaskManager ftp = FtpTaskManager.getInstance("test", new IFtpServerConfig() {
@Override
public boolean isSFTP() {
return false;
}

@Override
public String getServerIp() {
return "127.0.0.1";
}

@Override
public Integer getPort() {
return 21;
}

@Override
public String getUserName() {
return "demo";
}

@Override
public String getPassword() {
return "1";
}
});
ftp.uploadToFtp("S_2.jpg", "/", "f:\\temp\\tmp\\S_2.jpg", false);
// ftp.uploadToFtp("民族5.png", "/", "f:\\temp\\temp\\民族5.png", false);
// ftp.getThreadFtpUtil();
// ftp.uploadToFtp("民族1.png", "/", "f:\\temp\\temp\\民族1.png", false);

// ftp.uploadToFtp("民族2.png", "/", "f:\\temp\\temp\\民族2.png", false);
// ftp.uploadToFtp("民族3.png", "/", "f:\\temp\\temp\\民族3.png", false);
// ftp.downloadFile("民族2.png", "/", "f:/temp/民族2.png", true);
/*String[] ss = ftp.downFolder("/", "f:/temp/test", true);
for (String s: ss) {
System.out.println(s);
}*/

ftp.downloadFile("S_1.jpg", "/", "f:/temp/S_21.jpg", true);
// ftp.downloadFile("freesshd.log", "/", "f:/temp/freesshd.log", false);
//ftp.downFolder("data/11", "f:/temp/11", true, "");

ftp.dispose();
}
}

+ 393
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/FtpUtil.java Целия файл

@@ -0,0 +1,393 @@
package cc.smtweb.system.bpm.util.ftp;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilLogger;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

import java.io.*;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
* 一个ftp的封装类
*/
@SuppressWarnings("UnusedDeclaration")
public class FtpUtil implements IFtpUtil {
private static final int LOGIN_REPEAT_TIMES = 1;
private FTPClient ftpClient;
private boolean autoFree = true;
private IFtpServerConfig ftpConf;

public FtpUtil() {
this.ftpClient = new FTPClient();
}

@Override
public boolean isAutoFree() {
return autoFree;
}

@Override
public void setAutoFree(boolean autoFree) {
this.autoFree = autoFree;
}

//登录ftp
@Override
public boolean login(IFtpServerConfig ftpConf) {
try {
this.ftpConf = ftpConf;
return login(ftpConf.getServerIp(), ftpConf.getPort(), ftpConf.getUserName(), ftpConf.getPassword());
} catch (Exception e) {
logError("ftp登录失败", e);
return false;
}
}

//退出ftp
@Override
public void logout() {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
}
} catch (IOException e) {
logError("ftp退出登录失败", e);
}
}

//是否连接正常
@Override
public boolean isConnected() {
if (!ftpClient.isConnected())
return false;
try {
return ftpClient.sendNoOp();
} catch (IOException e) {
logError("ftp测试连接失败", e);
return false;
}
}

//设置远程目录
@Override
public boolean setRemoteDir(String path) {
try {
String d = gbktoiso8859(path);
ftpClient.changeWorkingDirectory("/");
if (!ftpClient.changeWorkingDirectory(d)) {
String[] paths = d.split("/");
for (String pa : paths) {
if (!ftpClient.changeWorkingDirectory(pa)) {
ftpClient.mkd(pa);
ftpClient.changeWorkingDirectory(pa);
}
}
}
return true;
} catch (IOException e) {
logError("ftp设置远程目录失败", e);
return false;
}
}

/**
* 创建指定文件夹
*
* @param dirName dirName
*/
public void mkdir(String dirName) {
setRemoteDir("/");
dirName = gbktoiso8859(dirName);

try {
ftpClient.makeDirectory(dirName);
} catch (Exception e) {
logError("ftp创建远程目录错误", e);
}
}

//删除远程路径
@Override
public void deleteFolder(String path) {
try {
String d = gbktoiso8859(path);
ftpClient.removeDirectory(d);
} catch (IOException e) {
logError("ftp删除远程目录失败", e);
}
}

/**
* 从ftp下载文件到本地
*
* @param remotePath 远程路径
* @param fileName 文件名
* @param localPath 本地路径(不带文件名)
*/
@Override
public void downloadFile(String remotePath, String fileName, String localPath) throws Exception {
downloadFileEx(remotePath, fileName, localPath + File.separator + fileName);
}

public void setPassiveNatWorkaroundStrategy() {
ftpClient.setPassiveNatWorkaroundStrategy(new FTPClient.HostnameResolver() {
@Override
public String resolve(String hostname) throws UnknownHostException {
return ftpConf.getServerIp();
}
});
}

/**
* 下载文件到本地
*
* @param remotePath 远程路径
* @param fileName 远程文件名
* @param localFileName 本地完全文件名(路径+文件名)
*/
@Override
public void downloadFileEx(String remotePath, String fileName, String localFileName) throws Exception {
setPassiveNatWorkaroundStrategy();
ftpClient.enterLocalPassiveMode();
setRemoteDir(remotePath);//转移到FTP服务器目录
UtilLogger.info("跳转到FTP服务目录:" + remotePath);
File localFile = new File(localFileName);
if (!localFile.exists()) UtilFile.CreateFile(localFileName);
FileOutputStream is = null;
try {
is = new FileOutputStream(localFile);
ftpClient.retrieveFile(gbktoiso8859(fileName), is);
} catch (IOException e) {
localFile.deleteOnExit();
} finally {
is.close();
}
}

/**
* 下载文件成流,使用此方法需要注意,关闭流之后要调用completePendingCommand方法
*
* @param remotePath 远程路径
* @param fileName 远程文件名
* @return 文件流
*/
@Override
public InputStream downloadFile(String remotePath, String fileName) throws Exception {
try {
setPassiveNatWorkaroundStrategy();
ftpClient.enterLocalPassiveMode();
setRemoteDir(remotePath);//转移到FTP服务器目录
return ftpClient.retrieveFileStream(gbktoiso8859(fileName));
} catch (IOException e) {
logError("ftp下载文件失败", e);
return null;
}
}

/**
* 上传文件到ftp
*
* @param path 远程路径
* @param filename 远程文件名
* @param localFileName 本地文件(含路径)
* @return
*/
@Override
public boolean uploadFile(String path, String filename, String localFileName) throws Exception {
return uploadFile(path, filename, new File(localFileName));
}

@Override
public boolean uploadFile(String path, String filename, File localFile) throws Exception {
FileInputStream in = null;
try {
setPassiveNatWorkaroundStrategy();
ftpClient.enterLocalPassiveMode();
in = new FileInputStream(localFile);
setRemoteDir(path);
boolean b = ftpClient.storeFile(gbktoiso8859(filename), in);
if (!b) throw new Exception("FTP上传失败,请检查服务器配置!");
return b;
} finally {
if (in != null) in.close();
}
}

/**
* 删除远程文件
*
* @param path 远程路径
* @param filename 远程文件名
*/
@Override
public void deleteFile(String path, String filename) {
try {
setPassiveNatWorkaroundStrategy();
setRemoteDir(path);
ftpClient.dele(gbktoiso8859(filename));
} catch (IOException e) {
logError("删除文件失败", e);
}
}

@Override
public boolean existsFile(String path, String filename) {
try {
setPassiveNatWorkaroundStrategy();
ftpClient.enterLocalPassiveMode();//设置被动模式
setRemoteDir(path);
String[] files = ftpClient.listNames(gbktoiso8859(filename));
return PubUtil.isNotEmpty(files);
} catch (IOException e) {
logError("判断文件是否存在失败", e);
return false;
}
}

@Override
public boolean rename(String path, String from, String to) {
try {
setPassiveNatWorkaroundStrategy();
setRemoteDir(path);
return ftpClient.rename(gbktoiso8859(from), gbktoiso8859(to));
} catch (IOException e) {
logError("重命名文件失败", e);
return false;
}
}

//调用返回流的方法,在处理完流后,要调用此方法。
@Override
public boolean completePendingCommand() {
try {
setPassiveNatWorkaroundStrategy();
return ftpClient.completePendingCommand();
} catch (IOException e) {
UtilLogger.error("ftp关闭流出错", e);
return false;
}
}

//断开连接
public FTPFile[] listFiles(String remotePath) throws IOException {
setPassiveNatWorkaroundStrategy();
return ftpClient.listFiles(remotePath);
}

//断开连接
@Override
public String[] listFileNames(String remotePath) throws Exception {
setPassiveNatWorkaroundStrategy();
setRemoteDir("/");
setRemoteDir(remotePath);
ftpClient.enterLocalPassiveMode();//设置被动模式
String[] files = ftpClient.listNames("");
List<String> list = new ArrayList<>();
for (String s : files) {
if (!ftpClient.changeWorkingDirectory(s)) {
s = new String(s.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
list.add(s);
} else {
ftpClient.changeToParentDirectory();
}
}
return list.toArray(new String[list.size()]);
}

//断开连接
@Override
public String[] listAllFileNames(String remotePath) throws Exception {
setPassiveNatWorkaroundStrategy();
setRemoteDir("/");
setRemoteDir(remotePath);
ftpClient.enterLocalPassiveMode();//设置被动模式
String[] files = ftpClient.listNames("");
List<String> list = new ArrayList<>();
for (String s : files) {
s = new String(s.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
list.add(s);
}
return list.toArray(new String[list.size()]);
}


//断开连接
@Override
public void disconnect() {
if (isAutoFree() && ftpClient.isConnected()) {
try {
setPassiveNatWorkaroundStrategy();
ftpClient.disconnect();
} catch (IOException ignored) {
}
}
}

//登录
protected boolean login(String server, int port, String user, String password) throws Exception {
for (int i = 0; i < LOGIN_REPEAT_TIMES; i++) {
ftpClient.setConnectTimeout(10000);
//if (!ftpClient.isConnected()) {
connect(server, port);
if (!ftpClient.isConnected()) continue;
//}
if (ftpClient.login(user, password)) {
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setDataTimeout(120000);
return true;
}
ftpClient.logout();
Thread.sleep(100L);
}
disconnect();
return false;
}

//连接
private void connect(String server, int port) throws Exception {
disconnect();
ftpClient.setDefaultPort(port);
ftpClient.connect(server);
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new Exception("服务器拒绝连接。");
}
}

private void logError(String msg, Exception e) {
UtilLogger.debug(msg + " " + e.getMessage());
}

//编码转换
private static String gbktoiso8859(String gbk) {
try {
if (gbk == null)
return "";
else //iso-8859-1
return new String(gbk.getBytes("GBK"), StandardCharsets.ISO_8859_1);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}

//编码转换
private static String iso8859toutf8(String gbk) {
try {
if (gbk == null)
return "";
else //iso-8859-1
return new String(gbk.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}

+ 6
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IDownloadFileWorker.java Целия файл

@@ -0,0 +1,6 @@
package cc.smtweb.system.bpm.util.ftp;

public interface IDownloadFileWorker {

boolean isDownload(String file, String fileNamePrefix);
}

+ 16
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpServerConfig.java Целия файл

@@ -0,0 +1,16 @@
package cc.smtweb.system.bpm.util.ftp;

/**
* Created by AKmm at 2009-5-21 16:41:25
* ftp服务器参数配置接口
*/
public interface IFtpServerConfig {
boolean isSFTP();
String getServerIp();

Integer getPort();

String getUserName();

String getPassword();
}

+ 59
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/IFtpUtil.java Целия файл

@@ -0,0 +1,59 @@
package cc.smtweb.system.bpm.util.ftp;

import java.io.File;
import java.io.InputStream;

/**
* Created by Akmm at 2015-12-08 14:33
*/
public interface IFtpUtil {
//是否自动删除
boolean isAutoFree();
//设置自动删除
void setAutoFree(boolean autoFree);
//登录ftp
boolean login(IFtpServerConfig ftpConf);
//退出ftp
void logout();

//是否连接正常
boolean isConnected();

//设置远程目录
boolean setRemoteDir(String path);
void mkdir(String dirName);

//删除远程路径
void deleteFolder(String path);

void downloadFile(String remotePath, String fileName, String localPath) throws Exception;

void downloadFileEx(String remotePath, String fileName, String localFileName) throws Exception;

InputStream downloadFile(String remotePath, String fileName) throws Exception;

boolean uploadFile(String path, String filename, String localFileName) throws Exception;

boolean uploadFile(String path, String filename, File localFile) throws Exception;

void deleteFile(String path, String filename);
//判断文件是否存在
boolean existsFile(String path, String filename);

//调用返回流的方法,在处理完流后,要调用此方法。
boolean completePendingCommand();

//断开连接
// FTPFile[] listFiles(String remotePath) throws IOException;

//枚举文件名
String[] listFileNames(String remotePath) throws Exception;

//枚举文件名,包含文件夹
String[] listAllFileNames(String remotePath) throws Exception;

//断开连接
void disconnect();

boolean rename(String remotePath, String from, String to) throws Exception;
}

+ 396
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/util/ftp/SFtpUtil.java Целия файл

@@ -0,0 +1,396 @@
package cc.smtweb.system.bpm.util.ftp;

import cc.smtweb.framework.core.util.PubUtil;
import cc.smtweb.system.bpm.util.UtilFile;
import cc.smtweb.system.bpm.util.UtilLogger;
import com.jcraft.jsch.*;
import org.apache.commons.io.IOUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
* 一个sftp的封装类
*/
@SuppressWarnings("UnusedDeclaration")
public class SFtpUtil implements IFtpUtil {
private static final int LOGIN_REPEAT_TIMES = 1;
private ChannelSftp sftp;
private boolean autoFree = true;

public SFtpUtil() {
this.sftp = null;
}

@Override
public boolean isAutoFree() {
return autoFree;
}

@Override
public void setAutoFree(boolean autoFree) {
this.autoFree = autoFree;
}

//登录ftp
@Override
public boolean login(IFtpServerConfig ftpConf) {
try {
int count = 0;
while (count < 3) {
// 设置超时时间为 5s
count++;
try {
JSch jsch = new JSch();
jsch.getSession(ftpConf.getUserName(), ftpConf.getServerIp(), ftpConf.getPort());
Session sshSession = jsch.getSession(ftpConf.getUserName(), ftpConf.getServerIp(), ftpConf.getPort());
System.out.println("Session created.");
sshSession.setPassword(ftpConf.getPassword());
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.setTimeout(10 * 1000);
sshSession.connect();
UtilLogger.debug("Session connected[" + count + "/3].");
UtilLogger.debug("Opening Channel[" + count + "/3].");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
UtilLogger.debug("已连接到 " + ftpConf.getServerIp() + ";");
return true;
} catch (Exception e) {
UtilLogger.debug("connect fail[" + count + "/3]:" + PubUtil.getOrigMsg(e));
}
}
UtilLogger.debug("sftp登录失败:3次连接超时...");
return false;
} catch (Exception e) {
logError("sftp登录失败", e);
return false;
}
}

//退出ftp
@Override
public void logout() {
disconnect();
}

//是否连接正常
@Override
public boolean isConnected() {
return sftp != null && sftp.isConnected();
/*try {
return sftpClient.sendSignal();
} catch (IOException e) {
logError("ftp测试连接失败", e);
return false;
}*/
}

//设置远程目录
@Override
public boolean setRemoteDir(String path) {
String d = path;
try {
sftp.cd("/");
sftp.cd(d);
return true;
} catch (Exception e) {
logError("sftp进远程目录失败[" + d + "],准备创建", e);
}

mkdir(d);
try {
sftp.cd(d);
return true;
} catch (Exception e) {
logError("sftp设置远程目录失败[" + d + "]", e);
return false;
}
}


private boolean openRemoteDir(String path) {
String d = path;
try {
sftp.cd(d);
return true;
} catch (Exception e) {
return false;
}
}

/**
* 创建指定文件夹
*
* @param dirName dirName
*/
public void mkdir(String dirName) {
String[] dirs = dirName.split("/");
try {
String now = sftp.pwd();
for (int i = 0; i < dirs.length; i++) {
if (PubUtil.isEmpty(dirs[i])) continue;
boolean dirExists = openRemoteDir(dirs[i]);
if (!dirExists) {
sftp.mkdir(dirs[i]);
sftp.cd(dirs[i]);
}
}
sftp.cd(now);
} catch (SftpException e) {
logError("sftp创建远程目录错误", e);
}
}

//删除远程路径
@Override
public void deleteFolder(String path) {
try {
String d = path;
sftp.rmdir(d);
} catch (Exception e) {
logError("sftp删除远程目录失败", e);
}
}

/**
* 从ftp下载文件到本地
*
* @param remotePath 远程路径
* @param fileName 文件名
* @param localPath 本地路径(不带文件名)
*/
@Override
public void downloadFile(String remotePath, String fileName, String localPath) throws Exception {
downloadFileEx(remotePath, fileName, localPath + File.separator + fileName);
}

public boolean isFileExists(String filePath, String fileName) throws Exception {
Vector<ChannelSftp.LsEntry> vector = sftp.ls(filePath);
Iterator<ChannelSftp.LsEntry> sftpFileNames = vector.iterator();
while (sftpFileNames.hasNext()) {
String name = sftpFileNames.next().getFilename();
if (name.equals(fileName)) {
return true;
}
}
return false;
}

/**
* 下载文件到本地
*
* @param remotePath 远程路径
* @param fileName 远程文件名
* @param localFileName 本地完全文件名(路径+文件名)
*/
@Override
public void downloadFileEx(String remotePath, String fileName, String localFileName) throws Exception {
if (!isFileExists(remotePath, fileName)) {
throw new Exception();
}
File file = null;
file = new File(localFileName);
if (!file.exists()) UtilFile.CreateFile(localFileName);
FileOutputStream output = null;

try {
String now = sftp.pwd();
sftp.cd(remotePath);
UtilLogger.info("跳转到SFTP服务目录:" + remotePath);

output = new FileOutputStream(file);
sftp.get(fileName, output);
sftp.cd(now);
} catch (Exception e) {
file.deleteOnExit();
throw e;
} finally {
IOUtils.closeQuietly(output);
}
}

/**
* 下载文件成流,使用此方法需要注意,关闭流之后要调用completePendingCommand方法
*
* @param remotePath 远程路径
* @param fileName 远程文件名
* @return 文件流
*/
@Override
public InputStream downloadFile(String remotePath, String fileName) throws Exception {
String now = sftp.pwd();
sftp.cd(remotePath);
//setRemoteDir(remotePath);//转移到FTP服务器目录 暂时注释 拷贝错误
InputStream is = sftp.get(fileName);
sftp.cd(now);
return is;

}

/**
* 上传文件到ftp
*
* @param path 远程路径
* @param filename 远程文件名
* @param localFileName 本地文件(含路径)
* @return
*/
@Override
public boolean uploadFile(String path, String filename, String localFileName) throws Exception {
return uploadFile(path, filename, new File(localFileName));
}

@Override
public boolean uploadFile(String path, String filename, File localFile) throws Exception {
FileInputStream is = null;
try {
String now = sftp.pwd();
setRemoteDir(path);
is = new FileInputStream(localFile);
try {
sftp.put(is, filename);
} finally {
IOUtils.closeQuietly(is);
}
sftp.cd(now);
if (!existsFile(path, filename)) {
throw new Exception("SFTP上传失败,请检查服务器配置!");
}
return true;
} finally {
if (is != null) is.close();
}
}

/**
* 删除远程文件
*
* @param path 远程路径
* @param filename 远程文件名
*/
@Override
public void deleteFile(String path, String filename) {
try {
String now = sftp.pwd();
setRemoteDir(path);
sftp.rm(filename);
sftp.cd(now);
} catch (Exception e) {
logError("删除文件失败", e);
}
}

@Override
public boolean rename(String path, String from, String to) throws Exception {
try {
String now = sftp.pwd();
setRemoteDir(path);
sftp.rename(from, to);
sftp.cd(now);
return true;
} catch (Exception e) {
logError("重命名文件失败", e);
return false;
}
}

//调用返回流的方法,在处理完流后,要调用此方法。
@Override
public boolean completePendingCommand() {
return true;
}

//断开连接
@Override
public String[] listFileNames(String remotePath) throws Exception {
List<String> list = new ArrayList<>();
Vector<ChannelSftp.LsEntry> sftpFile = sftp.ls(remotePath);
ChannelSftp.LsEntry isEntity = null;
String fileName = null;
Iterator<ChannelSftp.LsEntry> sftpFileNames = sftpFile.iterator();
while (sftpFileNames.hasNext()) {
isEntity = sftpFileNames.next();
if (!isEntity.getAttrs().isDir()) {
fileName = isEntity.getFilename();

list.add(fileName);
}
}
return list.toArray(new String[list.size()]);
}

//断开连接
@Override
public String[] listAllFileNames(String remotePath) throws Exception {
List<String> list = new ArrayList<>();
Vector<ChannelSftp.LsEntry> sftpFile = sftp.ls(remotePath);
ChannelSftp.LsEntry isEntity = null;
String fileName = null;
Iterator<ChannelSftp.LsEntry> sftpFileNames = sftpFile.iterator();
while (sftpFileNames.hasNext()) {
isEntity = sftpFileNames.next();
fileName = isEntity.getFilename();
list.add(fileName);
}
return list.toArray(new String[list.size()]);
}


//断开连接
@Override
public void disconnect() {
if (sftp != null && isAutoFree() && sftp.isConnected()) {
try {
if (sftp.getSession() != null) {
UtilLogger.debug("关闭连接 " + sftp.getSession().getHost() + ";");
sftp.getSession().disconnect();
UtilLogger.debug("Session disconnect.");
}
} catch (JSchException e) {
logError("关闭失败!", e);
}
sftp.quit();
sftp.disconnect();
UtilLogger.debug("Channel closed.");
sftp = null;
}
}

private void logError(String msg, Exception e) {
UtilLogger.debug(msg + ":" + e.getMessage());
}

//编码转换
private static String gbktoiso8859(String gbk) {
try {
if (gbk == null)
return "";
else //iso-8859-1
return new String(gbk.getBytes("GBK"), StandardCharsets.ISO_8859_1);
} catch (Exception e) {
e.printStackTrace();
return "";
}
}

@Override
public boolean existsFile(String path, String filename) {
try {
String now = sftp.pwd();
setRemoteDir(path);
Vector<ChannelSftp.LsEntry> files = sftp.ls(filename);
sftp.cd(now);
return PubUtil.isNotEmpty(files);
} catch (SftpException e) {
logError("判断文件是否存在失败", e);
return false;
}
}
}

+ 13
- 3
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/attach/AttachInfo.java Целия файл

@@ -62,12 +62,12 @@ public class AttachInfo extends DefaultEntity {
put("attach_path", attach_path);
}
/** 附件类别 */
public int getType() {
return getInt("attach_type");
public String getType() {
return getStr("attach_type");
}

/** 附件类别 */
public void setType(int attach_type) {
public void setType(String attach_type) {
put("attach_type", attach_type);
}
/** 附件大小 */
@@ -115,4 +115,14 @@ public class AttachInfo extends DefaultEntity {
public void setUserId(long attach_user_id) {
put("attach_user_id", attach_user_id);
}

/** 下载次数 */
public int getCount() {
return getInt("attach_count");
}

/** 下载次数 */
public void setCount(int attach_count) {
put("attach_count", attach_count);
}
}

+ 16
- 0
smtweb-framework/bpm/src/main/java/cc/smtweb/system/bpm/web/sys/base/attachFolder/pojo/AttachFolderPojo.java Целия файл

@@ -0,0 +1,16 @@
package cc.smtweb.system.bpm.web.sys.base.attachFolder.pojo;

import lombok.Data;

import java.io.Serializable;

@Data
public class AttachFolderPojo implements Serializable {
private static final long serialVersionUID = 1L;
private Long folderId;//
private String folderAttachPath;//
private String folderPeriod;//
private int folderMaxSeq;//
private Long folderFileCount;//
}


+ 16
- 0
smtweb-framework/bpm/src/main/resources/config/application.yaml Целия файл

@@ -3,6 +3,22 @@ smtweb:
file:
local-path: /data/sw/files/
url: http://127.0.0.1:8888/sw/files/
#访问路径,需/结尾
attach-http-path: 'http://bjjt.jujiatech.cn/files/'
#此配置原则上可以和local-path一致,可本机路径可ftp附件路径,需/结尾
attach-path: /jjkj/attach/
#临时文件路径,需/结尾
attach-temp-path: /jujia/tomcat_api/webapps/files/tempFile/
#附件上传方式 sftp/ftp/local
attach-type: sftp
#ftp IP地址
attach-ftp-ip: 172.26.60.191
#ftp 端口
attach-ftp-port: 22
#ftp 用户名
attach-ftp-user: gzhfile
#ftp 密码
attach-ftp-pwd: Bjjt@2021
bpm:
debug: true
# 有.idea或pom.xml文件的目录


+ 6
- 0
smtweb-framework/core/src/main/java/cc/smtweb/framework/core/db/dao/AbstractEntityDao.java Целия файл

@@ -14,6 +14,8 @@ import cc.smtweb.framework.core.exception.DbException;
import cc.smtweb.framework.core.util.DateUtil;
import cc.smtweb.framework.core.util.SpringUtil;
import cc.smtweb.framework.core.util.VariableUtil;
import com.esotericsoftware.minlog.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ClassUtils;

@@ -31,6 +33,7 @@ import java.util.Map;
*
* @param <T> 数据库值对象类型
*/
@Slf4j
public abstract class AbstractEntityDao<T> {
protected ModelTable modelTable;
protected String tableName;
@@ -62,6 +65,9 @@ public abstract class AbstractEntityDao<T> {

tableName = table.value();
modelTable = ModelTableCache.getInstance().getByName(tableName);
if(null == modelTable){
log.error("未找到缓存表结构:"+tableName);
}
if (DefaultEntity.class.isAssignableFrom(type)) {
for (ModelField field : modelTable.getFields()) {
add(field, null, null);


+ 1
- 0
smtweb-framework/pom.xml Целия файл

@@ -27,5 +27,6 @@
<modules>
<module>core</module>
<module>bpm</module>
<module>unit</module>
</modules>
</project>

Зареждане…
Отказ
Запис