FileInfoServiceImpl.java 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package com.fjhx.file.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.date.DateUtil;
  4. import cn.hutool.core.io.FileUtil;
  5. import cn.hutool.core.io.IoUtil;
  6. import cn.hutool.core.util.IdUtil;
  7. import cn.hutool.core.util.ObjectUtil;
  8. import com.baomidou.dynamic.datasource.annotation.DS;
  9. import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
  10. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  11. import com.fjhx.file.entity.*;
  12. import com.fjhx.file.mapper.FileInfoMapper;
  13. import com.fjhx.file.service.FileInfoService;
  14. import com.obs.services.ObsClient;
  15. import com.obs.services.model.PostSignatureRequest;
  16. import com.obs.services.model.PostSignatureResponse;
  17. import com.ruoyi.common.constant.DatasourceConstant;
  18. import com.ruoyi.common.core.domain.BaseIdPo;
  19. import com.ruoyi.common.exception.ServiceException;
  20. import com.ruoyi.common.utils.wrapper.IWrapper;
  21. import org.springframework.beans.factory.annotation.Value;
  22. import org.springframework.stereotype.Service;
  23. import org.springframework.transaction.annotation.Propagation;
  24. import org.springframework.transaction.annotation.Transactional;
  25. import java.util.*;
  26. import java.util.stream.Collectors;
  27. /**
  28. * <p>
  29. * 文件表 服务实现类
  30. * </p>
  31. *
  32. * @author zlj
  33. * @since 2023-03-14
  34. */
  35. @Service
  36. public class FileInfoServiceImpl extends ServiceImpl<FileInfoMapper, FileInfo> implements FileInfoService {
  37. @Value("${obs.ak}")
  38. private String ak;
  39. @Value("${obs.sk}")
  40. private String sk;
  41. @Value("${obs.endPoint}")
  42. private String endPoint;
  43. @Value("${obs.url}")
  44. private String url;
  45. @Value("${obs.bucketName}")
  46. private String bucketName;
  47. @Value("${spring.profiles.active}")
  48. private String active;
  49. @Override
  50. public SingVo getSing(SingDto dto) {
  51. SingVo singVo = new SingVo();
  52. // 文件后缀名
  53. String suffix = FileUtil.getSuffix(dto.getFileName());
  54. // 文件路径
  55. String objectKey = new StringJoiner("/")
  56. .add("byteSailing")
  57. .add(active)
  58. .add(DateUtil.format(new Date(), "yyyy/MM/dd"))
  59. .add(IdUtil.fastSimpleUUID() + (ObjectUtil.isEmpty(suffix) ? "" : "." + suffix))
  60. .toString();
  61. ObsClient obsClient = null;
  62. try {
  63. // 获取oss链接客户端
  64. obsClient = getObsClient();
  65. // 指定签名有效期为10秒
  66. long currentTimeMillis = System.currentTimeMillis() + 1000 * 10;
  67. // 获取签名
  68. PostSignatureRequest request = new PostSignatureRequest(currentTimeMillis, bucketName, objectKey);
  69. PostSignatureResponse temporarySignature = obsClient.createPostSignature(request);
  70. // 封装签名
  71. Map<String, String> body = new LinkedHashMap<>();
  72. body.put("policy", temporarySignature.getPolicy());
  73. body.put("AccessKeyId", ak);
  74. body.put("signature", temporarySignature.getSignature());
  75. body.put("key", objectKey);
  76. singVo.setUploadBody(body);
  77. } catch (Exception e) {
  78. throw new ServiceException("获取签名失败");
  79. } finally {
  80. IoUtil.close(obsClient);
  81. }
  82. // 保存文件
  83. FileInfo fileInfo = new FileInfo();
  84. fileInfo.setFileUrl(objectKey);
  85. fileInfo.setFileName(dto.getFileName());
  86. save(fileInfo);
  87. // 封装文件信息
  88. singVo.setUploadUrl("https://" + bucketName + "." + endPoint);
  89. singVo.setId(fileInfo.getId());
  90. singVo.setFileName(dto.getFileName());
  91. singVo.setFileUrl(url + objectKey);
  92. return singVo;
  93. }
  94. @Override
  95. public Map<String, List<FileInfoVo>> getList(FileInfoSelectDto dto) {
  96. if (ObjectUtil.isEmpty(dto.getBusinessIdList())) {
  97. return new HashMap<>();
  98. }
  99. IWrapper<Object> wrapper = IWrapper.getWrapper();
  100. wrapper.in("fi", FileInfo::getBusinessId, dto.getBusinessIdList());
  101. wrapper.eq("fi", FileInfo::getBusinessType, dto.getFileType());
  102. List<FileInfoVo> list = this.baseMapper.getList(wrapper);
  103. if (list.size() == 0) {
  104. return new HashMap<>();
  105. }
  106. for (FileInfoVo fileInfoVo : list) {
  107. fileInfoVo.setFileUrl(url + fileInfoVo.getFileUrl());
  108. }
  109. return list.stream().collect(Collectors.groupingBy(FileInfoVo::getId));
  110. }
  111. /**
  112. * !!!必须加上Transactional 更改事务传播行为,否则数据源将被缓存,造成数据源切换失败
  113. *
  114. * @param obsFileList 文件列表
  115. * @param businessId 业务id
  116. * @param businessType 业务文件类型
  117. */
  118. @Transactional(propagation = Propagation.REQUIRES_NEW)
  119. @DS(DatasourceConstant.BASE)
  120. @Override
  121. public void saveFile(List<ObsFile> obsFileList, Long businessId, Integer businessType) {
  122. // 切换到从库
  123. if (obsFileList == null || obsFileList.size() == 0) {
  124. return;
  125. }
  126. List<FileInfo> fileInfoList = BeanUtil.copyToList(obsFileList, FileInfo.class);
  127. for (FileInfo fileInfo : fileInfoList) {
  128. fileInfo.setBusinessId(businessId);
  129. fileInfo.setBusinessType(businessType);
  130. }
  131. this.updateBatchById(fileInfoList);
  132. DynamicDataSourceContextHolder.clear();
  133. }
  134. /**
  135. * !!!必须加上Transactional 更改事务传播行为,否则数据源将被缓存,造成数据源切换失败
  136. *
  137. * @param obsFileList 文件列表
  138. * @param businessId 业务id
  139. * @param businessType 业务文件类型
  140. */
  141. @Transactional(propagation = Propagation.REQUIRES_NEW)
  142. @DS(DatasourceConstant.BASE)
  143. @Override
  144. public void editFile(List<ObsFile> obsFileList, Long businessId, Integer businessType) {
  145. if (obsFileList == null || obsFileList.size() == 0) {
  146. return;
  147. }
  148. // 删除不包含在此列表的业务id文件
  149. List<Long> obsFileId = obsFileList.stream().map(ObsFile::getId).collect(Collectors.toList());
  150. this.remove(q -> q.notIn(BaseIdPo::getId, obsFileId).eq(FileInfo::getBusinessId, businessId));
  151. // 更新在此列表的文件
  152. saveFile(obsFileList, businessId, businessType);
  153. }
  154. /**
  155. * !!!必须加上Transactional 更改事务传播行为,否则数据源将被缓存,造成数据源切换失败
  156. *
  157. * @param businessId 业务id
  158. * @param businessType 业务文件类型
  159. */
  160. @Transactional(propagation = Propagation.REQUIRES_NEW)
  161. @DS(DatasourceConstant.BASE)
  162. @Override
  163. public void removeFile(Long businessId, Integer businessType) {
  164. this.remove(q -> q
  165. .eq(FileInfo::getBusinessId, businessId)
  166. .eq(FileInfo::getBusinessType, businessType));
  167. }
  168. /**
  169. * !!!必须加上Transactional 更改事务传播行为,否则数据源将被缓存,造成数据源切换失败
  170. *
  171. * @param businessId 业务id
  172. */
  173. @Transactional(propagation = Propagation.REQUIRES_NEW)
  174. @DS(DatasourceConstant.BASE)
  175. @Override
  176. public void removeFile(Long businessId) {
  177. this.remove(q -> q.eq(FileInfo::getBusinessId, businessId));
  178. }
  179. /**
  180. * 获取oss链接客户端
  181. */
  182. private ObsClient getObsClient() {
  183. return new ObsClient(ak, sk, endPoint);
  184. }
  185. }