| | |
| | | package com.product.file.service; |
| | | |
| | | import cn.hutool.core.date.DateUtil; |
| | | import cn.hutool.core.util.RandomUtil; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.google.common.collect.Lists; |
| | | import com.google.common.collect.Maps; |
| | | import com.product.common.lang.StringUtils; |
| | | import com.product.core.cache.util.RedisUtil; |
| | | import com.product.core.config.CoreConst; |
| | | import com.product.core.config.Global; |
| | | import com.product.core.connection.ConnectionManager; |
| | | import com.product.core.dao.BaseDao; |
| | |
| | | import com.product.core.spring.context.SpringMVCContextHolder; |
| | | import com.product.file.config.CmnConst; |
| | | import com.product.file.config.FileCode; |
| | | import com.product.file.util.AsposeUtil; |
| | | 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 com.product.tool.table.enums.FieldType; |
| | | import com.product.util.BaseUtil; |
| | | import com.product.util.http.HttpRequestUtil; |
| | | import okhttp3.MediaType; |
| | | import okhttp3.MultipartBody; |
| | | import okhttp3.RequestBody; |
| | | 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.net.URLEncoder; |
| | | import java.nio.file.Files; |
| | | import java.nio.file.StandardCopyOption; |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.*; |
| | | |
| | |
| | | public BaseDao baseDao; |
| | | @Autowired |
| | | FileUtils fileUtils; |
| | | |
| | | /** |
| | | * 标记文件已被修改 |
| | | * @param uuid |
| | | * @param userId |
| | | */ |
| | | public void signUpdateAttachment(String uuid, int userId) { |
| | | baseDao.executeUpdate("UPDATE product_sys_attachments SET updated_by = ?, updated_utc_datetime = NOW() WHERE uuid = ?", new Object[] {userId, uuid}); |
| | | } |
| | | |
| | | /** |
| | | * 获取静态资源 |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 集群文件同步方法-接收 |
| | | * @param rpe |
| | | * @return |
| | | */ |
| | | public void clusterFileSyncAccept(RequestParameterEntity rpe) throws IOException { |
| | | List<String> ipList = RedisUtil.getSet(CoreConst.SYSTEM_IP_PORT_KEY, String.class); |
| | | String curRequestIp = rpe.getIp(); |
| | | boolean checkFlag = false; |
| | | for (String ipInfo : ipList) { |
| | | if (!StringUtils.isEmpty(ipInfo) && ipInfo.contains(":") && curRequestIp.equals(ipInfo.split(":")[0])) { |
| | | checkFlag = true; |
| | | break; |
| | | } |
| | | } |
| | | if (!checkFlag) { |
| | | throw new BaseException(FileCode.CLUSTER_FILE_SYNC_CHECK_FAIL); |
| | | } |
| | | Map<Object, Object> otherMap = rpe.getOther(); |
| | | Map<String, File> fileMap = rpe.getFiles(); |
| | | File aimFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + otherMap.get("relativePath")); |
| | | for (Map.Entry<String, File> entry : fileMap.entrySet()) { |
| | | File file = entry.getValue(); |
| | | Files.copy(file.toPath(), aimFile.toPath(), StandardCopyOption.REPLACE_EXISTING); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 集群文件同步方法-请求调用 |
| | | * @param file 同步的文件 |
| | | * @param fileName 文件名称,保存的文件名称,就是时间戳+2位随机字符串 |
| | | * @param relativePath 相对路径 |
| | | * @param attachmentUUID 附近表uuid |
| | | * @param preLogFse 之前的日志fse |
| | | */ |
| | | public void clusterFileSyncRequest(File file, String fileName, String relativePath, String attachmentUUID, FieldSetEntity preLogFse) { |
| | | try { |
| | | if (file == null || StringUtils.isEmpty(fileName)) { |
| | | return; |
| | | } |
| | | List<String> ipList = RedisUtil.getSet(CoreConst.SYSTEM_IP_PORT_KEY, String.class); |
| | | String curIpInfo = Global.getSystemConfig(CoreConst.SYSTEM_NAME, ""); |
| | | for (String ipInfo : ipList) { |
| | | // 排除当前 |
| | | if (curIpInfo.equals(ipInfo)) { |
| | | continue; |
| | | } |
| | | if (!StringUtils.isEmpty(ipInfo) && ipInfo.contains(":")) { |
| | | String url = String.format("http://%s/lx/api/fileManager/cluster-file-sync/v1", ipInfo); |
| | | RequestBody requestBody = new MultipartBody.Builder() |
| | | .setType(MultipartBody.FORM) |
| | | // 添加文件字段 |
| | | .addFormDataPart("file", fileName, RequestBody.create(MediaType.parse("application/octet-stream"), file)) |
| | | .addFormDataPart("title", fileName) |
| | | .addFormDataPart("relativePath", relativePath) |
| | | .build(); |
| | | JSONObject result = HttpRequestUtil.request(url, "POST", "multipart/form-data", requestBody); |
| | | SpringMVCContextHolder.getSystemLogger().error("[6ctest]:" + result.toString()); |
| | | // 记录日志 |
| | | recordClusterSyncFileLog(result, attachmentUUID, curIpInfo, ipInfo, preLogFse); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | throw new BaseException(FileCode.CLUSTER_FILE_SYNC_FAIL); |
| | | } |
| | | } |
| | | public void clusterFileSyncRequest(File file, String fileName, String relativePath, String attachmentUUID) { |
| | | clusterFileSyncRequest(file, fileName, relativePath, attachmentUUID, null); |
| | | } |
| | | |
| | | /** |
| | | * 记录集群同步文件日志 |
| | | * @param result 结果,-1-失败,1-成功,2-已重新处理 |
| | | * @param attachmentUUID 附件uuid |
| | | * @param sourceIpInfo 请求地址信息 |
| | | * @param targetIpInfo 目标地址信息 |
| | | * @param preLogFse 之前日志fse |
| | | */ |
| | | private void recordClusterSyncFileLog(JSONObject result, String attachmentUUID, String sourceIpInfo, String targetIpInfo, FieldSetEntity preLogFse) { |
| | | FieldSetEntity logFse = new FieldSetEntity(); |
| | | logFse.setTableName(CmnConst.PRODUCT_SYS_CLUSTER_SYNC_FILE_LOG); |
| | | if (!"200".equals(result.getString("code"))) { |
| | | logFse.setValue(CmnConst.ERROR_INFO, result.getString("msg")); |
| | | logFse.setValue(CmnConst.RESULT, -1); |
| | | logFse.setValue(CmnConst.NEED_RETRY, 1); |
| | | } else { |
| | | logFse.setValue(CmnConst.RESULT, 1); |
| | | logFse.setValue(CmnConst.NEED_RETRY, -1); |
| | | } |
| | | if (!FieldSetEntity.isEmpty(preLogFse)) { |
| | | logFse.setValue(CmnConst.RETRY_COUNT, preLogFse.getInteger(CmnConst.RETRY_COUNT) == null ? 1 : (preLogFse.getInteger(CmnConst.RETRY_COUNT) + 1)); |
| | | logFse.setValue(CmnConst.PRE_UUID, preLogFse.getUUID()); |
| | | } else { |
| | | logFse.setValue(CmnConst.RETRY_COUNT, 0); |
| | | } |
| | | logFse.setValue(CmnConst.ATTACHMENT_UUID, attachmentUUID); |
| | | logFse.setValue(CmnConst.SOURCE_INFO, sourceIpInfo); |
| | | logFse.setValue(CmnConst.TARGET_INFO, targetIpInfo); |
| | | logFse.setValue(CmnConst.CREATED_UTC_DATETIME, new Date()); |
| | | SystemUser curUser = SpringMVCContextHolder.getCurrentUser(); |
| | | logFse.setValue(CmnConst.CREATED_BY, curUser == null ? -1 : curUser.getUser_id()); |
| | | baseDao.saveFieldSetEntity(logFse); |
| | | } |
| | | |
| | | /** |
| | | * 定时任务触发-扫描集群同步文件日志记录表,重试未达最大次数的错误日志 |
| | | */ |
| | | public void retryClusterSyncFileFailLog() { |
| | | // 最大重试次数 |
| | | int maxRetryCount = 3; |
| | | // 当前地址信息 |
| | | String curIpInfo = Global.getSystemConfig(CoreConst.SYSTEM_NAME, ""); |
| | | DataTableEntity waitRetryDte = baseDao.listTable(CmnConst.PRODUCT_SYS_CLUSTER_SYNC_FILE_LOG, "result=-1 AND retry_count<? AND need_retry=1 AND source_info=?", new Object[]{maxRetryCount, curIpInfo}); |
| | | for (int i = 0; i < waitRetryDte.getRows(); i++) { |
| | | FieldSetEntity waitRetryFse = waitRetryDte.getFieldSetEntity(i); |
| | | |
| | | FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, waitRetryFse.getString(CmnConst.ATTACHMENT_UUID), false); |
| | | String fileName = attachmentFse.getString("attachment_title"); |
| | | String relativePath = attachmentFse.getString("attachment_url") + File.separator + fileName; |
| | | File aimFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + relativePath); |
| | | clusterFileSyncRequest(aimFile, fileName, relativePath, attachmentFse.getUUID(), waitRetryFse); |
| | | |
| | | waitRetryFse.setValue(CmnConst.RESULT, 2); |
| | | waitRetryFse.setValue(CmnConst.NEED_RETRY, -1); |
| | | baseDao.saveFieldSetEntity(waitRetryFse); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 上传文件到本地服务器 |
| | | * 禁止修改任何逻辑!!!!!! |
| | |
| | | Object value; |
| | | String fileNames; |
| | | FieldSetEntity fieldFse; |
| | | File tempFile; |
| | | File tempFile = null; |
| | | File localTempFile = null; |
| | | long fileLength = 0; |
| | | |
| | |
| | | } |
| | | |
| | | String uuids = ""; |
| | | String fileFinalName = ""; |
| | | for (Map.Entry<Object, Object> 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); |
| | | if (fieldFse == null || !Arrays.asList(CmnConst.ATTACHMENT_TYPE, "file-image", FieldType.FILE_ATTACHMENT.getDictValue()).contains(fieldFse.getString(CmnConst.FIELD_TYPE))) { |
| | | fse.setValue(entry.getKey().toString(), null); |
| | | continue; |
| | | } |
| | | // 已经判定为附件,进行操作 |
| | |
| | | } |
| | | } |
| | | |
| | | |
| | | final String fileFinalName = FileUtils.uploadFile(tempFile, templateType, clientUuid); |
| | | boolean saveInDbFlag = FieldType.FILE_ATTACHMENT.getDictValue().equals(fieldFse.getString("field_type")); |
| | | if (!saveInDbFlag) { |
| | | fileFinalName = FileUtils.uploadFile(tempFile, templateType, clientUuid); |
| | | } else { |
| | | fileFinalName = System.currentTimeMillis() + RandomUtil.randomString(2); |
| | | } |
| | | |
| | | // 记录附件信息到数据库 |
| | | 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.FUNCTION_UUID, fse.getString(CmnConst.FUNCTION_UUID)); |
| | | 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); |
| | | } |
| | | 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); |
| | | } |
| | | if (saveInDbFlag) { |
| | | // 判断附件字段的类型为FileAttachment时,要把文档内容放到附件表中的file_content字段中 |
| | | try { |
| | | attachmentFse.setValue(CmnConst.FILE_CONTENT, com.product.common.io.FileUtils.readFileToByteArray(tempFile)); |
| | | } catch (Exception e) { |
| | | throw new BaseException(FileCode.FILE_TRANSFER_BYTE_ARRAY_FAIL); |
| | | } |
| | | } |
| | | //允许编辑 |
| | | 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.FUNCTION_UUID, fse.getString(CmnConst.FUNCTION_UUID)); |
| | | 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; |
| | | 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; |
| | | |
| | | // 集群布署本地存储时,附件信息要同步到其它服务器上 |
| | | if (!saveInDbFlag && !needUpload2FileServerFlag) { |
| | | File curFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + dir + File.separator + fileFinalName); |
| | | clusterFileSyncRequest(curFile, fileFinalName, dir + File.separator + fileFinalName, attachmentFse.getUUID()); |
| | | } |
| | | } |
| | | logger.info("正在回写uuid..."); |
| | | System.out.println(uuids); |
| | | fse.setValue(fieldName, uuids); |
| | | } |
| | | return fse; |
| | | } |
| | | |
| | | /** |
| | | * 根据附件表数据生成文档索引 |
| | | */ |
| | | public void readAttachmentCreateIndex() { |
| | | // 遍历附件表 |
| | | DataTableEntity dtAttachment = baseDao.listTable(CmnConst.PRODUCT_SYS_ATTACHMENTS); |
| | | if (BaseUtil.dataTableIsEmpty(dtAttachment)) { |
| | | return; |
| | | } |
| | | for (int i = 0; i < dtAttachment.getRows(); i++) { |
| | | // 获取附件信息,并判断是否有表和字段 |
| | | FieldSetEntity fseAttachment = dtAttachment.getFieldSetEntity(i); |
| | | if (BaseUtil.strIsNull(fseAttachment.getString("attachment_data_field")) || BaseUtil.strIsNull(fseAttachment.getString("attachment_data_field"))) { |
| | | continue; |
| | | } |
| | | // 查询原数据,有原数据再生成文档检索 |
| | | FieldSetEntity fseRecord = baseDao.getFieldSetEntityByFilter(fseAttachment.getString("attachment_data_table"), fseAttachment.getString("attachment_data_field") + " LIKE ?", new Object[]{"%" + fseAttachment.getUUID() + "%"}, false); |
| | | if (fseRecord != null) { |
| | | // 生成文档检索信息 |
| | | FieldSetEntity fseIndex = new FieldSetEntity(); |
| | | fseIndex.setTableName("fseIndex"); |
| | | fseIndex.setValue("function_uuid", fseAttachment.getString("function_uuid")); |
| | | fseIndex.setValue("attachment_uuid", fseAttachment.getUUID()); |
| | | CreateDocumentIndexThread.getInstance().appendAttaInfo(fseIndex); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 移动端升级,安装包下载 |
| | | * |
| | | * @param fse |
| | | * @param response |
| | | */ |
| | | public void getFileContent(FieldSetEntity fse, HttpServletResponse response, boolean isUpgrade) throws IOException { |
| | | if (isUpgrade) { |
| | | FieldSetEntity attachmentFse = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_ATTACHMENTS, fse.getUUID(), false); |
| | | if (attachmentFse == null || !"product_sys_app_version".equals(attachmentFse.getString("attachment_data_table"))) { |
| | | return; |
| | | } |
| | | logger.info("正在获取文件流..."); |
| | | boolean needDownloadFromServerFlag = "1".equals(attachmentFse.getString(CmnConst.UPLOAD_SIGN)); |
| | | String dir = attachmentFse.getString(CmnConst.ATTACHMENT_URL); |
| | | String fileName = attachmentFse.getString(CmnConst.ATTACHMENT_TITLE); |
| | | //真实文件名 |
| | | String realFileName = attachmentFse.getString(CmnConst.FILE_NAME); |
| | | 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); |
| | | |
| | | String clientType = CoreConst.CLIENT_TYPE_APP; |
| | | |
| | | String contentType = "multipart/form-data"; |
| | | boolean isExcel = realFileName.endsWith(".xlsx") || realFileName.endsWith(".xls"); |
| | | if (needOnlineViewFlag) { |
| | | //特殊处理: 如果客户端不是App 但预览的文件是Excel 直接返回excel源文件 content头标识是excel cheng 2025年2月11日10:41:41 |
| | | if (isExcel && !CoreConst.CLIENT_TYPE_APP.equals(clientType)) { |
| | | contentType = "application/vnd.ms-excel"; |
| | | } else { |
| | | dir += File.separator + CmnConst.TRANSFER_DIR_NAME; |
| | | } |
| | | } |
| | | |
| | | String path = dir + File.separator + fileName; |
| | | if (needDownloadFromServerFlag) { |
| | | // 需要从附件服务器上取文件 |
| | | FTPService ftpService = new FTPService(); |
| | | logger.info("需要从附件服务器上取文件..."); |
| | | response.setHeader("Access-Control-Expose-Headers", "*"); |
| | | |
| | | response.setContentType(contentType); |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8")); |
| | | //设置头中的文件类型 |
| | | 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() && CoreConst.CLIENT_TYPE_APP.equals(clientType)) { |
| | | //特殊处理: 是App 但预览的文件是Excel 需要将之前已转换为的文件删除掉重新转换(因转换后的格式不是pdf) |
| | | String changeTime = "2025-02-11 23:59:59"; |
| | | Date changeDate = DateUtil.parse(changeTime, "yyyy-MM-dd HH:mm:ss"); |
| | | long fileTime = file.lastModified(); |
| | | //如果时间是 2025年2月10日23:59:59,那么就重新转换 |
| | | //删除文件 |
| | | if (fileTime <= changeDate.getTime()) { |
| | | file.delete(); |
| | | } |
| | | } |
| | | 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]; |
| | | InputStream is = new FileInputStream(file); |
| | | response.setHeader("Access-Control-Expose-Headers", "*"); |
| | | |
| | | response.setContentType(contentType); |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8")); |
| | | 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(); |
| | | } |
| | | is.close(); |
| | | } |
| | | logger.info("文件流获取成功"); |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | |
| | | 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 && !realFileName.endsWith(".xlsx") && !realFileName.endsWith(".xls")) { |
| | | // 需要在线预览且转换之后才能在线预览 excel 文件不需要转换直接输出预览 |
| | | dir += File.separator + CmnConst.TRANSFER_DIR_NAME; |
| | | String clientType = SpringMVCContextHolder.getCurrentUser().getClientType(); |
| | | |
| | | String contentType = "multipart/form-data"; |
| | | boolean isExcel = realFileName.endsWith(".xlsx") || realFileName.endsWith(".xls"); |
| | | if (needOnlineViewFlag) { |
| | | //特殊处理: 如果客户端不是App 但预览的文件是Excel 直接返回excel源文件 content头标识是excel cheng 2025年2月11日10:41:41 |
| | | if (isExcel && !CoreConst.CLIENT_TYPE_APP.equals(clientType)) { |
| | | contentType = "application/vnd.ms-excel"; |
| | | } else { |
| | | dir += File.separator + CmnConst.TRANSFER_DIR_NAME; |
| | | } |
| | | } |
| | | |
| | | String path = dir + File.separator + fileName; |
| | |
| | | FTPService ftpService = new FTPService(); |
| | | logger.info("需要从附件服务器上取文件..."); |
| | | response.setHeader("Access-Control-Expose-Headers", "*"); |
| | | if (realFileName.endsWith(".xlsx") || realFileName.endsWith(".xls")) { |
| | | response.setContentType("application/vnd.ms-excel"); |
| | | } else { |
| | | response.setContentType("multipart/form-data"); |
| | | } |
| | | |
| | | response.setContentType(contentType); |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8")); |
| | | //设置头中的文件类型 |
| | | if (!needOnlineViewFlag && !encrptSignFlag) { |
| | |
| | | tempOs.flush(); |
| | | tempOs.close(); |
| | | } |
| | | boolean delete = false; |
| | | if (realFileName.endsWith(".xls") && needOnlineViewFlag && localTempFile.exists() && !CoreConst.CLIENT_TYPE_APP.equals(clientType)) { |
| | | //转换为xlsx |
| | | AsposeUtil.xls2xlsx(localTempFile.getPath(), getSystemConfig("temp.dir", "/attachment/temp") + "/" + localTempFile.getName(), "xls"); |
| | | File oldFile = localTempFile; |
| | | localTempFile = new File(getSystemConfig("temp.dir", "/attachment/temp") + "/" + localTempFile.getName()); |
| | | if (!localTempFile.isFile()) { |
| | | localTempFile = oldFile; |
| | | } else { |
| | | delete = true; |
| | | oldFile.delete(); |
| | | } |
| | | } |
| | | response.setContentLengthLong(localTempFile.length()); |
| | | InputStream is = new FileInputStream(localTempFile); |
| | | int len; |
| | |
| | | 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(); |
| | | } |
| | | InputStream is = null; |
| | | boolean delete = false; |
| | | File file = null; |
| | | long fileLength = 0L; |
| | | Object fileContent = attachmentFse.getValue("file_content"); |
| | | // 是否存储到数据库 |
| | | boolean saveInDb = fileContent != null; |
| | | if (saveInDb) { |
| | | is = (InputStream) fileContent; |
| | | fileLength = attachmentFse.getLong("attachment_size"); |
| | | } |
| | | if (fileContent == null || needOnlineViewFlag) { |
| | | // 直接在本地的目录中找文件 |
| | | logger.info("直接在本地的目录中找文件..."); |
| | | String localBasePath = Global.getSystemConfig("local.dir", ""); |
| | | path = localBasePath + File.separator + path; |
| | | file = new File(path); |
| | | if (needOnlineViewFlag && file.exists() && CoreConst.CLIENT_TYPE_APP.equals(clientType)) { |
| | | //特殊处理: 是App 但预览的文件是Excel 需要将之前已转换为的文件删除掉重新转换(因转换后的格式不是pdf) |
| | | String changeTime = "2025-02-11 23:59:59"; |
| | | Date changeDate = DateUtil.parse(changeTime, "yyyy-MM-dd HH:mm:ss"); |
| | | long fileTime = file.lastModified(); |
| | | //如果时间是 2025年2月10日23:59:59,那么就重新转换 |
| | | //删除文件 |
| | | if (fileTime <= changeDate.getTime()) { |
| | | file.delete(); |
| | | } |
| | | } |
| | | if (needOnlineViewFlag && !file.exists()) { |
| | | // 若是预览,但是转换后的文件不存在,那么重新执行转换操作 |
| | | // 若是存储到数据库的,那么先查看本地是否存在,若是不存在,那么存一份到本地 |
| | | if (saveInDb) { |
| | | File localFile = new File(Global.getSystemConfig("local.dir", "") + File.separator + attachmentFse.getString(CmnConst.ATTACHMENT_URL) + File.separator + fileName); |
| | | if (!localFile.exists()) { |
| | | Files.copy(is, localFile.toPath(), StandardCopyOption.REPLACE_EXISTING); |
| | | } |
| | | } |
| | | 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(); |
| | | } |
| | | if (realFileName.endsWith(".xls") && needOnlineViewFlag && file.exists() && !CoreConst.CLIENT_TYPE_APP.equals(clientType)) { |
| | | //转换为xlsx |
| | | AsposeUtil.xls2xlsx(file.getPath(), getSystemConfig("temp.dir", "/attachment/temp") + "/" + file.getName(), "xls"); |
| | | File oldFile = file; |
| | | file = new File(getSystemConfig("temp.dir", "/attachment/temp") + "/" + file.getName()); |
| | | if (!file.isFile()) { |
| | | file = oldFile; |
| | | } else { |
| | | delete = true; |
| | | } |
| | | } |
| | | is = Files.newInputStream(file.toPath()); |
| | | fileLength = file.length(); |
| | | } |
| | | |
| | | int len; |
| | | byte[] b = new byte[1024]; |
| | | InputStream is = new FileInputStream(file); |
| | | response.setHeader("Access-Control-Expose-Headers", "*"); |
| | | if (realFileName.endsWith(".xlsx") || realFileName.endsWith(".xls")) { |
| | | response.setContentType("application/vnd.ms-excel"); |
| | | } else { |
| | | response.setContentType("multipart/form-data"); |
| | | } |
| | | |
| | | response.setContentType("application/octet-stream"); |
| | | response.setContentType(contentType); |
| | | response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(realFileName, "UTF-8")); |
| | | response.setContentLengthLong(file.length()); |
| | | try (ServletOutputStream os = response.getOutputStream()) { |
| | | while ((len = is.read(b)) > 0) { |
| | | response.setContentLengthLong(fileLength); |
| | | try (ServletOutputStream os = response.getOutputStream()) { |
| | | while ((len = is.read(b)) != -1) { |
| | | if (encrptSignFlag) { |
| | | // 需要解密 |
| | | logger.info("需要解密..."); |
| | |
| | | os.flush(); |
| | | } |
| | | is.close(); |
| | | if (delete && file != null) { |
| | | file.delete(); |
| | | } |
| | | } |
| | | logger.info("文件流获取成功"); |
| | | } |