package com.product.file.service; import com.alibaba.fastjson.JSONObject; import com.azure.storage.blob.BlobServiceClient; import com.azure.storage.blob.BlobServiceClientBuilder; import com.azure.storage.common.sas.AccountSasPermission; import com.azure.storage.common.sas.AccountSasSignatureValues; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.product.common.lang.StringUtils; import com.product.core.config.Global; import com.product.core.connection.ConnectionManager; import com.product.core.dao.BaseDao; import com.product.core.entity.DataTableEntity; import com.product.core.entity.FieldMetaEntity; import com.product.core.entity.FieldSetEntity; import com.product.core.entity.RequestParameterEntity; import com.product.core.exception.BaseException; import com.product.core.service.support.AbstractBaseService; import com.product.core.spring.context.SpringMVCContextHolder; import com.product.file.config.CmnConst; import com.product.file.config.FileCode; import com.product.file.util.CreateDocumentIndexThread; import com.product.file.util.FileUtil; import com.product.file.util.FileUtils; import com.product.module.sys.entity.SystemUser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.text.SimpleDateFormat; import java.time.OffsetDateTime; import java.util.*; import java.util.concurrent.TimeUnit; /** * Copyright LX-BASE * * @Title: FileManagerService * @Project: LX-BASE-SERVER * @Date: 2020-06-16 10:30 * @Author: LiuChao * @Description: 文件管理 */ @Service("fileManagerService") public class FileManagerService extends AbstractBaseService { @Autowired public BaseDao baseDao; @Autowired FileUtils fileUtils; /** * 获取静态资源 * * @param uuid * @param response * @throws IOException * @throws BaseException */ public void getStaticFile(String uuid, HttpServletResponse response) throws IOException, BaseException { String systemConfig = Global.getSystemConfig("file.static", ""); if (StringUtils.isEmpty(uuid) || StringUtils.isEmpty(systemConfig)) { throw new BaseException(FileCode.GET_FILE_FAIL); } FieldSetEntity fs = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, uuid, false); if (fs == null || StringUtils.isEmpty(fs.getString("attachment_data_table")) || StringUtils.isEmpty(fs.getString("attachment_data_field"))) { throw new BaseException(FileCode.GET_FILE_FAIL); } List list = new ArrayList<>(Arrays.asList(systemConfig.split(","))); if (list != null && list.size() > 0) { if (list.contains((fs.getString("attachment_data_table") + "." + fs.getString("attachment_data_field")))) { // 允许的静态资源 this.getFileContent(fs, response); return; } } throw new BaseException(FileCode.GET_FILE_FAIL); } /** * 文件记录-新增 * * @param fse 参数对象 * @return UUID * @throws BaseException 基本异常 */ public FieldSetEntity addFileRecordPlan(FieldSetEntity fse) throws BaseException { //设置临时token String url = Global.getSystemConfig(CmnConst.UPLOAD_URL, ""); String sostoken = Global.getSystemConfig(CmnConst.UPLOAD_KEY, ""); String connection_string = Global.getSystemConfig("upload.connection_string", ""); BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(url).sasToken(sostoken).connectionString(connection_string) .buildClient(); AccountSasSignatureValues values1 = new AccountSasSignatureValues(); AccountSasPermission permission1 = new AccountSasPermission().setReadPermission(true).setAddPermission(true).setWritePermission(true).setCreatePermission(true).setDeletePermission(true).setDeleteVersionPermission(true) .setUpdatePermission(true).setListPermission(true); values1.setPermissions(permission1); values1.setServices("bfqt"); values1.setResourceTypes("sco"); values1.setStartTime(OffsetDateTime.now()); OffsetDateTime expiryTime = OffsetDateTime.now().plusMinutes(5); values1.setExpiryTime(expiryTime); String sas = blobServiceClient.generateAccountSas(values1); String CLIENT_UUID = fse.getString(CmnConst.CLIENT_UUID); if (StringUtils.isEmpty(CLIENT_UUID)) { String[] split = SpringMVCContextHolder.getCurrentUser().getClientUuid().split(","); CLIENT_UUID = split[0]; fse.setValue(CmnConst.CLIENT_UUID, split[0]); } if (!StringUtils.isEmpty(CLIENT_UUID)) { FieldSetEntity clientFse = baseDao.getFieldSetEntityByFilter("product_sysclients", "uuid = ?", new String[]{CLIENT_UUID}, false); if (clientFse != null) { String curClientDomain = clientFse.getString(CmnConst.ATTACHMENT_DOMAIN); fse.setValue(CmnConst.ATTACHMENT_DOMAIN, StringUtils.isEmpty(curClientDomain) ? Global.getSystemConfig("default_domain", "") : curClientDomain); fse.setValue(CmnConst.ATTACHMENT_CONTAINER, clientFse.getUUID()); } } if (!StringUtils.isEmpty(fse.getString(CmnConst.PRODUCT_UUID))) { FieldSetEntity productFse = baseDao.getFieldSetEntity("product_sysproducts", fse.getString(CmnConst.PRODUCT_UUID), false); fse.setValue(CmnConst.ATTACHMENT_ACCOUNT, productFse.getString("product_shortcode") + "_Account"); } if (!StringUtils.isEmpty(fse.getString(CmnConst.MODULE_UUID))) { fse.setValue(CmnConst.MODULE_UUID, fse.getString(CmnConst.MODULE_UUID)); } else if (!StringUtils.isEmpty(fse.getString(CmnConst.FUNCTION_UUID))) { FieldSetEntity functionFse = baseDao.getFieldSetEntity("product_sysfunctions", fse.getString(CmnConst.FUNCTION_UUID), false); FieldSetEntity moduleFse = baseDao.getFieldSetEntity("product_sysmodules", functionFse.getString(CmnConst.MODULE_UUID), false); fse.setValue(CmnConst.MODULE_UUID, moduleFse.getUUID()); fse.setValue("attachment_catalog", moduleFse.getString("module_shortcode") + "_Directory"); } else {//功能、模块都为空时,传到指定位置 fse.setValue(CmnConst.MODULE_UUID, "public-module"); } String attachmentTitle = fse.getString(CmnConst.ATTACHMENT_TITLE); double curFileSize = fse.getDouble(CmnConst.ATTACHMENT_SIZE) == null ? 0d : fse.getDouble(CmnConst.ATTACHMENT_SIZE); if (!StringUtils.isEmpty(CLIENT_UUID) && findClientFileResidueCapacity(CLIENT_UUID) < curFileSize) { throw new BaseException(FileCode.ADD_FILE_NO_CAPACITY.getValue(), FileCode.ADD_FILE_NO_CAPACITY.getText()); } //验证文件格式 String type = attachmentTitle.substring(attachmentTitle.lastIndexOf(".") + 1); type = type.toLowerCase(); FieldSetEntity typeFse = baseDao.getFieldSetEntityByFilter("product_sysdict", "dict_name='upload_file_format' and dict_value=? and is_used=1", new Object[]{type}, false); if (typeFse == null) { throw new BaseException(FileCode.ADD_FILE_NOT_ALLOWED.getValue(), FileCode.ADD_FILE_NOT_ALLOWED.getText() + ":attachment_type_uuid"); } fse.setValue("attachment_type_uuid", typeFse.getString("uuid")); Calendar c = Calendar.getInstance(); String timeCatalog = c.get(Calendar.YEAR) + "/" + (c.get(Calendar.MONTH) + 1) + "/" + c.get(Calendar.DATE); fse.setValue("attachment_time_catalog", timeCatalog); fse.setValue("opt_flat", 1); fse.setValue(CmnConst.CREATED_BY, SpringMVCContextHolder.getCurrentUser().getUser_id()); fse.setValue(CmnConst.CREATED_UTC_DATETIME, c.getTime()); //设置重命名文件及源文件名 fse.setValue(CmnConst.FILE_NAME, fse.getString(CmnConst.ATTACHMENT_TITLE)); String field_name = UUID.randomUUID().toString() + "." + type; fse.setValue(CmnConst.ATTACHMENT_TITLE, field_name); fse.getMeta().setTableName(new Object[]{CmnConst.PRODUCT_SYS_ATTACHMENTS}); fse.setValue(CmnConst.CLIENT_UUID, fse.getString("uuid")); fse.setValue("uuid", null); //修改----把附件的url地址保存到库----shicf------------- StringBuilder upload_url = new StringBuilder(); upload_url.append(fse.getString(CmnConst.ATTACHMENT_DOMAIN)).append("/") .append(fse.getString(CmnConst.ATTACHMENT_CONTAINER)).append("/").append( fse.getString(CmnConst.MODULE_UUID)).append("/").append(fse.getString(CmnConst.ATTACHMENT_TITLE)) .append("?").append(sas); fse.setValue("attachment_url", upload_url.toString()); //修改-------end-------------------- String uuid = baseDao.add(fse); FieldSetEntity upload = new FieldSetEntity(); upload.setTableName(new String[]{CmnConst.PRODUCT_SYS_ATTACHMENTS}); upload.setValue("sostoken", "?" + sas); upload.setValue("uuid", uuid); upload.setValue("upload_url", upload_url.toString()); fse.setValue("sostoken", "?" + sas); fse.setValue("upload_url", upload_url.toString()); //设置剩余空间大小 fse.setValue(CmnConst.SOURCE_DOMAIN, Global.getSystemConfig(CmnConst.SOURCE_DOMAIN, "")); FieldSetEntity fss = baseDao.getFieldSetEntityByFilter("product_sysclients", "uuid=?", new String[]{CLIENT_UUID}, false); if (fss != null) { DataTableEntity da = baseDao.listTable(CmnConst.PRODUCT_SYS_ATTACHMENTS, "client_uuid=?", new String[]{fss.getString("uuid")}); if (da.getRows() > 0) { int size = 0; for (int i = 0; i < da.getRows(); i++) { FieldSetEntity fiel = da.getFieldSetEntity(i); size = size + fiel.getInteger(CmnConst.ATTACHMENT_SIZE); } fse.setValue("residue_capacity", fss.getInteger(CmnConst.ATTACHMENT_CAPACITY) - size); } else { fse.setValue("residue_capacity", fss.getInteger(CmnConst.ATTACHMENT_CAPACITY)); } } return upload; } /** * 文件记录-文件新增结果回调: * result-1 服务器新增成功,修改状态 * result-其他 服务器新增失败,删除准备新增的记录 * * @param fse 参数对象 * @return 结果 * @throws BaseException 基本异常 */ public JSONObject addFileCallback(FieldSetEntity fse) throws BaseException { String result = fse.getString(CmnConst.RESULT); JSONObject returnResult = new JSONObject(); if ("1".equals(result)) { returnResult.put(CmnConst.TYPE, "update"); returnResult.put(CmnConst.RESULT, updateFileStatus(fse.getString("uuid"), 2) != null); } else { returnResult.put(CmnConst.TYPE, "del"); returnResult.put(CmnConst.RESULT, baseDao.delete(CmnConst.PRODUCT_SYS_ATTACHMENTS, new String[]{fse.getString("uuid")})); } return returnResult; } /** * 文件记录-删除准备(状态修改) * * @param fse 参数对象 * @return 待删除的文件记录fse * @throws BaseException 基本异常 */ public FieldSetEntity delFileRecordPlan(FieldSetEntity fse) throws BaseException { return updateFileStatus(fse.getString("uuid"), 3); } /** * 文件记录-文件删除回调: * result-1 服务器删除成功,删除本地记录 * result-其他 服务器删除失败,还原本地记录 * * @param fse 参数对象 * @return 结果 * @throws BaseException 基本异常 */ public JSONObject delFileCallback(FieldSetEntity fse) throws BaseException { String result = fse.getString(CmnConst.RESULT); JSONObject returnResult = new JSONObject(); if ("1".equals(result)) { returnResult.put(CmnConst.TYPE, "del"); returnResult.put(CmnConst.RESULT, baseDao.delete(CmnConst.PRODUCT_SYS_ATTACHMENTS, new String[]{fse.getString("uuid")})); } else { returnResult.put(CmnConst.TYPE, "update"); returnResult.put(CmnConst.RESULT, updateFileStatus(fse.getString("uuid"), 2) != null); } return returnResult; } /** * 修改文件状态 * * @param fileUUID 文件UUID * @param status 待修改的状态 * @return 是否成功 * @throws BaseException 基本异常 */ private FieldSetEntity updateFileStatus(String fileUUID, int status) throws BaseException { FieldSetEntity fse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, fileUUID, false); fse.setValue("opt_flat", status); fse.setValue(CmnConst.UPDATED_BY, SpringMVCContextHolder.getCurrentUser().getUser_id()); fse.setValue(CmnConst.UPDATED_UTC_DATETIME, new Date()); baseDao.update(fse); fse.setValue(CmnConst.SOURCE_DOMAIN, Global.getSystemConfig(CmnConst.SOURCE_DOMAIN, "")); return fse; } /** * 获取客户上传的文件总大小 * * @param clientUUID 客户UUID * @return 已上传文件总大小 * @throws BaseException 基本异常 */ public long findClientFileUsedCapacity(String clientUUID) throws BaseException { StringBuilder sql = new StringBuilder() .append("\nselect sum(attachment_size) usedCapacity from ").append(CmnConst.PRODUCT_SYS_ATTACHMENTS) .append("\nwhere client_uuid=?"); DataTableEntity dt = baseDao.listTable(sql.toString(), new Object[]{clientUUID}); FieldSetEntity fse; long usedCapacity = 0; if (dt.getRows() == 1) { fse = dt.getFieldSetEntity(0); usedCapacity = fse.getLong("usedCapacity") == null ? 0 : fse.getLong("usedCapacity"); } return usedCapacity; } /** * 获取客户剩余的文件总大小 * * @return 剩余空间大小 */ public long findClientFileResidueCapacity(String CLIENT_UUID) throws BaseException { FieldSetEntity clientFse = baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_CLIENTS, "uuid=?", new String[]{CLIENT_UUID}, false); return findClientFileResidueCapacity(clientFse); } /** * 获取客户剩余的文件总大小 * * @param fse 客户fse * @return 剩余空间大小 */ public long findClientFileResidueCapacity(FieldSetEntity fse) throws BaseException { long clientCapacity = fse.getLong(CmnConst.ATTACHMENT_CAPACITY) == null ? 0 : fse.getInteger(CmnConst.ATTACHMENT_CAPACITY); long usedCapacity = findClientFileUsedCapacity(fse.getString("uuid")); return clientCapacity - usedCapacity; } /** * 验证是否允许上传的文件类型 * * @param attachmentTitle 文件名称 * @return 是否 */ public boolean checkIsAllowedFileType(String attachmentTitle) { if (StringUtils.isEmpty(attachmentTitle) || attachmentTitle.lastIndexOf(".") < 0 || attachmentTitle.length() < 1) { return false; } String curFileTail = attachmentTitle.substring(attachmentTitle.lastIndexOf(".") + 1, attachmentTitle.length()); String allowedFileTypes = Global.getSystemConfig("allowed_file_type", "").toLowerCase(Locale.ROOT); return allowedFileTypes != null && ("," + allowedFileTypes + ",").contains("," + curFileTail.toLowerCase() + ","); } /** * 获取原始域名 * * @return 原始域名 */ public String findSourceDomain() { return Global.getSystemConfig(CmnConst.SOURCE_DOMAIN, ""); } /** * 定时任务:自动清理无用数据 */ public boolean autoClearNoUsedData() throws BaseException { StringBuilder sql = new StringBuilder() .append("\ndelete from ").append(CmnConst.PRODUCT_SYS_ATTACHMENTS) .append("\nwhere opt_flat in (1,3)") .append("\nand ").append(CmnConst.CREATED_BY).append("<=date_format(adddate(now(),-1),'%Y-%m-%d')"); return baseDao.executeUpdate(sql.toString()); } /** * 获取文件信息地址 */ public Map getFileInfo(FieldSetEntity fse) throws BaseException { //设置临时token String url = Global.getSystemConfig(CmnConst.UPLOAD_URL, ""); String sostoken = Global.getSystemConfig(CmnConst.UPLOAD_KEY, ""); String CONNECTION_STRING = Global.getSystemConfig("upload.connection_string", ""); BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(url).sasToken(sostoken).connectionString(CONNECTION_STRING) .buildClient(); OffsetDateTime expiryTime = OffsetDateTime.now().plusMinutes(5); AccountSasSignatureValues values1 = new AccountSasSignatureValues(); values1.setExpiryTime(expiryTime); values1.setStartTime(OffsetDateTime.now()); values1.setServices("bfqt"); values1.setResourceTypes("sco"); AccountSasPermission permission1 = new AccountSasPermission().setReadPermission(true).setDeletePermission(true); values1.setPermissions(permission1); String sas = blobServiceClient.generateAccountSas(values1); Map date = new HashMap<>(); if (fse.getUUID() != null) { String[] split = fse.getUUID().split(","); List> urls = new ArrayList<>(); if (split.length > 0) { for (int i = 0; i < split.length; i++) { FieldSetEntity fieldSetEntity = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, split[i], false); if (fieldSetEntity != null) { Map file = new HashMap(); file.put("path", fieldSetEntity.getString(CmnConst.ATTACHMENT_DOMAIN) + "/" + fieldSetEntity.getString(CmnConst.ATTACHMENT_CONTAINER) + "/" + fieldSetEntity.getString(CmnConst.MODULE_UUID) + "/" + fieldSetEntity.getString(CmnConst.ATTACHMENT_TITLE) + "?" + sas); file.put("name", fieldSetEntity.getString(CmnConst.ATTACHMENT_TITLE)); file.put("size", fieldSetEntity.getString(CmnConst.ATTACHMENT_SIZE)); file.put("uuid", fieldSetEntity.getString("uuid")); file.put(CmnConst.FILE_NAME, fieldSetEntity.getString(CmnConst.FILE_NAME)); urls.add(file); } } } date.put("files", urls); } date.put("sastoken", "?" + sas); //睡眠1S,保证token写入微软云 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); ie.printStackTrace(); throw new BaseException(ie); } return date; } /*** * 检验sastoken是否正确 */ private Boolean checkSas(String sas) throws BaseException { //设置临时token try { String url = Global.getSystemConfig(CmnConst.UPLOAD_URL, ""); BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().endpoint(url).sasToken(sas) .buildClient(); blobServiceClient.getProperties(); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 上传文件到本地服务器 * 禁止修改任何逻辑!!!!!! * * @param rpe * @return */ public FieldSetEntity uploadFile(RequestParameterEntity rpe) { FieldSetEntity fse = rpe.getFormData().clones(); Map fileMap = rpe.getFiles(); SystemUser user = SpringMVCContextHolder.getCurrentUser(); String clientUuid = user == null ? fse.getString("client_uuid") : user.getClient_uuid(); // long residueCapacity = findClientFileResidueCapacity(clientUuid); // long fileTotalSize = 0; for (Map.Entry entry : fileMap.entrySet()) { // 格式验证 if (!checkIsAllowedFileType(entry.getKey())) { throw new BaseException(FileCode.ADD_FILE_NOT_ALLOWED.getValue(), FileCode.ADD_FILE_NOT_ALLOWED.getText() + ":" + entry.getKey().substring(entry.getKey().indexOf(".") + 1)); } // fileTotalSize += (int) entry.getValue().length(); } // 剩余空间判定 // if (residueCapacity < fileTotalSize) { // throw new BaseException(FileCode.ADD_FILE_NO_CAPACITY.getValue(), FileCode.ADD_FILE_NO_CAPACITY.getText()); // } Map map = new HashMap<>(fse.getValues()); ConnectionManager.getConnection(); FieldMetaEntity fieldMetaEntity = fse.getMeta(); Object o; String fieldName = fse.getString("~field_name~"); Object value; String fileNames; FieldSetEntity fieldFse; File tempFile; File localTempFile = null; long fileLength = 0; FTPService ftpService; boolean needUpload2FileServerFlag = FTPService.needUpload2FileServer(); String templateType = fse.getString("template_type"); String dir; if (StringUtils.isEmpty(templateType)) { String timeStr = new SimpleDateFormat("yyyyMMdd").format(new Date()); dir = clientUuid + File.separator + timeStr; } else { dir = CmnConst.DIR_TEMPLATE + File.separator + ("1".equals(templateType) ? CmnConst.DIR_IMPORT : ("2".equals(templateType) ? CmnConst.DIR_PRINT : CmnConst.DIR_OTHER)); } String uuids = ""; for (Map.Entry entry : map.entrySet()) { fieldFse = fieldMetaEntity.getFieldMeta(fieldName); if (fieldFse == null || !CmnConst.ATTACHMENT_TYPE.equals(fieldFse.getString(CmnConst.FIELD_TYPE))) { fse.setValue(entry.getKey().toString(), null); continue; } // 已经判定为附件,进行操作 value = entry.getValue(); if (value == null || StringUtils.isEmpty(fileNames = value.toString())) { fse.setValue(entry.getKey().toString(), null); continue; } for (String fileName : fileNames.split(",")) { if (StringUtils.isEmpty(fieldName)) { fse.setValue(entry.getKey().toString(), null); continue; } tempFile = fileMap.get(fileName); if (tempFile == null) { //不是文件 跳过 continue; } fileLength = tempFile.length(); String tail = fileName.substring(fileName.lastIndexOf(".") + 1); int viewOnlineSign = 0; if (("," + Global.getSystemConfig("can.direct.view.online.format", "") + ",").contains("," + tail + ",")) { viewOnlineSign = 2; } else { if (Global.getPropertyToBoolean("file.view.online", "true") && ("," + Global.getSystemConfig("can.transfer.format", "") + ",").contains("," + tail + ",") && StringUtils.isEmpty(templateType)) { viewOnlineSign = 1; } } final String fileFinalName = FileUtils.uploadFile(tempFile, templateType, clientUuid); // 记录附件信息到数据库 logger.info("正在记录附件信息到数据库..."); FieldSetEntity dictFse = baseDao.getFieldSetEntityByFilter(CmnConst.PRODUCT_SYS_DICT, new String[]{CmnConst.UUID, CmnConst.DICT_VALUE}, "lower( " + CmnConst.DICT_VALUE + ")=lower(?) and dict_name='upload_file_format' and is_used=1", new Object[]{tail}, false, ""); FieldSetEntity attachmentFse = new FieldSetEntity(); attachmentFse.setTableName(CmnConst.PRODUCT_SYS_ATTACHMENTS); String fileType; if (dictFse != null && !StringUtils.isEmpty(dictFse.getString(CmnConst.UUID))) { attachmentFse.setValue(CmnConst.ATTACHMENT_TYPE_UUID, dictFse.getUUID()); fileType = dictFse.getString(CmnConst.DICT_VALUE); } else { fileType = tail; attachmentFse.setValue(CmnConst.ATTACHMENT_TYPE_UUID, tail); } //允许编辑 int allowEdit = ("," + Global.getSystemConfig("can.web.online.edit", "doc,docx,xls,xlsx.ppt,pptx,wps,cvs,wps,wpt,et,eet") + ",").indexOf("," + fileType + ",") != -1 ? 1 : 0; attachmentFse.setValue(CmnConst.OPT_FLAT, 2); attachmentFse.setValue(CmnConst.FILE_NAME, fileName); attachmentFse.setValue(CmnConst.ATTACHMENT_TITLE, fileFinalName); attachmentFse.setValue(CmnConst.CLIENT_UUID, clientUuid); attachmentFse.setValue(CmnConst.VIEW_ONLINE_SIGN, viewOnlineSign); attachmentFse.setValue(CmnConst.ATTACHMENT_DATA_TABLE, fse.getTableName()); attachmentFse.setValue(CmnConst.ATTACHMENT_DATA_FIELD, fieldName); attachmentFse.setValue(CmnConst.ATTACHMENT_URL, dir.replaceAll("\\\\", "/")); attachmentFse.setValue(CmnConst.ENCRPT_SIGN, Global.getPropertyToBoolean("file.encrypt", "true") ? 1 : 0); attachmentFse.setValue(CmnConst.ATTACHMENT_SIZE, fileLength); attachmentFse.setValue(CmnConst.UPLOAD_SIGN, needUpload2FileServerFlag ? 1 : 0); attachmentFse.setValue(CmnConst.ATTACHMENT_CONTAINER, fse.getString(CmnConst.ATTACHMENT_CONTAINER)); attachmentFse.setValue(CmnConst.ATTACHMENT_DOMAIN, fse.getString(CmnConst.ATTACHMENT_DOMAIN)); attachmentFse.setValue(CmnConst.MODULE_UUID, fse.getString(CmnConst.MODULE_UUID)); //luoxin 未获取当前人id 就直接覆1 try { attachmentFse.setValue(CmnConst.CREATED_BY, SpringMVCContextHolder.getCurrentUser().getUser_id()); } catch (Exception e) { e.getStackTrace(); attachmentFse.setValue(CmnConst.CREATED_BY, 1); } attachmentFse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date()); baseDao.saveFieldSetEntity(attachmentFse); logger.info("记录成功"); String uuid = attachmentFse.getUUID(); FieldSetEntity fseIndex = new FieldSetEntity(); fseIndex.setTableName("fseIndex"); fseIndex.setValue("function_uuid", fse.getString("function_uuid")); fseIndex.setValue("attachment_uuid", uuid); CreateDocumentIndexThread.getInstance().appendAttaInfo(fseIndex); fse.setValue(uuid, fileName); fse.setValue(entry.getKey().toString(), uuid); fse.setValue(entry.getKey().toString() + "_edit", allowEdit); fse.setValue(entry.getKey().toString() + "_type", fileType); if (!StringUtils.isEmpty(uuids)) { uuids += ","; } uuids += uuid; } logger.info("正在回写uuid..."); System.out.println(uuids); fse.setValue(fieldName, uuids); } return fse; } /** * 提取文件信息-下载文件或者在线预览文件 * * @param fse * @param response */ public void getFileContent(FieldSetEntity fse, HttpServletResponse response) throws IOException { logger.info("正在获取文件流..."); String uuid = fse.getUUID(); FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, uuid, false); if (attachmentFse == null) { return; } boolean needDownloadFromServerFlag = "1".equals(attachmentFse.getString(CmnConst.UPLOAD_SIGN)); String dir = attachmentFse.getString(CmnConst.ATTACHMENT_URL); String fileName = attachmentFse.getString(CmnConst.ATTACHMENT_TITLE); String viewOnlineSign = attachmentFse.getString(CmnConst.VIEW_ONLINE_SIGN); boolean encrptSignFlag = "1".equals(attachmentFse.getString(CmnConst.ENCRPT_SIGN)); boolean needOnlineViewFlag = "1".equals(fse.getString(CmnConst.NEED_ONLINE_VIEW)) && "1".equals(viewOnlineSign); if (needOnlineViewFlag) { // 需要在线预览且转换之后才能在线预览 dir += File.separator + CmnConst.TRANSFER_DIR_NAME; } HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); String userAgent = request.getHeader("User-Agent"); String file_name = attachmentFse.getString("file_name"); if (userAgent.contains("MSIE") || userAgent.contains("Trident")) { file_name = java.net.URLEncoder.encode(file_name, "UTF-8"); } else { // 非IE浏览器的处理: file_name = new String(file_name.getBytes("UTF-8"), "ISO-8859-1"); } String path = dir + File.separator + fileName; if (needDownloadFromServerFlag) { // 需要从附件服务器上取文件 FTPService ftpService = new FTPService(); logger.info("需要从附件服务器上取文件..."); response.setContentType("multipart/form-data"); response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", file_name)); if (!needOnlineViewFlag && !encrptSignFlag) { logger.info("不需要解密且获取原文件..."); try (ServletOutputStream os = response.getOutputStream()) { ftpService.downloadFile(path, os); } } else { logger.info("需要解密或者获取转换后的文件..."); String localTempPath = Global.getSystemConfig("temp.dir", "") + File.separator + fileName; File localTempFile = new File(localTempPath); OutputStream tempOs = new FileOutputStream(localTempFile); ftpService.downloadFile(path, tempOs); tempOs.flush(); tempOs.close(); if (needOnlineViewFlag && localTempFile.length() == 0L) { // 若是预览,但是转换后的文件不存在,那么重新执行转换操作 File sourceFile = fileUtils.getFile(true, attachmentFse.getString(CmnConst.ATTACHMENT_URL), fileName, encrptSignFlag); File tempSourceFile = new File(sourceFile.getParentFile().getAbsolutePath() + File.separator + attachmentFse.getString(CmnConst.FILE_NAME)); sourceFile.renameTo(tempSourceFile); FileUtils.convertPdf(false, true, encrptSignFlag, true, tempSourceFile, dir, fileName, attachmentFse.getString(CmnConst.FILE_NAME)); tempSourceFile.delete(); // 重新拉文件 tempOs = new FileOutputStream(localTempFile); ftpService = new FTPService(); ftpService.downloadFile(path, tempOs); tempOs.flush(); tempOs.close(); } response.setContentLengthLong(localTempFile.length()); InputStream is = new FileInputStream(localTempFile); int len; byte[] b = new byte[1024]; try (ServletOutputStream os = response.getOutputStream()) { while ((len = is.read(b)) > 0) { os.write(encrptSignFlag ? FileUtil.decryption(b) : b, 0, len); } os.flush(); is.close(); } // 删除临时文件 localTempFile.delete(); } } else { // 直接在本地的目录中找文件 logger.info("直接在本地的目录中找文件..."); String localBasePath = Global.getSystemConfig("local.dir", ""); path = localBasePath + File.separator + path; File file = new File(path); if (needOnlineViewFlag && !file.exists()) { // 若是预览,但是转换后的文件不存在,那么重新执行转换操作 File sourceFile = fileUtils.getFile(false, attachmentFse.getString(CmnConst.ATTACHMENT_URL), fileName, encrptSignFlag); File tempSourceFile = new File(sourceFile.getParentFile().getAbsolutePath() + File.separator + attachmentFse.getString(CmnConst.FILE_NAME)); sourceFile.renameTo(tempSourceFile); FileUtils.convertPdf(false, false, encrptSignFlag, true, tempSourceFile, dir, fileName, attachmentFse.getString(CmnConst.FILE_NAME)); tempSourceFile.delete(); } int len; byte[] b = new byte[1024]; response.setContentType("multipart/form-data"); InputStream is = new FileInputStream(file); response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", file_name)); response.setContentLengthLong(file.length()); try (ServletOutputStream os = response.getOutputStream()) { while ((len = is.read(b)) > 0) { if (encrptSignFlag) { // 需要解密 logger.info("需要解密..."); os.write(FileUtil.decryption(b), 0, len); } else { // 无需解密 os.write(b, 0, len); } } os.flush(); } } logger.info("文件流获取成功"); } /** * 获取文件字节 根据文件uuid */ public byte[] getFileContent(String uuid) throws BaseException { FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, uuid, false); return this.getFileContent(attachmentFse); } /** * 根据附件uuid获取文件 * 用完之后需要删除返回的 file (临时文件) * * @param uuid * @return * @throws BaseException */ public File getFile(String uuid) throws BaseException { FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, uuid, false); byte[] fileContent = getFileContent(attachmentFse); if (fileContent != null && fileContent.length > 0) { String localTempPath = Global.getSystemConfig("temp.dir", "") + File.separator + new Date().getTime() + attachmentFse.getString(CmnConst.ATTACHMENT_TITLE) + attachmentFse.getString("file_name"); File temp = new File(localTempPath); File td = new File(Global.getSystemConfig("temp.dir", "")); if (!td.exists()) td.mkdirs(); try { temp.createNewFile(); } catch (IOException e) { throw new BaseException(FileCode.GET_FILE_FAIL.getValue(), FileCode.GET_FILE_FAIL.getText() + (e.getMessage() != null ? e.getMessage() : "")); } try (FileOutputStream fos = new FileOutputStream(temp); BufferedOutputStream out = new BufferedOutputStream(fos)) { out.write(fileContent); return temp; } catch (Exception e) { e.printStackTrace(); throw new BaseException(FileCode.GET_FILE_FAIL.getValue(), FileCode.GET_FILE_FAIL.getText() + (e.getMessage() != null ? e.getMessage() : "")); } } throw new BaseException(FileCode.GET_FILE_FAIL.getValue(), FileCode.GET_FILE_FAIL.getText()); } /** * 获取文件字节 根据附件field */ public byte[] getFileContent(FieldSetEntity attachmentFse) throws BaseException { if (attachmentFse == null || !CmnConst.PRODUCT_SYS_ATTACHMENTS.equals(attachmentFse.getTableName())) { return new byte[16]; } try (ByteArrayOutputStream os = new ByteArrayOutputStream();) { FTPService ftpService = new FTPService(); boolean needDownloadFromServerFlag = "1".equals(attachmentFse.getString(CmnConst.UPLOAD_SIGN)); String dir = attachmentFse.getString(CmnConst.ATTACHMENT_URL); String fileName = attachmentFse.getString(CmnConst.ATTACHMENT_TITLE); boolean encrptSignFlag = "1".equals(attachmentFse.getString(CmnConst.ENCRPT_SIGN)); String path = dir + File.separator + fileName; if (needDownloadFromServerFlag) { // 需要从附件服务器上取文件 if (encrptSignFlag) { // 需要解密 String localTempPath = Global.getSystemConfig("temp.dir", "") + File.separator + fileName; File localTempFile = new File(localTempPath); OutputStream tempOs = new FileOutputStream(localTempFile); ftpService.downloadFile(path, tempOs); tempOs.flush(); tempOs.close(); InputStream is = new FileInputStream(localTempFile); int len; byte[] b = new byte[1024]; while ((len = is.read(b)) > 0) { os.write(FileUtil.decryption(b), 0, len); } os.flush(); is.close(); // 删除临时文件 localTempFile.delete(); } else { ftpService.downloadFile(path, os); } } else { // 直接在本地的目录中找文件 String localBasePath = Global.getSystemConfig("local.dir", ""); path = localBasePath + File.separator + path; File file = new File(path); int len; byte[] b = new byte[1024]; try (InputStream is = new FileInputStream(file)) { while ((len = is.read(b)) > 0) { if (Global.getPropertyToBoolean("file.encrypt", "true")) { // 需要解密 os.write(FileUtil.decryption(b), 0, len); } else { // 无需解密 os.write(b, 0, len); } } } } return os.toByteArray(); } catch (Exception e) { SpringMVCContextHolder.getSystemLogger().error(FileCode.GET_FILE_BYTES_FAIL.getValue(), FileCode.GET_FILE_BYTES_FAIL.getText() + "," + e.getMessage()); throw new BaseException(FileCode.GET_FILE_BYTES_FAIL.getValue(), FileCode.GET_FILE_BYTES_FAIL.getText() + "," + e.getMessage()); } } /** * 获取文件字节,再转换成字符串 根据文件uuid */ public String getFileContentString(String uuid) { byte[] b = getFileContent(uuid); if (b == null) { return null; } String str = new String(b); return str; } /** * 提取文件信息-批量打包下载文件 * * @param fse * @param */ public void downLoadFileZip(FieldSetEntity fse, HttpServletResponse response) throws IOException, BaseException { logger.info("正在打包下载文件..."); response.setContentType("multipart/form-data"); try (ServletOutputStream os = response.getOutputStream()) { String uuids = fse.getString("uuids"); if (StringUtils.isEmpty(uuids)) { throw new BaseException(FileCode.GET_DATA_FAIL.getValue(), FileCode.GET_DATA_FAIL.getText() + ":uuids"); } DataTableEntity attachmentDte = baseDao.listTable(CmnConst.PRODUCT_SYS_ATTACHMENTS, new Object[]{CmnConst.ATTACHMENT_URL, CmnConst.FILE_NAME, CmnConst.VIEW_ONLINE_SIGN, CmnConst.FILE_NAME, CmnConst.ENCRPT_SIGN, CmnConst.ATTACHMENT_TITLE, CmnConst.UPLOAD_SIGN}, uuids.split(",")); FieldSetEntity attachmentFse; String fileName; String dir; String sourcePath; String localTempPath; FTPService ftpService; boolean needDownloadFromServerFlag; List> pathList = Lists.newArrayList(); Map pathMap; for (int i = 0; i < attachmentDte.getRows(); i++) { pathMap = Maps.newHashMap(); attachmentFse = attachmentDte.getFieldSetEntity(i); needDownloadFromServerFlag = "1".equals(attachmentFse.getString(CmnConst.UPLOAD_SIGN)); fileName = attachmentFse.getString(CmnConst.ATTACHMENT_TITLE); dir = attachmentFse.getString(CmnConst.ATTACHMENT_URL); sourcePath = dir + File.separator + fileName; localTempPath = Global.getSystemConfig("temp.dir", "") + File.separator + fileName; pathMap.put(CmnConst.REAL_FILE_NAME, attachmentFse.getString(CmnConst.FILE_NAME)); pathMap.put(CmnConst.ENCRPT_SIGN, attachmentFse.getString(CmnConst.ENCRPT_SIGN)); if (needDownloadFromServerFlag) { ftpService = new FTPService(); ftpService.downloadFile(sourcePath, localTempPath); pathMap.put(CmnConst.NEED_LOCAL_TEMP_FILE_SIGN, "1"); pathMap.put(CmnConst.SOURCE_PATH, localTempPath); } else { pathMap.put(CmnConst.NEED_LOCAL_TEMP_FILE_SIGN, "0"); pathMap.put(CmnConst.SOURCE_PATH, Global.getSystemConfig("local.dir", "") + File.separator + sourcePath); } pathList.add(pathMap); } long fileSize = FileUtil.createZip(pathList, os); response.setContentLengthLong(fileSize); File file; for (Map map : pathList) { for (String key : map.keySet()) { if ("1".equals(map.get(CmnConst.NEED_LOCAL_TEMP_FILE_SIGN)) && !CmnConst.SOURCE_PATH.equals(key)) { continue; } file = new File(key); file.delete(); } } logger.info("文件流获取成功"); } catch (IOException e) { throw e; } } /** * 删除本地或线上服务器文件 * * @param fse * @return */ public boolean delFiles(FieldSetEntity fse) { FTPService ftpService = new FTPService(); boolean needUpload2FileServerFlag = FTPService.needUpload2FileServer(); String uuid = fse.getString(CmnConst.UUID); boolean needOnlineViewFlag = "1".equals(fse.getString(CmnConst.UPLOAD_SIGN)); FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, uuid, false); String path = attachmentFse.getString(CmnConst.ATTACHMENT_URL); if (needUpload2FileServerFlag) { //删除线上服务器文件 ftpService.deleteFile(path, attachmentFse.getString(CmnConst.FILE_NAME)); //if(needOnlineViewFlag){//需要删除转换后的文件 path += File.separator + CmnConst.TRANSFER_DIR_NAME; ftpService.deleteFile(path, attachmentFse.getString(CmnConst.FILE_NAME)); //} } else { //删除本地服务器文件 deleteFiles(Global.getSystemConfig("temp.dir", "") + "/" + attachmentFse.getString(CmnConst.FILE_NAME));// 路径及文件名(或文件夹) deleteFiles(Global.getSystemConfig("temp.dir", "") + "/" + CmnConst.TRANSFER_DIR_NAME + "/" + attachmentFse.getString(CmnConst.FILE_NAME));// 在线预览路径及文件名(或文件夹) deleteFiles(Global.getSystemConfig("local.dir", "") + "/" + attachmentFse.getString(CmnConst.FILE_NAME));// 路径及文件名(或文件夹) deleteFiles(Global.getSystemConfig("local.dir", "") + "/" + CmnConst.TRANSFER_DIR_NAME + "/" + attachmentFse.getString(CmnConst.FILE_NAME));// 在线预览路径及文件名(或文件夹) } //删除数据库记录 return baseDao.delete(CmnConst.PRODUCT_SYS_ATTACHMENTS, new Object[]{uuid}); } /** * 删除单个文件 * * @param pathName 删除文件路径名 * @return */ public boolean deleteFiles(String pathName) { boolean flag = false; //根据路径创建文件对象 File file = new File(pathName); //路径是个文件且不为空时删除文件 if (file.isFile() && file.exists()) { flag = file.delete(); } //删除失败时,返回false return flag; } /** * 删除目录本身以及目录下的所有文件及文件夹 * * @param pathName 目录名 * @return */ public boolean deleteDiretory(String pathName) { boolean flag = false; //根据路径创建文件对象 File directory = new File(pathName); //如果路径是一个目录且不为空时,删除目录 if (directory.isDirectory() && directory.exists()) { //获取目录下的所有的目录和文件,放入数组files中 File[] files = directory.listFiles(); //遍历目录下的所有的文件和目录 for (int i = 0; i < files.length; i++) { //如果目录下是文件时,调用deleteFiles()方法,删除单个文件 if (files[i].isFile()) { flag = deleteFiles(files[i].getAbsolutePath()); }//如果目录下是目录时,调用自身deleteDirectory(),形成递归调用 else { flag = deleteDiretory(files[i].getAbsolutePath()); } } //删除目录本身,如果想要保留目录只删除文件,此句可以不要 flag = directory.delete(); } //删除成功时返回true,失败时返回false return flag; } /** * 删除文件或者目录 * * @param pathName 路径名 * @return */ public boolean deleteDirectoryOrFile(String pathName) { boolean flag = false; File file = new File(pathName); //如果路径是一个文件则调用deleteFiles() if (file.isFile() && file.exists()) { flag = deleteFiles(pathName); }//如果路径是目录则调用deleteDirectory() else if (file.isDirectory() && file.exists()) { flag = deleteDiretory(pathName); } return flag; } }