package com.caimei.www.service.page.impl; import com.alibaba.fastjson.JSONObject; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.OSSObject; import com.caimei.www.mapper.DocumentAuthDao; import com.caimei.www.pojo.JsonModel; import com.caimei.www.pojo.document.CookieBuilder; import com.caimei.www.pojo.document.OssArchive; import com.caimei.www.pojo.document.OssArchivePdf; import com.caimei.www.pojo.document.OssAuthorization; import com.caimei.www.service.page.DocumentAuthService; import com.caimei.www.service.redis.RedisService; import com.caimei.www.utils.ImageUtil; import com.caimei.www.utils.RandomCodeGenerator; import com.caimei.www.utils.VerifyCodeUtils; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.*; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.stereotype.Service; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; import org.springframework.web.client.RestTemplate; import reactor.core.publisher.Mono; import javax.annotation.Resource; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Description * * @author : plf * @date : 2020/11/10 */ @Slf4j @Service public class DocumentAuthServiceImpl implements DocumentAuthService { @Resource private DocumentAuthDao documentAuthDao; @Resource private RedisService redisService; @Value("${caimei.wwwDomain}") private String domain; @Value("${aliyun.accessKeyId}") private String accessKeyId; @Value("${aliyun.accessKeySecret}") private String accessKeySecret; @Value("${aliyun.bucketName}") private String bucketName; @Value("${aliyun.endpoint}") private String endpoint; @Value("${spring.profiles.active}") private String active; @Value("${caimei.coreServer}") private String coreServer; @Override public Boolean getAuthorizationCookie(String authorizationMobile) { if (!StringUtils.isEmpty(authorizationMobile)) { OssAuthorization ossAuthorization = documentAuthDao.findOssAuthorizationByMobile(authorizationMobile); return ossAuthorization != null; } return false; } @Override public Mono getImgVerifyCode() { Map jsonResult = new HashMap<>(2); try { VerifyCodeUtils.VerifyCode verifyCode = null; String verifyCodeKey = ""; while (true) { verifyCode = VerifyCodeUtils.createVerifyCode(200, 80, 4); verifyCodeKey = "www:oss:" + verifyCode.getMd5Code(); boolean exists = redisService.exists(verifyCodeKey); // 不存在,为了防止重复的图片验证码 if (!exists) { // 保存5分钟 redisService.set(verifyCodeKey, verifyCode.getCode(), 5 * 60L); break; } } jsonResult.put("baseImage", verifyCode.getBase64Image()); jsonResult.put("token", verifyCode.getMd5Code()); return Mono.just(JsonModel.success(jsonResult)); } catch (Exception e) { return Mono.just(JsonModel.error("验证码获取失败")); } } @Override public Mono ossNote(String mobile, String imgCode, String token) { String code = (String) redisService.get("www:oss:" + token); String mobileCode = RandomCodeGenerator.generateCodeInt(6); //手机验证码,30分钟有效 redisService.set(mobile + ":mobileCode", mobileCode, 30 * 60L); String content = "采美资料库访问授权验证码:" + mobileCode + ",30分钟内有效"; if (!StringUtils.isEmpty(code) && code.equalsIgnoreCase(imgCode)) { log.info("采美资料库访问授权验证码>>>>>" + mobileCode); //boolean sms = SMSUtils.sendSms(mobile, content); RestTemplate restTemplate = new RestTemplate(); String uri = coreServer + "/tools/sms/send"; // 发起Post请求 MultiValueMap paramMap = new LinkedMultiValueMap<>(); paramMap.add("mobile", mobile); paramMap.add("content", content); String result = restTemplate.postForObject(uri, paramMap, String.class); log.info(result); JSONObject json = (JSONObject) JSONObject.parse(result); if (null != json && json.getInteger("code") == 0) { return Mono.just(JsonModel.success()); } } else { boolean exists = redisService.exists(mobile + ":mobileCode"); if (exists) { redisService.remove(mobile + ":mobileCode"); } } return Mono.just(JsonModel.error("验证码不正确")); } @Override public ResponseEntity mobileCodeLogin(OssAuthorization authorization) { HttpHeaders headers = new HttpHeaders(); if (StringUtils.isEmpty(authorization.getMobile()) || StringUtils.isEmpty(authorization.getCode())) { return new ResponseEntity<>(JsonModel.error("参数异常"), headers, HttpStatus.OK); } String mobileCode = (String) redisService.get(authorization.getMobile() + ":mobileCode"); if (!StringUtils.isEmpty(mobileCode) && authorization.getCode().equals(mobileCode)) { OssAuthorization ossAuthorization = documentAuthDao.findOssAuthorizationByMobile(authorization.getMobile()); if (ossAuthorization != null) { String cookie = new CookieBuilder().setKey("authorizationMobile") .setValue(authorization.getMobile()) .setMaxAge(60 * 60 * 24 * 30 * 1000L) .setPath("/") .build(); headers.add("Set-Cookie", cookie); return new ResponseEntity<>(JsonModel.success(), headers, HttpStatus.OK); } else { return new ResponseEntity<>(JsonModel.error(-2, "登录失败,您可能没有查看资料的权限"), headers, HttpStatus.OK); } } else { return new ResponseEntity<>(JsonModel.error("短信验证码不正确"), headers, HttpStatus.OK); } } @Override public Mono dataList(String name, Integer pageNum, Integer pageSize) { pageNum = pageNum == null ? 1 : pageNum; pageSize = pageSize == null ? 20 : pageSize; PageHelper.startPage(pageNum, pageSize); List ossArchiveList = documentAuthDao.findOssArchive(name); PageInfo pageInfo = null; if (ossArchiveList != null && ossArchiveList.size() > 0) { for (OssArchive ossArchive : ossArchiveList) { if (!StringUtils.isEmpty(ossArchive.getMainImage())) { ossArchive.setMainImage(ImageUtil.getImageURL("product", ossArchive.getMainImage(), 0, domain)); } List pdfList = documentAuthDao.findOssArchivePdf(ossArchive.getId()); if (pdfList != null && pdfList.size() > 0) { pdfList.forEach(this::setOssArchivePdfUrl); ossArchive.setIsShowDowns(false); } else { ossArchive.setIsShowDowns(true); } ossArchive.setPdfList(pdfList); } pageInfo = new PageInfo<>(ossArchiveList); } return Mono.just(JsonModel.success(pageInfo)); } @Override public Mono dataDetails(Integer pdfId) { Map map = new HashMap<>(2); OssArchivePdf ossArchivePdf = documentAuthDao.findOssArchivePdfById(pdfId); setOssArchivePdfUrl(ossArchivePdf); OssArchive ossArchive = documentAuthDao.getOssArchive(ossArchivePdf.getArchiveId()); if (!StringUtils.isEmpty(ossArchive.getMainImage())) { ossArchive.setMainImage(ImageUtil.getImageURL("product", ossArchive.getMainImage(), 0, domain)); } map.put("ossArchivePdf", ossArchivePdf); map.put("ossArchive", ossArchive); return Mono.just(JsonModel.success(map)); } /** * 设置预览链接 * * @param ossArchivePdf pdf文件 */ private void setOssArchivePdfUrl(OssArchivePdf ossArchivePdf) { OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); String ossName = ossArchivePdf.getOssName(); // 设置URL过期时间为1个小时 Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = null; try { date = format.parse("2021-06-01 00:00:00"); if (ossArchivePdf.getUploadTime() != null && ossArchivePdf.getUploadTime().compareTo(date) > 0) { //之后的文件都放在对应文件夹里 ossName = active + "/" + ossName; } } catch (ParseException e) { log.info("格式化时间错误", e); } String url = ossClient.generatePresignedUrl(bucketName, ossName, expiration).toString(); ossArchivePdf.setUrl(url); ossClient.shutdown(); } @Override public Mono moreData(Integer archiveId) { OssArchive ossArchive = documentAuthDao.getOssArchive(archiveId); if (ossArchive != null) { if (!StringUtils.isEmpty(ossArchive.getMainImage())) { ossArchive.setMainImage(ImageUtil.getImageURL("product", ossArchive.getMainImage(), 0, domain)); } List pdfList = documentAuthDao.findOssArchivePdf(ossArchive.getId()); if (pdfList != null && pdfList.size() > 0) { pdfList.forEach(this::setOssArchivePdfUrl); } ossArchive.setPdfList(pdfList); } return Mono.just(JsonModel.success(ossArchive)); } @Override public Mono downFile(Integer pdfId, ServerHttpRequest request, ServerHttpResponse response) { try { OssArchivePdf ossArchivePdf = documentAuthDao.findOssArchivePdfById(pdfId); // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); File file = new File("src/main/resources/static/file"); if (!file.exists()) { file.mkdir(); } // 下载OSS文件到本地文件。如果指定的本地文件存在会覆盖,不存在则新建。 ossClient.getObject(new GetObjectRequest(bucketName, ossArchivePdf.getOssName()), new File("src/main/resources/static/file/" + ossArchivePdf.getName())); // 关闭OSSClient。 ossClient.shutdown(); File pdfFile = new File("src/main/resources/static/file/" + ossArchivePdf.getName()); //输出文件名乱码问题处理 response.getHeaders().set(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + new String(pdfFile.getName().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); ZeroCopyHttpOutputMessage zeroCopyResponse = (ZeroCopyHttpOutputMessage) response; response.getHeaders().setContentType(MediaType.APPLICATION_PDF); return zeroCopyResponse.writeWith(pdfFile, 0, pdfFile.length()); } catch (Exception e) { e.printStackTrace(); return Mono.error(e); } } @Override public void deleteFile() { File file = new File("src/main/resources/static/file"); //取得这个目录下的所有子文件对象 File[] files = file.listFiles(); //遍历该目录下的文件对象 if (files != null && files.length > 0) { for (File f : files) { //打印文件名 String name = file.getName(); log.info("定时删除服务器临时文件,文件名>>>>>" + name); //判断子目录是否存在子目录,如果是文件则删除 f.delete(); } } //删除空文件夹 file.delete(); } @Override public Mono downFileAll(Integer pdfId) { Map map = new HashMap<>(2); StringBuilder date = new StringBuilder(); try { OssArchivePdf ossArchivePdf = documentAuthDao.findOssArchivePdfById(pdfId); map.put("name", ossArchivePdf.getName()); // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); // ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。 OSSObject ossObject = ossClient.getObject(bucketName, ossArchivePdf.getOssName()); // 读取文件内容。 BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); while (true) { String line = reader.readLine(); if (line == null) { break; } date.append(line); } // 数据读取完成后,获取的流必须关闭,否则会造成连接泄漏,导致请求无连接可用,程序无法正常工作。 reader.close(); // 关闭OSSClient。 ossClient.shutdown(); } catch (IOException e) { e.printStackTrace(); } map.put("date", date); return Mono.just(JsonModel.success(JsonModel.success(map))); } }