package com.jsh.erp.service.systemConfig; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.CopyObjectResult; import com.aliyun.oss.model.PutObjectRequest; import com.aliyun.oss.model.PutObjectResult; import com.jsh.erp.constants.BusinessConstants; import com.jsh.erp.datasource.entities.SystemConfig; import com.jsh.erp.datasource.entities.SystemConfigExample; import com.jsh.erp.datasource.entities.User; import com.jsh.erp.datasource.mappers.SystemConfigMapper; import com.jsh.erp.datasource.mappers.SystemConfigMapperEx; import com.jsh.erp.exception.JshException; import com.jsh.erp.service.log.LogService; import com.jsh.erp.service.platformConfig.PlatformConfigService; import com.jsh.erp.service.user.UserService; import com.jsh.erp.utils.ExcelUtils; import com.jsh.erp.utils.FileUtils; import com.jsh.erp.utils.StringUtil; import com.jsh.erp.utils.Tools; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.FileCopyUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.imageio.stream.ImageOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.net.HttpURLConnection; import java.net.URL; import java.nio.file.*; import java.util.ArrayList; import java.util.Date; import java.util.List; @Service public class SystemConfigService { private Logger logger = LoggerFactory.getLogger(SystemConfigService.class); @Resource private SystemConfigMapper systemConfigMapper; @Resource private SystemConfigMapperEx systemConfigMapperEx; @Resource private PlatformConfigService platformConfigService; @Resource private UserService userService; @Resource private LogService logService; @Value(value="${file.uploadType}") private Long fileUploadType; @Value(value="${file.path}") private String filePath; private static String DELETED = "deleted"; public SystemConfig getSystemConfig(long id)throws Exception { SystemConfig result=null; try{ result=systemConfigMapper.selectByPrimaryKey(id); }catch(Exception e){ JshException.readFail(logger, e); } return result; } public List getSystemConfig()throws Exception { SystemConfigExample example = new SystemConfigExample(); example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED); List list=null; try{ list=systemConfigMapper.selectByExample(example); }catch(Exception e){ JshException.readFail(logger, e); } return list; } public List select(String companyName, int offset, int rows)throws Exception { List list=null; try{ list=systemConfigMapperEx.selectByConditionSystemConfig(companyName, offset, rows); }catch(Exception e){ JshException.readFail(logger, e); } return list; } public Long countSystemConfig(String companyName)throws Exception { Long result=null; try{ result=systemConfigMapperEx.countsBySystemConfig(companyName); }catch(Exception e){ JshException.readFail(logger, e); } return result; } @Transactional(value = "transactionManager", rollbackFor = Exception.class) public int insertSystemConfig(JSONObject obj, HttpServletRequest request) throws Exception{ SystemConfig systemConfig = JSONObject.parseObject(obj.toJSONString(), SystemConfig.class); int result=0; try{ result=systemConfigMapper.insertSelective(systemConfig); String logInfo = StringUtil.isNotEmpty(systemConfig.getCompanyName())?systemConfig.getCompanyName():"配置信息"; logService.insertLogWithUserId(userService.getCurrentUser().getId(), userService.getCurrentUser().getTenantId(), "系统配置", new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(logInfo).toString(), request); }catch(Exception e){ JshException.writeFail(logger, e); } return result; } @Transactional(value = "transactionManager", rollbackFor = Exception.class) public int updateSystemConfig(JSONObject obj, HttpServletRequest request) throws Exception{ SystemConfig systemConfig = JSONObject.parseObject(obj.toJSONString(), SystemConfig.class); int result=0; try{ result = systemConfigMapper.updateByPrimaryKeySelective(systemConfig); String logInfo = StringUtil.isNotEmpty(systemConfig.getCompanyName())?systemConfig.getCompanyName():"配置信息"; logService.insertLogWithUserId(userService.getCurrentUser().getId(), userService.getCurrentUser().getTenantId(), "系统配置", new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(logInfo).toString(), request); }catch(Exception e){ JshException.writeFail(logger, e); } return result; } @Transactional(value = "transactionManager", rollbackFor = Exception.class) public int deleteSystemConfig(Long id, HttpServletRequest request)throws Exception { return batchDeleteSystemConfigByIds(id.toString()); } @Transactional(value = "transactionManager", rollbackFor = Exception.class) public int batchDeleteSystemConfig(String ids, HttpServletRequest request)throws Exception { return batchDeleteSystemConfigByIds(ids); } @Transactional(value = "transactionManager", rollbackFor = Exception.class) public int batchDeleteSystemConfigByIds(String ids)throws Exception { logService.insertLog("系统配置", new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_DELETE).append(ids).toString(), ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()); User userInfo=userService.getCurrentUser(); String [] idArray=ids.split(","); int result=0; try{ result = systemConfigMapperEx.batchDeleteSystemConfigByIds(new Date(), userInfo == null ? null : userInfo.getId(), idArray); }catch(Exception e){ JshException.writeFail(logger, e); } return result; } public int checkIsNameExist(Long id, String name) throws Exception{ SystemConfigExample example = new SystemConfigExample(); example.createCriteria().andIdNotEqualTo(id).andCompanyNameEqualTo(name).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED); List list =null; try{ list=systemConfigMapper.selectByExample(example); }catch(Exception e){ JshException.readFail(logger, e); } return list==null?0:list.size(); } /** * 本地文件上传 * @param mf 文件 * @param bizPath 自定义路径 * @return */ public String uploadLocal(MultipartFile mf, String bizPath, HttpServletRequest request) throws Exception { try { if(StringUtil.isEmpty(bizPath)){ bizPath = ""; } // Validate bizPath to prevent directory traversal if (bizPath.contains("..") || bizPath.contains("/")) { throw new IllegalArgumentException("Invalid bizPath"); } String token = request.getHeader("X-Access-Token"); Long tenantId = Tools.getTenantIdByToken(token); bizPath = bizPath + File.separator + tenantId; String ctxPath = filePath; String fileName = null; File file = new File(ctxPath + File.separator + bizPath + File.separator ); if (!file.exists()) { file.mkdirs();// 创建文件根目录 } String orgName = mf.getOriginalFilename();// 获取文件名 orgName = FileUtils.getFileName(orgName); // Validate file extension to allow only specific types String[] allowedExtensions = {".gif", ".jpg", ".jpeg", ".png", ".pdf", ".txt",".doc",".docx",".xls",".xlsx", ".ppt",".pptx",".zip",".rar",".mp3",".mp4",".avi"}; boolean isValidExtension = false; for (String ext : allowedExtensions) { if (orgName.toLowerCase().endsWith(ext)) { isValidExtension = true; break; } } if (!isValidExtension) { throw new IllegalArgumentException("Invalid file type"); } if(orgName.contains(".")){ fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); }else{ fileName = orgName+ "_" + System.currentTimeMillis(); } String savePath = file.getPath() + File.separator + fileName; File savefile = new File(savePath); FileCopyUtils.copy(mf.getBytes(), savefile); // 返回路径 String dbpath = null; if(StringUtil.isNotEmpty(bizPath)){ dbpath = bizPath + File.separator + fileName; }else{ dbpath = fileName; } if (dbpath.contains("\\")) { dbpath = dbpath.replace("\\", "/"); } return dbpath; } catch (IOException e) { logger.error(e.getMessage(), e); } return ""; } /** * 阿里Oss文件上传 * @param mf 文件 * @param bizPath 自定义路径 * @return */ public String uploadAliOss(MultipartFile mf, String bizPath, HttpServletRequest request) throws Exception { if(StringUtil.isEmpty(bizPath)){ bizPath = ""; } // Validate bizPath to prevent directory traversal if (bizPath.contains("..") || bizPath.contains("/")) { throw new IllegalArgumentException("Invalid bizPath"); } String token = request.getHeader("X-Access-Token"); Long tenantId = Tools.getTenantIdByToken(token); bizPath = bizPath + "/" + tenantId; String endpoint = platformConfigService.getPlatformConfigByKey("aliOss_endpoint").getPlatformValue(); String accessKeyId = platformConfigService.getPlatformConfigByKey("aliOss_accessKeyId").getPlatformValue(); String accessKeySecret = platformConfigService.getPlatformConfigByKey("aliOss_accessKeySecret").getPlatformValue(); String bucketName = platformConfigService.getPlatformConfigByKey("aliOss_bucketName").getPlatformValue(); // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。 String fileName = ""; String orgName = mf.getOriginalFilename();// 获取文件名 orgName = FileUtils.getFileName(orgName); // Validate file extension to allow only specific types String[] allowedExtensions = {".gif", ".jpg", ".jpeg", ".png", ".pdf", ".txt",".doc",".docx",".xls",".xlsx", ".ppt",".pptx",".zip",".rar",".mp3",".mp4",".avi"}; boolean isValidExtension = false; for (String ext : allowedExtensions) { if (orgName.toLowerCase().endsWith(ext)) { isValidExtension = true; break; } } if (!isValidExtension) { throw new IllegalArgumentException("Invalid file type"); } if(orgName.contains(".")){ fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); }else{ fileName = orgName+ "_" + System.currentTimeMillis(); } String filePathStr = StringUtil.isNotEmpty(filePath)? filePath.substring(1):""; String objectName = filePathStr + "/" + bizPath + "/" + fileName; String smallObjectName = filePathStr + "-small/" + bizPath + "/" + fileName; // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。 byte [] byteArr = mf.getBytes(); // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); try { // 保存原文件 InputStream inputStream = new ByteArrayInputStream(byteArr); PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, inputStream); ossClient.putObject(putObjectRequest); // 如果是图片-保存缩略图 int index = fileName.lastIndexOf("."); String ext = fileName.substring(index + 1); if(ext.contains("gif") || ext.contains("jpg") || ext.contains("jpeg") || ext.contains("png") || ext.contains("GIF") || ext.contains("JPG") || ext.contains("JPEG") || ext.contains("PNG")) { String fileUrl = getFileUrlAliOss(bizPath + "/" + fileName); URL url = new URL(fileUrl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(5 * 1000); InputStream imgInputStream = conn.getInputStream();// 通过输入流获取图片数据 BufferedImage smallImage = getImageMini(imgInputStream, 80); ByteArrayOutputStream bs = new ByteArrayOutputStream(); ImageOutputStream imOut = ImageIO.createImageOutputStream(bs); ImageIO.write(smallImage, ext, imOut); InputStream isImg = new ByteArrayInputStream(bs.toByteArray()); PutObjectRequest putSmallObjectRequest = new PutObjectRequest(bucketName, smallObjectName, isImg); ossClient.putObject(putSmallObjectRequest); } // 返回路径 return bizPath + "/" + fileName; } catch (OSSException oe) { logger.error("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); logger.error("Error Message:" + oe.getErrorMessage()); logger.error("Error Code:" + oe.getErrorCode()); logger.error("Request ID:" + oe.getRequestId()); logger.error("Host ID:" + oe.getHostId()); } catch (ClientException ce) { logger.error("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } return ""; } public String getFileUrlLocal(String imgPath) { return filePath + File.separator + imgPath; } public String getFileUrlAliOss(String imgPath) throws Exception { String linkUrl = platformConfigService.getPlatformConfigByKey("aliOss_linkUrl").getPlatformValue(); return linkUrl + filePath + "/" + imgPath; } /** * 逻辑删除文件 * @param pathList */ public void deleteFileByPathList(List pathList) throws Exception { if(fileUploadType == 1) { //本地 for(String pathStr: pathList) { if(StringUtil.isNotEmpty(pathStr)) { String[] pathArr = pathStr.split(","); for (String path : pathArr) { // 提取文件的路径 String pathDir = getDirByPath(path); if (StringUtil.isNotEmpty(pathDir)) { // 源文件路径 Path sourcePath = Paths.get(filePath + File.separator + path); // 目标文件路径(注意这里是新文件的完整路径,包括文件名) Path targetPath = Paths.get(filePath + File.separator + DELETED + File.separator + path); try { File file = new File(filePath + File.separator + DELETED + File.separator + pathDir); if (!file.exists()) { file.mkdirs();// 创建文件根目录 } // 复制文件,如果目标文件已存在则替换它 Files.copy(sourcePath, targetPath, StandardCopyOption.REPLACE_EXISTING); // 删除源文件 Files.delete(sourcePath); logger.info("File copied successfully."); } catch (NoSuchFileException e) { logger.error("Source file not found: " + e.getMessage()); } catch (IOException e) { logger.error("An I/O error occurred: " + e.getMessage()); } catch (SecurityException e) { logger.error("No permission to copy file: " + e.getMessage()); } } } } } } else if(fileUploadType == 2) { //oss String endpoint = platformConfigService.getPlatformConfigByKey("aliOss_endpoint").getPlatformValue(); String accessKeyId = platformConfigService.getPlatformConfigByKey("aliOss_accessKeyId").getPlatformValue(); String accessKeySecret = platformConfigService.getPlatformConfigByKey("aliOss_accessKeySecret").getPlatformValue(); String bucketName = platformConfigService.getPlatformConfigByKey("aliOss_bucketName").getPlatformValue(); for(String pathStr: pathList) { if(StringUtil.isNotEmpty(pathStr)) { String[] pathArr = pathStr.split(","); for (String path : pathArr) { if(StringUtil.isNotEmpty(path)) { // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); try { String filePathStr = StringUtil.isNotEmpty(filePath) ? filePath.substring(1) : ""; String sourceObjectKey = filePathStr + "/" + path; String sourceSmallObjectKey = filePathStr + "-small/" + path; String destinationObjectKey = DELETED + "/list/" + sourceObjectKey; String destinationSmallObjectKey = DELETED + "/list/" + sourceSmallObjectKey; this.copySourceToDest(ossClient, bucketName, sourceObjectKey, destinationObjectKey); this.copySourceToDest(ossClient, bucketName, sourceSmallObjectKey, destinationSmallObjectKey); } catch (Exception e) { logger.error(e.getMessage()); } finally { // 关闭OSSClient。 if (ossClient != null) { ossClient.shutdown(); } } } } } } } } /** * * @param ossClient * @param bucketName * @param sourceObjectKey 源文件路径,包括目录和文件名 * @param destinationObjectKey 目标文件路径,包括新目录和文件名 */ public void copySourceToDest(OSS ossClient, String bucketName, String sourceObjectKey, String destinationObjectKey) { // 复制文件 CopyObjectResult copyResult = ossClient.copyObject(bucketName, sourceObjectKey, bucketName, destinationObjectKey); // 确认复制成功 if (copyResult != null && copyResult.getETag() != null) { logger.info("文件复制成功,ETag: " + copyResult.getETag()); // 删除源文件 ossClient.deleteObject(bucketName, sourceObjectKey); logger.info("源文件已删除:" + sourceObjectKey); } else { logger.info("文件复制失败"); } } public String getDirByPath(String path) { if(path.lastIndexOf("/")>-1) { return path.substring(0, path.lastIndexOf("/")); } else { return null; } } public BufferedImage getImageMini(InputStream inputStream, int w) throws Exception { BufferedImage img = ImageIO.read(inputStream); //获取图片的长和宽 int width = img.getWidth(); int height = img.getHeight(); int tempw = 0; int temph = 0; if(width>height){ tempw = w; temph = height* w/width; }else{ tempw = w*width/height; temph = w; } Image _img = img.getScaledInstance(tempw, temph, Image.SCALE_DEFAULT); BufferedImage image = new BufferedImage(tempw, temph, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = image.createGraphics(); graphics.drawImage(_img, 0, 0, null); graphics.dispose(); return image; } /** * 获取仓库开关 * @return * @throws Exception */ public boolean getDepotFlag() throws Exception { boolean depotFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getDepotFlag(); if(("1").equals(flag)) { depotFlag = true; } } return depotFlag; } /** * 获取客户开关 * @return * @throws Exception */ public boolean getCustomerFlag() throws Exception { boolean customerFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getCustomerFlag(); if(("1").equals(flag)) { customerFlag = true; } } return customerFlag; } /** * 获取负库存开关 * @return * @throws Exception */ public boolean getMinusStockFlag() throws Exception { boolean minusStockFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getMinusStockFlag(); if(("1").equals(flag)) { minusStockFlag = true; } } return minusStockFlag; } /** * 获取更新单价开关 * @return * @throws Exception */ public boolean getUpdateUnitPriceFlag() throws Exception { boolean updateUnitPriceFlag = true; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getUpdateUnitPriceFlag(); if(("0").equals(flag)) { updateUnitPriceFlag = false; } } return updateUnitPriceFlag; } /** * 获取超出关联单据开关 * @return * @throws Exception */ public boolean getOverLinkBillFlag() throws Exception { boolean overLinkBillFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getOverLinkBillFlag(); if(("1").equals(flag)) { overLinkBillFlag = true; } } return overLinkBillFlag; } /** * 获取强审核开关 * @return * @throws Exception */ public boolean getForceApprovalFlag() throws Exception { boolean forceApprovalFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getForceApprovalFlag(); if(("1").equals(flag)) { forceApprovalFlag = true; } } return forceApprovalFlag; } /** * 获取多级审核开关 * @return * @throws Exception */ public boolean getMultiLevelApprovalFlag() throws Exception { boolean multiLevelApprovalFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getMultiLevelApprovalFlag(); if(("1").equals(flag)) { multiLevelApprovalFlag = true; } } return multiLevelApprovalFlag; } /** * 获取出入库管理开关 * @return * @throws Exception */ public boolean getInOutManageFlag() throws Exception { boolean inOutManageFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getInOutManageFlag(); if(("1").equals(flag)) { inOutManageFlag = true; } } return inOutManageFlag; } /** * 获取移动平均价开关 * @return * @throws Exception */ public boolean getMoveAvgPriceFlag() throws Exception { boolean moveAvgPriceFlag = false; List list = getSystemConfig(); if(list.size()>0) { String flag = list.get(0).getMoveAvgPriceFlag(); if(("1").equals(flag)) { moveAvgPriceFlag = true; } } return moveAvgPriceFlag; } /** * Excel导出统一方法 * @param title * @param head * @param tip * @param arr * @param response * @throws Exception */ public void exportExcelByParam(String title, String head, String tip, JSONArray arr, HttpServletResponse response) throws Exception { List nameList = StringUtil.strToStringList(head); String[] names = StringUtil.listToStringArray(nameList); List objects = new ArrayList<>(); if (null != arr) { for (Object object: arr) { List list = (List) object; String[] objs = new String[names.length]; for (int i = 0; i < list.size(); i++) { if(null != list.get(i)) { objs[i] = list.get(i).toString(); } } objects.add(objs); } } File file = ExcelUtils.exportObjectsOneSheet(title, tip, names, title, objects); ExcelUtils.downloadExcel(file, file.getName(), response); } }