diff --git a/pom.xml b/pom.xml index 1f49eac..2e467f6 100644 --- a/pom.xml +++ b/pom.xml @@ -88,7 +88,7 @@ tk.mybatis mapper-spring-boot-starter - 1.2.0 + 1.2.4 org.mybatis.generator @@ -240,6 +240,17 @@ poi-ooxml 4.1.0 + + + com.aliyun.oss + aliyun-sdk-oss + 2.8.3 + + + org.springframework.boot + spring-boot-configuration-processor + true + diff --git a/src/main/java/com/bsd/cases/conf/OssProperties.java b/src/main/java/com/bsd/cases/conf/OssProperties.java new file mode 100644 index 0000000..3463b3b --- /dev/null +++ b/src/main/java/com/bsd/cases/conf/OssProperties.java @@ -0,0 +1,53 @@ +package com.bsd.cases.conf; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties(prefix = "oss") +public class OssProperties { + //仓库名称 +// @Value("${oss.bucket}") + public String bucket; + //地域节点 +// @Value("${oss.endpoint}") + public String endpoint; + //AccessKey ID 阿里云AccessKey +// @Value("${oss.accessId}") + public String accessId ; + //Access Key Secret 阿里云Secret +// @Value("${oss.accessKey}") + public String accessKey; + + public String getBucket() { + return bucket; + } + + public void setBucket(String bucket) { + this.bucket = bucket; + } + + public String getEndpoint() { + return endpoint; + } + + public void setEndpoint(String endpoint) { + this.endpoint = endpoint; + } + + public String getAccessId() { + return accessId; + } + + public void setAccessId(String accessId) { + this.accessId = accessId; + } + + public String getAccessKey() { + return accessKey; + } + + public void setAccessKey(String accessKey) { + this.accessKey = accessKey; + } +} diff --git a/src/main/java/com/bsd/cases/conf/WebMvcConfig.java b/src/main/java/com/bsd/cases/conf/WebMvcConfig.java index 44b5b92..919e559 100644 --- a/src/main/java/com/bsd/cases/conf/WebMvcConfig.java +++ b/src/main/java/com/bsd/cases/conf/WebMvcConfig.java @@ -24,16 +24,25 @@ package com.bsd.cases.conf; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.servlet.MultipartConfigFactory; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import javax.servlet.MultipartConfigElement; + /** * @author * @since 2015-12-19 16:16 */ @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { + @Value("${oss.maxFileSize}") + private String maxFileSize; + @Value("${oss.maxRequestSize}") + private String maxRequestSize; @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { @@ -43,4 +52,19 @@ public class WebMvcConfig extends WebMvcConfigurerAdapter { registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } + + /** + * 文件上传配置 + * + * @return + */ + @Bean + public MultipartConfigElement multipartConfigElement() { + MultipartConfigFactory factory = new MultipartConfigFactory(); + // 单个数据大小 + factory.setMaxFileSize(maxFileSize); + /// 总上传数据大小 + factory.setMaxRequestSize(maxRequestSize); + return factory.createMultipartConfig(); + } } diff --git a/src/main/java/com/bsd/cases/controller/CaseCategoryController.java b/src/main/java/com/bsd/cases/controller/CaseCategoryController.java index 04bfc9e..ea82204 100644 --- a/src/main/java/com/bsd/cases/controller/CaseCategoryController.java +++ b/src/main/java/com/bsd/cases/controller/CaseCategoryController.java @@ -2,16 +2,23 @@ package com.bsd.cases.controller; import com.alibaba.fastjson.JSONObject; import com.bsd.cases.service.CaseCategoryService; +import com.bsd.cases.service.OssService; import com.bsd.cases.util.AjaxRequest; import com.bsd.cases.util.AjaxResult; +import com.bsd.cases.util.LogUtils; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; @CrossOrigin @RestController @@ -20,6 +27,11 @@ public class CaseCategoryController { @Resource private CaseCategoryService caseCategoryService; + @Value("${oss.filedir}") + private String filedir; + private Logger logger = LogUtils.getBussinessLogger(); + @Resource + private OssService ossService; @RequestMapping("/get-all-category") public AjaxResult getAllCategory(HttpServletRequest request) { @@ -170,4 +182,5 @@ public class CaseCategoryController { } return ajaxResult; } + } diff --git a/src/main/java/com/bsd/cases/controller/CaseContentAttachmentController.java b/src/main/java/com/bsd/cases/controller/CaseContentAttachmentController.java index bba0ad7..91a6716 100644 --- a/src/main/java/com/bsd/cases/controller/CaseContentAttachmentController.java +++ b/src/main/java/com/bsd/cases/controller/CaseContentAttachmentController.java @@ -2,15 +2,22 @@ package com.bsd.cases.controller; import com.alibaba.fastjson.JSONObject; import com.bsd.cases.service.CaseContentAttachmentService; +import com.bsd.cases.service.OssService; import com.bsd.cases.util.AjaxRequest; import com.bsd.cases.util.AjaxResult; +import com.bsd.cases.util.LogUtils; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; @CrossOrigin @RestController @@ -19,6 +26,11 @@ public class CaseContentAttachmentController { @Resource private CaseContentAttachmentService caseContentAttachmentService; + @Value("${oss.filedir}") + private String filedir; + private Logger logger = LogUtils.getBussinessLogger(); + @Resource + private OssService ossService; @RequestMapping("/get-attachment-by-content-id") public AjaxResult getCaseContentAttachment(@RequestBody AjaxRequest ajaxRequest, HttpServletRequest request) { @@ -39,4 +51,32 @@ public class CaseContentAttachmentController { } return ajaxResult; } + + /** + * @CK + * files就是文件流,filedir是oss路径 + * @return + */ + @RequestMapping(value = "/upload-attachment", produces = "text/html;charset=UTF-8") + public String uploadAttachment(MultipartFile file) { + Map value = new HashMap<>(); + try { + if(file!=null){ + //保存文件 + JSONObject jsonObject = ossService.uploadAttachmentFile(file,filedir); + String url = jsonObject.getString("attachmentUrl"); + logger.debug("图片路径{}",url); + value.put("code", 2000); + value.put("msg", "附件上传成功"); + value.put("data",jsonObject); + } + } catch (Exception e) { + e.printStackTrace(); + value.put("code", 2001); + value.put("msg", "附件上传失败"); + } + return JSONObject.toJSONString(value); + + } + } diff --git a/src/main/java/com/bsd/cases/controller/CaseContentController.java b/src/main/java/com/bsd/cases/controller/CaseContentController.java index 2a8d7d3..f35283c 100644 --- a/src/main/java/com/bsd/cases/controller/CaseContentController.java +++ b/src/main/java/com/bsd/cases/controller/CaseContentController.java @@ -3,16 +3,22 @@ package com.bsd.cases.controller; import com.alibaba.fastjson.JSONObject; import com.bsd.cases.service.CaseContentLikeService; import com.bsd.cases.service.CaseContentService; +import com.bsd.cases.service.OssService; import com.bsd.cases.util.AjaxRequest; import com.bsd.cases.util.AjaxResult; +import com.bsd.cases.util.LogUtils; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; @CrossOrigin @RestController @@ -24,6 +30,11 @@ public class CaseContentController { @Resource private CaseContentLikeService caseContentLikeService; + @Value("${oss.filedir}") + private String filedir; + private Logger logger = LogUtils.getBussinessLogger(); + @Resource + private OssService ossService; @RequestMapping("/get-content-list-by-category-id") public AjaxResult getContentListByCategoryId(@RequestBody AjaxRequest ajaxRequest, HttpServletRequest request) { @@ -53,7 +64,7 @@ public class CaseContentController { } @RequestMapping("/get-content-detail-by-category-id") - public AjaxResult getContentDetailByContentId(@RequestBody AjaxRequest ajaxRequest, HttpServletRequest request) throws UnsupportedEncodingException { + public AjaxResult getContentDetailByContentId(@RequestBody AjaxRequest ajaxRequest, HttpServletRequest request) { AjaxResult ajaxResult = new AjaxResult(); JSONObject data = ajaxRequest.getData(); if (null == data){ @@ -196,4 +207,29 @@ public class CaseContentController { } return ajaxResult; } + + /** + * @CK + * files就是文件流,filedir是oss路径 + * @return + */ + @RequestMapping(value = "/upload-file", produces = "text/html;charset=UTF-8") + public String uploadFile(MultipartFile file) { + Map value = new HashMap<>(); + try { + if(file!=null){ + //保存文件 + String url = ossService.uploadFile(file,filedir); + logger.debug("图片路径{}",url); + value.put("code", 2000); + value.put("msg", "图片上传成功"); + value.put("url",url); + } + } catch (Exception e) { + e.printStackTrace(); + value.put("code", 2001); + value.put("msg", "图片上传失败"); + } + return JSONObject.toJSONString(value); + } } diff --git a/src/main/java/com/bsd/cases/service/OssService.java b/src/main/java/com/bsd/cases/service/OssService.java new file mode 100644 index 0000000..84c1e14 --- /dev/null +++ b/src/main/java/com/bsd/cases/service/OssService.java @@ -0,0 +1,71 @@ +package com.bsd.cases.service; + +import com.alibaba.fastjson.JSONObject; +import com.bsd.cases.conf.OssProperties; +import com.bsd.cases.constants.Constants; +import com.bsd.cases.mapper.CaseCategoryMapper; +import com.bsd.cases.mapper.CaseContentAttachmentMapper; +import com.bsd.cases.model.CaseCategory; +import com.bsd.cases.model.CaseContentAttachment; +import com.bsd.cases.util.FileSizeUtils; +import com.bsd.cases.util.OSSClientUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.util.Date; + +@Service +@Transactional +public class OssService { + @Autowired + OssProperties ossProperties; + @Resource + private CaseCategoryMapper caseCategoryMapper; + + public JSONObject uploadAttachmentFile(MultipartFile file, String filedir) throws Exception { + if (file == null || file.getSize() <= 0) { + throw new Exception("file不能为空"); + } + //文件名称 + String realFileName = file.getOriginalFilename(); + //文件前缀 + String fileName = realFileName.substring(0,realFileName.indexOf(".")); + //文件后缀 + String suffix = realFileName.substring(realFileName.lastIndexOf(".") + 1); + //文件大小 + Long len = file.getSize(); + String size = FileSizeUtils.getPrintSize(len); + + OSSClientUtil ossClient=new OSSClientUtil(ossProperties); + String name = ossClient.uploadImg2Oss(file,filedir); + String imgUrl = ossClient.getImgUrl(name,filedir); + String[] split = imgUrl.split("\\?"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("type",suffix); + jsonObject.put("size",size); + jsonObject.put("attachmentName",fileName); + jsonObject.put("attachmentUrl",split[0]); + return jsonObject; + } + + public String uploadFile(MultipartFile file, String filedir) throws Exception { + if (file == null || file.getSize() <= 0) { + throw new Exception("file不能为空"); + } + + OSSClientUtil ossClient=new OSSClientUtil(ossProperties); + String name = ossClient.uploadImg2Oss(file,filedir); + String imgUrl = ossClient.getImgUrl(name,filedir); + String[] split = imgUrl.split("\\?"); + + return split[0]; + } + +// public JSONObject uploadContentMaterial(MultipartFile file, String filedir) throws Exception { +// +// } + +} diff --git a/src/main/java/com/bsd/cases/service/impl/CaseContentServiceImpl.java b/src/main/java/com/bsd/cases/service/impl/CaseContentServiceImpl.java index 079ad0c..d29005a 100644 --- a/src/main/java/com/bsd/cases/service/impl/CaseContentServiceImpl.java +++ b/src/main/java/com/bsd/cases/service/impl/CaseContentServiceImpl.java @@ -213,6 +213,7 @@ public class CaseContentServiceImpl extends BaseServiceImpl caseContentAttachmentList = caseContentAttachmentMapper.select(findCaseContentAttachment); caseContentDetailBakVo.setCaseContentAttachmentList(caseContentAttachmentList); + //level + CaseCategory findCaseCategory3 = caseCategoryMapper.selectByPrimaryKey(caseContent.getCategoryId()); + CaseCategory findCaseCategory2 = caseCategoryMapper.selectByPrimaryKey(findCaseCategory3.getParentId()); + caseContentDetailBakVo.setLevelId2(findCaseCategory2.getId()); + CaseCategory findCaseCategory1 = caseCategoryMapper.selectByPrimaryKey(findCaseCategory2.getParentId()); + caseContentDetailBakVo.setLevelId1(findCaseCategory1.getId()); + return caseContentDetailBakVo; } } diff --git a/src/main/java/com/bsd/cases/util/FileSizeUtils.java b/src/main/java/com/bsd/cases/util/FileSizeUtils.java new file mode 100644 index 0000000..9764d10 --- /dev/null +++ b/src/main/java/com/bsd/cases/util/FileSizeUtils.java @@ -0,0 +1,39 @@ +package com.bsd.cases.util; + +public class FileSizeUtils { + /** + * 字节 转换为B MB GB + * @param size 字节大小 + * @return + */ + public static String getPrintSize(Long size){ + long rest = 0; + if(size < 1024){ + return String.valueOf(size) + "B"; + }else{ + size /= 1024; + } + + if(size < 1024){ + return String.valueOf(size) + "KB"; + }else{ + rest = size % 1024; + size /= 1024; + } + + if(size < 1024){ + size = size * 100; + return String.valueOf((size / 100)) + "." + String.valueOf((rest * 100 / 1024 % 100)) + "MB"; + }else{ + size = size * 100 / 1024; + return String.valueOf((size / 100)) + "." + String.valueOf((size % 100)) + "GB"; + } + } + public static void main(String[] args){ + System.out.println(getPrintSize(120005171L)); + System.out.println(getPrintSize(15522272L)); + System.out.println(getPrintSize(123456L)); + System.out.println(getPrintSize(12012L)); + System.out.println(getPrintSize(1021L)); + } +} diff --git a/src/main/java/com/bsd/cases/util/OSSClientUtil.java b/src/main/java/com/bsd/cases/util/OSSClientUtil.java new file mode 100644 index 0000000..2e25afe --- /dev/null +++ b/src/main/java/com/bsd/cases/util/OSSClientUtil.java @@ -0,0 +1,198 @@ +package com.bsd.cases.util; + +import com.aliyun.oss.OSSClient; +import com.aliyun.oss.model.ObjectMetadata; +import com.aliyun.oss.model.PutObjectResult; +import com.bsd.cases.conf.OssProperties; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; + +import java.io.*; +import java.net.URL; +import java.util.Date; + +@Component +public class OSSClientUtil { + private static final Logger logger = LoggerFactory.getLogger(OSSClientUtil.class); + //仓库名称 + public String bucket; + //地域节点 + public String endpoint; + //AccessKey ID 阿里云AccessKey + public String accessId ; + //Access Key Secret 阿里云Secret + public String accessKey; + + private OSSClient ossClient; + + private OssProperties ossProperties; + + public OSSClientUtil(OssProperties ossProperties) { + this.ossProperties = ossProperties; + bucket = ossProperties.bucket; + endpoint = ossProperties.endpoint; + accessKey = ossProperties.accessKey; + accessId = ossProperties.accessId; + ossClient = new OSSClient(endpoint, accessId, accessKey); + } + + /** + * 初始化 + */ +// @PostConstruct + public void init() { + ossClient = new OSSClient(endpoint, accessId, accessKey); + } + + /** + * 销毁 + */ + public void destory() { + ossClient.shutdown(); + } + + /** + * 上传图片 + * + * @param url + * @throws Exception + */ + public void uploadImg2Oss(String url,String filedir) throws Exception { + File fileOnServer = new File(url); + FileInputStream fin; + try { + fin = new FileInputStream(fileOnServer); + String[] split = url.split("/"); + this.uploadFile2OSS(fin, split[split.length - 1],filedir); + } catch (FileNotFoundException e) { + throw new Exception("图片上传失败"); + } + } + + public String uploadImg2Oss(MultipartFile file, String filedir) throws Exception { + if (file.getSize() > 10 * 1024 * 1024) { + throw new Exception("上传图片大小不能超过10M!"); + } + String originalFilename = file.getOriginalFilename(); +// String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase(); +// Random random = new Random(); + String name = originalFilename; + try { + InputStream inputStream = file.getInputStream(); + this.uploadFile2OSS(inputStream, name,filedir); + return name; + } catch (Exception e) { + throw new Exception("图片上传失败"); + } + } + + /** + * 获得图片路径 + * + * @param fileUrl + * @return + */ + public String getImgUrl(String fileUrl,String filedir) { + System.out.println(fileUrl); + if (!StringUtils.isEmpty(fileUrl)) { + String[] split = fileUrl.split("/"); + return this.getUrl(filedir + split[split.length - 1]); + } + return null; + } + + /** + * 上传到OSS服务器 如果同名文件会覆盖服务器上的 + * + * @param instream 文件流 + * @param fileName 文件名称 包括后缀名 + * @return 出错返回"" ,唯一MD5数字签名 + */ + public String uploadFile2OSS(InputStream instream, String fileName,String filedir) { + String ret = ""; + try { + // 创建上传Object的Metadata + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentLength(instream.available()); + objectMetadata.setCacheControl("no-cache"); + objectMetadata.setHeader("Pragma", "no-cache"); + objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf(".")))); + objectMetadata.setContentDisposition("inline;filename=" + fileName); + // 上传文件 + PutObjectResult putResult = ossClient.putObject(bucket, filedir + fileName, instream, objectMetadata); + ret = putResult.getETag(); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } finally { + try { + if (instream != null) { + instream.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return ret; + } + + /** + * Description: 判断OSS服务文件上传时文件的contentType + * + * @param filenameExtension 文件后缀 + * @return String + */ + public static String getcontentType(String filenameExtension) { + if (filenameExtension.equalsIgnoreCase("bmp")) { + return "image/bmp"; + } + if (filenameExtension.equalsIgnoreCase("gif")) { + return "image/gif"; + } + if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg") + || filenameExtension.equalsIgnoreCase("png")) { + return "image/jpeg"; + } + if (filenameExtension.equalsIgnoreCase("html")) { + return "text/html"; + } + if (filenameExtension.equalsIgnoreCase("txt")) { + return "text/plain"; + } + if (filenameExtension.equalsIgnoreCase("vsd")) { + return "application/vnd.visio"; + } + if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) { + return "application/vnd.ms-powerpoint"; + } + if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) { + return "application/msword"; + } + if (filenameExtension.equalsIgnoreCase("xml")) { + return "text/xml"; + } + return "image/jpeg"; + } + + /** + * 获得url链接 + * + * @param key + * @return + */ + public String getUrl(String key) { + // 设置URL过期时间为10年 3600l* 1000*24*365*10 + + Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10); + // 生成URL + URL url = ossClient.generatePresignedUrl(bucket, key, expiration); + if (url != null) { + return url.toString(); + } + return null; + } + +} + diff --git a/src/main/java/com/bsd/cases/vo/CaseContentDetailBakVo.java b/src/main/java/com/bsd/cases/vo/CaseContentDetailBakVo.java index 37311c5..820e522 100644 --- a/src/main/java/com/bsd/cases/vo/CaseContentDetailBakVo.java +++ b/src/main/java/com/bsd/cases/vo/CaseContentDetailBakVo.java @@ -15,4 +15,8 @@ public class CaseContentDetailBakVo extends CaseContent { private List caseContentMaterialList; private List caseContentAttachmentList; + + private Long levelId1; + + private Long levelId2; } diff --git a/src/main/resources/application-production.yml b/src/main/resources/application-production.yml index 4b06236..b869e2a 100644 --- a/src/main/resources/application-production.yml +++ b/src/main/resources/application-production.yml @@ -59,3 +59,11 @@ wx: SIGNUP_TEMPLATE_ID: wqbPcPHkoThymDu51V1ib2FxI6kC5VFOES0mXJy4nDc CANCEL_TEMPLATE_ID: MZGrdIYaXSIgJtZqf1Li_oh3IbqiAFqXWR-iUOhcg1c CHANGE_TEMPLATE_ID: PVuWhUHeKuX-DeqtXDOaccJJht89JKartyqhsh_sHTk +oss: + bucket: dj-databackup + endpoint: oss-cn-zhangjiakou.aliyuncs.com + accessId: LTAIhZASeqbsyQXm + accessKey: 8xROCAL9xwJdyItKGW2saI7yCg1G25 + maxFileSize: 10240KB + maxRequestSize: 102400KB + filedir: cktest/ \ No newline at end of file