改进 #38784
【评标】评委评标界面增加一键下载新功能,下载投保文件附件,如:技术标评分,一键下载所有的技术标附件
用户附件上传时,会对用户的附件进行特殊加密,一键下载前,需要对附件逐一解密,再进行压缩zip。
(一键打包下载方法在最后。)
/**
*上传下载类
*/
@Entity
@Table(name = "s_sys_upload")
@SuppressWarnings("serial")
public class Upload extends IdEntity {
public static String SOURCE_IN="in";//内网
public static String SOURCE_OUT="out";//外网
@Lob
@Basic(fetch = FetchType.LAZY)
private byte[] fileContent;
/**
* 附件备注
*/
@Lob
private String note;
/**
* 附件是否加密
*/
private String isEncrypt;
/**
* 附件名
*/
@Description(name = "附件名称")
private String fileName;
/**
* 附件路径
*/
private String path;
/**
* 附件分类
*/
private String category;
/**
* 附件后缀
*/
private String ext;
/**
* 附件上传时间
*/
private long uploadTime;
/**
* 附件来源
*/
private String source;
/**
* 附件归属id
*/
private String ownerId;
}
/**
*加密类
*/
public class FileDESPlus {
public static String strDefaultKey = "biohazard";
private static Cipher encryptCipher = null;
private static Cipher decryptCipher = null;
/**
* 指定密钥构造方法
*
* @param strKey
* 指定的密钥
* @throws Exception
*/
public FileDESPlus(String strKey) throws Exception {
//Security.addProvider(new com.sun.crypto.provider.SunJCE());
Key key = getKey(strKey.getBytes());
encryptCipher = Cipher.getInstance("DES");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);//Cipher.ENCRYPT_MODE = 1
decryptCipher = Cipher.getInstance("DES");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
}
/**
* 默认构造方法,使用默认密钥
*
* @throws Exception
*/
public FileDESPlus() throws Exception {
this(strDefaultKey);
}
/**
* 从指定字符串生成密钥,密钥所需的字节数组长度为8位 不足8位时后面补0,超出8位只取前8位
*
* @param arrBTmp
* 构成该字符串的字节数组
* @return 生成的密钥
* @throws java.lang.Exception
*/
private Key getKey(byte[] arrBTmp) throws Exception {
// 创建一个空的8位字节数组(默认值为0)
byte[] arrB = new byte[8];
// 将原始字节数组转换为8位
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
// 生成密钥
Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES");
return key;
}
//文件加密
public static void encryptFile(File myFile,File newFile){
try {
FileInputStream dataFIS = new FileInputStream(myFile);
CipherInputStream CIS=new CipherInputStream(dataFIS,encryptCipher);
byte[] b = new byte[1024*10];
int len;
FileOutputStream FOS=new FileOutputStream(newFile);
try {
while ((len =CIS.read(b)) > 0){
FOS.write(b, 0, len);//写入文件中
}
CIS.close();
FOS.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//文件解密
public static void decryptFile(File myFile,File newFile){
try {
FileInputStream dataFIS = new FileInputStream(myFile);
CipherInputStream CIS = new CipherInputStream(dataFIS,decryptCipher);
byte[] b = new byte[1024*10];
int len;
FileOutputStream FOS=new FileOutputStream(newFile);
try {
while ((len =CIS.read(b)) > 0){
FOS.write(b, 0, len);//写入文件中
}
CIS.close();
FOS.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//文件解密
public static CipherInputStream decryptFileToStream(File myFile){
try {
FileInputStream dataFIS = new FileInputStream(myFile);
CipherInputStream CIS = new CipherInputStream(dataFIS,decryptCipher);
return CIS;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static void main(String[] args) {
File myFile = new File("d:\\FCKeditor文件上各类传解决方案.docx");
File newFile = new File("d:\\FCKeditor文件上各类传解决方案1.docx");
try {
FileDESPlus des = new FileDESPlus();
des.decryptFile(myFile, newFile);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/***********************************************************************************************/
/**
*上传方法 Action的方法
*/
public void upload() {
boolean ifUpload = true;
String exceptionDescribe = "";
String UVScanInfoStatus = "0";
Upload upload = null;
File src = null;
File dst = null;
String useJson = getParameter("useJson");
//文件上传
//附件大小限制
try{
if(StringUtils.isBlank(fileLimit)){
fileLimit = "50";
}
//验证文件名是否重复
boolean isExistSameFile = getCommonService().isExist(Upload.class, "category = ? and ownerId = ? and fileName = ?", new Object[]{category,ownerId,filedataFileName});
if(isExistSameFile){
ifUpload = false;
exceptionDescribe = "文件名不能重复。";
}else if((filedata.length()/1024)>(Integer.valueOf(fileLimit)*1024)){
ifUpload = false;
exceptionDescribe = "请上传"+fileLimit+"兆以内的附件。";
}else{
//(Ext后他乱码)
if(filedataFileName.indexOf("&#")!=-1 && StringHelper.parseBoolean(getParameter("isExt"))){
filedataFileName = HtmlUtils.htmlUnescape(filedataFileName);
}
upload = fileService.upload(filedata, filedataFileName, filedataFileName, note,category,ownerId, FileService.PATH_STYLE_OWNERID, StringHelper.parseBoolean(isSingle),false,StringHelper.parseBoolean(isScan));
//如果附件带有来源,则进行保存
if(!StringUtils.isBlank(source)){
getCommonService().execute("update Upload set source = ? where id = ?",new Object[]{source,upload.getId()});
}
//防止文件名过长(默认长度为31个字符)
if(StringUtils.isBlank(wordLimit)){
wordLimit = "31";
}
filedataFileName = this.truncate(filedataFileName,Integer.valueOf(wordLimit), "...");
//文件杀毒扫描
if(Constant.TRUE.equals(isScan)){
String filePath = upload.getPath();
Map uploadMap = (Map)AppConfig.getBean("uploadMap");
//正常路径
String realConfigPath = (String)uploadMap.get(upload.getCategory());
if(!realConfigPath.endsWith(File.separator))realConfigPath = realConfigPath + File.separator;
String realPath = realConfigPath + filePath;
//缓冲区路径
String bufferConfigPath = SettingService.getSettingValue(BtcStaticInterface.SKEY_file_buffer_root);
if(!bufferConfigPath.endsWith(File.separator))bufferConfigPath = bufferConfigPath + File.separator;
String bufferPath = bufferConfigPath + filePath;
//扫描缓冲区的文件
UVScanInfo UVScanInfo = UVScanService.startScan(bufferPath, category, ownerId);
UVScanInfoStatus = String.valueOf(UVScanInfo.getStatus());
//正常文件
if(UVScanInfo.SCAN_STATUS_NORMAL==UVScanInfo.getStatus()){
//更新文件的扫描状态
getCommonService().execute("update Upload set isSafe = ? where id = ?",new Object[]{String.valueOf(UVScanInfo.SCAN_STATUS_NORMAL),upload.getId()});
//文件从缓冲文件夹移动至上传文件夹下
try{
src = new File(bufferPath);
dst = new File(realPath);
try {
dst.mkdirs();
dst.createNewFile();
} catch (IOException e) {
ifUpload = false;
exceptionDescribe = "创建目标目录失败,请您联系管理员。";
}
FileUtils.copyForChannel(src, dst);
//删除缓冲区文件
//ADD 删除父空目录
String parentDir = "";
try{
parentDir = src.getParent();
}
catch(Exception e){
}
src.delete();
//执行删除父空目录
try{
if(StringUtils.isNotEmpty(parentDir)){
File _parentDir = new File(parentDir);
if(_parentDir.isDirectory() && parentDir.isEmpty()){
_parentDir.delete();
}
}
}
catch(Exception e){
}
//加密
if(Constant.TRUE.equals(isEncrypt)){
fileService.uploadEncrypt(upload.getId());
getCommonService().execute("update Upload set isEncrypt = ? where id = ?",new Object[]{Constant.TRUE,upload.getId()});
}
}catch (Exception e) {
ifUpload = false;
exceptionDescribe = "服务器繁忙,请您稍候再试。";
}
}
//感染文件
else if(UVScanInfo.SCAN_STATUS_INFECTED==UVScanInfo.getStatus()){
getCommonService().delete(upload);
upload = null;
}
//异常情况
else if(UVScanInfo.SCAN_STATUS_ERROR==UVScanInfo.getStatus()){
//更新文件的扫描状态
getCommonService().execute("update Upload set isSafe = ? where id = ?",new Object[]{String.valueOf(UVScanInfo.SCAN_STATUS_ERROR),upload.getId()});
try{
//文件从缓冲文件夹移动至上传文件夹下
src = new File(bufferPath);
dst = new File(realPath);
try {
dst.mkdirs();
dst.createNewFile();
} catch (IOException e) {
ifUpload = false;
exceptionDescribe = "创建目标目录失败,请您联系管理员。";
}
FileUtils.copyForChannel(src, dst);
//删除缓冲区文件
src.delete();
//加密
if(Constant.TRUE.equals(isEncrypt)){
fileService.uploadEncrypt(upload.getId());
getCommonService().execute("update Upload set isEncrypt = ? where id = ?",new Object[]{Constant.TRUE,upload.getId()});
}
}catch (Exception e) {
ifUpload = false;
exceptionDescribe = "服务器繁忙,请您稍候再试。";
}
}
else{
//加密
if(Constant.TRUE.equals(isEncrypt)){
fileService.uploadEncrypt(upload.getId());
getCommonService().execute("update Upload set isEncrypt = ? where id = ?",new Object[]{Constant.TRUE,upload.getId()});
}
}
}else{
//加密
if(Constant.TRUE.equals(isEncrypt)){
fileService.uploadEncrypt(upload.getId());
getCommonService().execute("update Upload set isEncrypt = ? where id = ?",new Object[]{Constant.TRUE,upload.getId()});
}
}
}
}catch (Exception e) {
ifUpload = false;
exceptionDescribe = "服务器繁忙,请您稍候再试。";
}
if(ifUpload){
if(!StringHelper.parseBoolean(useJson)){
if(upload!=null&&upload.getId()!=null){
renderHtml("<script>parent.uploadOK("+upload.getId()+",'"+fileTrId+"','"+filedataFileName+"','"+upload.getFileName()+"','"+fileTdId+"','"+noteTdId+"','"+operationTdId+"','"+note+"','"+category+"','"+ownerId+"',"+UVScanInfoStatus+",'"+isEncrypt+"','"+isScan+"','"+isDoAfter+"','"+maskCode+"','"+luckyTime+"');</script>");
}else{
renderHtml("<script>parent.uploadOK('','"+fileTrId+"','"+filedataFileName+"','','"+fileTdId+"','"+noteTdId+"','"+operationTdId+"','"+note+"','"+category+"','"+ownerId+"',"+UVScanInfoStatus+",'"+isEncrypt+"','"+isScan+"','"+isDoAfter+"','"+maskCode+"','"+luckyTime+"');</script>");
}
}
else{
super.renderText("OK");
}
}else{
renderHtml("<script>parent.alertException('"+exceptionDescribe+"');</script>");
}
}
/**********************************************************/
/**
*调用的service的upload() 方法
*/
public Upload upload(File filedata,String fileName,String userLabel,String note,String category,String ownerId,int pathStyle,boolean isSingle,boolean inDB,boolean isScan){
Upload pojo = null;
//唯一性冗余保证
if(isSingle){
pojo = (Upload)getDao().findFirst(Upload.class,"category=? and ownerId=?", new Object[]{category,ownerId});
}
if(pojo==null){
pojo = new Upload();
}
Map uploadMap = AppConfig.getBean(Map.class,"uploadMap");
String configPath = "";
//扫描,文件放入缓冲区
if(isScan){
configPath = s.getSettingValue(BtcStaticInterface.SKEY_file_buffer_root);
}else{
configPath = (String)uploadMap.get(category);
}
String orgnShortName = "";
String orgnFullName = "";
String userId = "";
String userName = "";
if(StringUtils.isEmpty(userLabel)) userLabel = fileName;
if(filedata!=null){
if(inDB){
try {
byte[] file = FileUtils.streamToByte(new FileInputStream(filedata));
pojo.setFileContent(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
else if(StringUtils.isNotEmpty(configPath)){
try {
//写文件
String relativePath = getRelativePath(ownerId,pathStyle);
if(!configPath.endsWith(File.separator)) configPath += File.separator;
if(!relativePath.endsWith(File.separator)) relativePath += File.separator;
FileUtils.checkDir(configPath + relativePath);
String newPath = configPath + relativePath + fileName;
File newFile = new File(newPath);
if(newFile.exists() && newFile.isFile()){
newFile.delete();
}
FileUtils.copyForChannel(filedata, newFile);
//filedata.renameTo(newFile);
//路径信息
pojo.setPath(relativePath + fileName);
} catch (Exception e) {
}
}
String ext = ".unknow";
if(fileName.indexOf(".")!=-1)
ext = fileName.substring(fileName.lastIndexOf("."));
pojo.setCategory(category);
pojo.setOwnerId(ownerId);
pojo.setNote(note);
pojo.setFileName(fileName);
pojo.setIsEncrypt(Constant.FALSE);
pojo.setOrgnShortName(orgnShortName);
pojo.setOrgnFullName(orgnFullName);
pojo.setUploadTime(System.currentTimeMillis());
pojo.setUserId(userId);
pojo.setUserName(userName);
pojo.setUserLabel(userLabel);
pojo.setExt(ext);
getDao().saveOrUpdate(pojo);
return pojo;
}
return null;
}
/**********************************************************/
/**
*调用service层的附件加密方法
public File uploadEncrypt(Integer uploadId){
File returnFile = null;
Upload upload = null;
if(uploadId!=null){
upload = getDao().getById(Upload.class,uploadId);
String filePath = upload.getPath();
Map uploadMap = (Map)AppConfig.getBean("uploadMap");
String configPath = (String)uploadMap.get(upload.getCategory());
String fileName = upload.getFileName();
if(!configPath.endsWith(File.separator))
configPath = configPath + File.separator;
File file = new File(configPath + filePath);
if(!file.exists()){
throw new JException("对不起,未找到打开文件!");
}
filePath = filePath.replaceAll(upload.getExt(), "temp"+upload.getExt());
File file_temp = new File(configPath + filePath);
//文件加密保存(先生成一个加密的临时文件,在把真实文件替换为临时文件,最后删除临时文件)
try {
FileDESPlus FileDESPlus = new FileDESPlus();
FileDESPlus.encryptFile(file, file_temp);
FileUtils.copyForChannel(file_temp, file);
returnFile = file;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
file_temp.delete();
}
}
return returnFile;
}
/**********************************************************/
/**
*service层的附件解密方法
public File uploadDecrypt(Integer uploadId) {
File returnFile = null;
Upload upload = null;
if (uploadId != null) {
upload = getDao().getById(Upload.class, uploadId);
}
String filePath = upload != null ? upload.getPath() : null;
Map uploadMap = (Map)AppConfig.getBean("uploadMap");
String configPath = uploadMap != null ? (String)uploadMap.get(upload.getCategory()) : "";
@SuppressWarnings("unused")
String fileName = upload != null ? upload.getFileName() : "";
if (!configPath.endsWith(File.separator)) configPath = configPath + File.separator;
File file = new File(configPath + filePath);
File file_temp = null;// 解密临时文件
if (!file.exists()) {
throw new JException("对不起,未找到打开文件!");
}
// 解密
if (Constant.TRUE.equals(upload.getIsEncrypt())) {
filePath = filePath.replaceAll(upload.getExt(), "temp" + upload.getExt());
file_temp = new File(configPath + filePath);
if (!file_temp.exists() || !file_temp.isFile()) {
FileDESPlus FileDESPlus;
try {
FileDESPlus = new FileDESPlus();
FileDESPlus.decryptFile(file, file_temp);
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
returnFile = file_temp;
} else {
returnFile = file;
}
return returnFile;
}
/**********************************************************/
/**
*打包下载 Action的方法
public void packZip(){
String proId = request.getParameter("projectId");
String pbtype = request.getParameter("pbtype");
super.CheckNotNull(projectId, pbtype);
Integer projectId = Integer.valueOf(proId);
//打包附件名的前缀
String prefix = "";
if ("1".equals(pbtype)){
category = "hb_technical_file_1";
prefix = "技术标附件_";
} else if ("2".equals(pbtype)){
category = "hb_commercial_file";
prefix = "商务标附件_";
} else {
category = "hb_price_list";
prefix = "报价标附件_";
}
List<String> ownerIdList = getCommonService().findByHQL(String.class, "select k.ownerId from KpbLogTrack k where k.project_id = ?", projectId);
if (ownerIdList.size() > 0){
StringBuilder ownerIds = new StringBuilder();
for (int i =0; i < ownerIdList.size(); i++){
if (i == ownerIdList.size() - 1){
ownerIds.append("'" + ownerIdList.get(i)+"'");
} else {
ownerIds.append("'" + ownerIdList.get(i)+"',");
}
}
uploadList = getCommonService().findByHQL(Upload.class, "from Upload u where u.ownerId in("+ownerIds.toString()+") and u.category = ?", category);
if (uploadList.size() > 0){
byte[] b = new byte[AttConstant.ATT_PACK_READ_SIZE]; // 1024 * 1024
ZipOutputStream out = null;
try {
response.reset();
response.setContentType("application/x-msdownload");
response.setHeader("Content-Disposition", //ATT_PACK_NAME = 附件信息.zip, ATT_BYTES_CODE = GB2312
"attachment; filename=\""+ new String(AttConstant.ATT_PACK_NAME.getBytes(AttConstant.ATT_BYTES_CODE), "ISO8859-1") + "\"");
out = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
// 设置编码
out.setEncoding(AttConstant.ATT_BYTES_CODE);
File file = null;
for (Upload upload : uploadList) {
if (Constant.TRUE.equals(upload.getIsEncrypt())) {
file = fileService.uploadDecrypt(upload.getId());
}
// 处理压缩包所包含的下载文件
if (file != null && file.isFile() && file.exists()) {
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
String companyNameHql = "select s.companyName from KpbLogTrack k inner join k.yqCorpentry c inner join c.supplier s where k.ownerId = ?";
String supplierCompanyName = getCommonService().findString(companyNameHql, upload.getOwnerId());
String itemQbwjTimesHql = "select c.itemQbwjTimes from ClearPaper c inner join c.kpbLogTrack k where c.projectId = ? and k.ownerId = ?";
Integer itemQbwjTimes = getCommonService().findInt(itemQbwjTimesHql, projectId, upload.getOwnerId());
String fileName = "";
//判断是否有清标 填充文件名
if (0 == itemQbwjTimes){
fileName = prefix + supplierCompanyName + "_第1次回标_" + file.getName();
} else {
fileName = prefix + supplierCompanyName + "_第"+itemQbwjTimes+"次清标_" + file.getName();
}
fileName = fileName.replaceAll("/", "_").replaceAll("temp.", ".");
ZipEntry entry = new ZipEntry(fileName);
out.putNextEntry(entry);
int len;
while ((len = bis.read(b)) > 0) {
out.write(b, 0, len); // 写入文件中
}
try {
fis.close();
fis = null;
bis.close();
bis = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
throw new JException("对不起,打包时发生如下错误:" + e.getMessage() + ",如有疑问请及时联系管理员。");
} finally {
if (out != null) {
try {
out.closeEntry();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
out = null;
}
}
}
}
}