| package com.zt.modules.oss.service; | 
|   | 
| import cn.hutool.core.collection.CollectionUtil; | 
| import cn.hutool.core.io.IoUtil; | 
| import cn.hutool.core.util.NumberUtil; | 
| import cn.hutool.core.util.ReflectUtil; | 
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 
| import com.zt.common.constant.Constant; | 
| import com.zt.common.db.query.QueryFilter; | 
| import com.zt.common.entity.BaseEntity; | 
| import com.zt.common.exception.ErrorCode; | 
| import com.zt.common.exception.RenException; | 
| import com.zt.common.service.BaseService; | 
| import com.zt.core.oss.dto.OssDto; | 
| import com.zt.core.oss.service.ISysOssService; | 
| import com.zt.modules.oss.annotation.DataFieldParser; | 
| import com.zt.modules.oss.cloud.AbstractStorageService; | 
| import com.zt.modules.oss.constant.OssConstant; | 
| import com.zt.modules.oss.dao.SysOssDao; | 
| import com.zt.modules.oss.enums.CloudChannel; | 
| import com.zt.modules.oss.enums.OssStatus; | 
| import com.zt.modules.oss.mapstruct.OssMapper; | 
| import com.zt.modules.oss.model.OssFieldDefine; | 
| import com.zt.modules.oss.model.SysOss; | 
| import org.apache.commons.io.FileUtils; | 
| import org.apache.commons.io.FilenameUtils; | 
| import org.springframework.beans.factory.annotation.Autowired; | 
| import org.springframework.stereotype.Service; | 
| import org.springframework.web.bind.annotation.RequestBody; | 
| import org.springframework.web.multipart.MultipartFile; | 
| import sun.misc.BASE64Decoder; | 
|   | 
| import javax.annotation.PostConstruct; | 
| import javax.crypto.Cipher; | 
| import javax.crypto.KeyGenerator; | 
| import java.io.*; | 
| import java.security.Key; | 
| import java.security.SecureRandom; | 
| import java.util.*; | 
| import java.util.stream.Collectors; | 
|   | 
| /** | 
|  * 文件上传 | 
|  * | 
|  * @author hehz | 
|  */ | 
| @Service | 
| public class SysOssService extends BaseService<SysOssDao, SysOss> implements ISysOssService { | 
|   | 
|     @Autowired | 
|     private AbstractStorageService storageService; | 
|     @Autowired | 
|     private DataFieldParser dataFieldParser; | 
|     @Autowired | 
|     private OssMapper ossMapper; | 
|   | 
|     private Map<String, OssFieldDefine> map = new HashMap<>(); | 
|     private static final String CIPHER_ALGORITHM = "AES"; | 
|     private static final String key = "zhpt-key#%W"; | 
|   | 
|     @PostConstruct | 
|     private void init() { | 
|         try { | 
|             dataFieldParser.getOssFields().stream().forEach(d -> map.put(d.getClassName(), d)); | 
|         } catch (Exception e) { | 
|         } | 
|     } | 
|   | 
|     public List<SysOss> page(QueryFilter queryFilter) { | 
|         List<SysOss> list = baseDao.getList(queryFilter.getParams()); | 
|         list.stream().forEach(oss -> oss.setUrl(getOssUrl(oss))); | 
|         return queryFilter.getPageList(list); | 
|     } | 
|   | 
|     public SysOss getById(Long id) { | 
|         SysOss oss = baseDao.selectById(id); | 
|         oss.setUrl(getOssUrl(oss)); | 
|         return oss; | 
|     } | 
|   | 
|     /** | 
|      * 通过业务id BusiId和业务类型 busiType获取附件数据 | 
|      * | 
|      * @return | 
|      */ | 
|     public List<SysOss> getSysOssByBusiIdAnd(Long busiId, String busiType) { | 
|         return baseDao.selectList(new QueryWrapper<SysOss>().eq(Constant.TableColumn.IS_DELETE, Constant.Bool.NO).lambda() | 
|                 .eq(SysOss::getBusiId, busiId).eq(SysOss::getBusiType, busiType)); | 
|     } | 
|   | 
|     /** | 
|      * 上传 | 
|      * | 
|      * @param file | 
|      * @return | 
|      * @throws IOException | 
|      */ | 
|     public SysOss uploadExt(MultipartFile file, Long busiId, String busiType) throws IOException { | 
|         if (file.isEmpty()) { | 
|             throw new RenException(ErrorCode.UPLOAD_FILE_EMPTY); | 
|         } | 
|   | 
|         // 上传文件 | 
|         String extension = FilenameUtils.getExtension(file.getOriginalFilename()); | 
|         SysOss oss = storageService.uploadSuffix(file.getBytes(), extension); | 
|         oss.setName(file.getOriginalFilename()); | 
|         oss.setType(extension); | 
|         String url = oss.getUrl(); | 
|         String idPart = OssConstant.ID + "=" + oss.getId(); | 
|         oss.setUrl(url + (url.indexOf("?") > 0 ? "&" : "?") + idPart); | 
|         oss.setSize(NumberUtil.round(file.getSize() / 1024, 2).doubleValue()); | 
|         oss.setChannel(storageService.getConfig().getType());// 渠道 | 
|         oss.setStatus(OssStatus.TEMPORARY.getValue()); | 
|         oss.setBusiType(busiType); | 
|         //oss.setFileType(); | 
|         oss.setBusiId(busiId); | 
|         this.insert(oss); | 
|         return oss; | 
|     } | 
|   | 
|     /** | 
|      * 上传 | 
|      * | 
|      * @param | 
|      * @return | 
|      * @throws IOException | 
|      */ | 
|     public OssDto uploadNew(@RequestBody Map<String, Object> fileData) throws IOException { | 
|         if (fileData.get("uid") == null) { | 
|             throw new RenException(ErrorCode.UPLOAD_FILE_EMPTY); | 
|         } | 
|         String name = (String) fileData.get("name"); | 
|         String uid = (String) fileData.get("uid"); | 
|         // 上传文件 | 
|         String extension = FilenameUtils.getExtension(name); | 
|         String tempUploadDir = storageService.getConfig().getLocalPath() + File.separator + "TEMP_UPLOAD"; | 
|         String filePath = tempUploadDir + File.separator + "file_" + uid; | 
|   | 
|         File file = new File(filePath); | 
|         SysOss oss = storageService.uploadSuffix(FileUtils.openInputStream(file), extension); | 
|         oss.setName(name); | 
|         oss.setType(extension); | 
|         String url = oss.getUrl(); | 
|         String idPart = OssConstant.ID + "=" + oss.getId(); | 
|         oss.setUrl(url + (url.indexOf("?") > 0 ? "&" : "?") + idPart); | 
|         oss.setSize(NumberUtil.round(file.length() / 1024, 2).doubleValue()); | 
|         oss.setChannel(storageService.getConfig().getType());// 渠道 | 
|         oss.setStatus(OssStatus.TEMPORARY.getValue()); | 
|   | 
|         this.insert(oss); | 
|         return ossMapper.toDto(oss); | 
|     } | 
|   | 
|     public OssDto upload(MultipartFile file) throws IOException { | 
|         if (file.isEmpty()) { | 
|             throw new RenException(ErrorCode.UPLOAD_FILE_EMPTY); | 
|         } | 
|   | 
|         // 上传文件 | 
|         String extension = FilenameUtils.getExtension(file.getOriginalFilename()); | 
|         SysOss oss = storageService.uploadSuffix(file.getBytes(), extension); | 
|         oss.setName(file.getOriginalFilename()); | 
|         oss.setType(extension); | 
|         String url = oss.getUrl(); | 
|         String idPart = OssConstant.ID + "=" + oss.getId(); | 
|         oss.setUrl(url + (url.indexOf("?") > 0 ? "&" : "?") + idPart); | 
|         oss.setSize(NumberUtil.round(file.getSize() / 1024, 2).doubleValue()); | 
|         oss.setChannel(storageService.getConfig().getType());// 渠道 | 
|         oss.setStatus(OssStatus.TEMPORARY.getValue()); | 
|   | 
|         this.insert(oss); | 
|         return ossMapper.toDto(oss); | 
|     } | 
|   | 
|     public void upload2(MultipartFile file, Long busiId, String busiType, String busiTypeName, String busiField, String busiFieldName) throws IOException { | 
|         if (file.isEmpty()) { | 
|             throw new RenException(ErrorCode.UPLOAD_FILE_EMPTY); | 
|         } | 
|   | 
|         // 上传文件 | 
|         String extension = FilenameUtils.getExtension(file.getOriginalFilename()); | 
|         SysOss oss = storageService.uploadSuffix(file.getBytes(), extension); | 
|         oss.setName(file.getOriginalFilename()); | 
|         oss.setType(extension); | 
|         String url = oss.getUrl(); | 
|         String idPart = OssConstant.ID + "=" + oss.getId(); | 
|         oss.setUrl(url + (url.indexOf("?") > 0 ? "&" : "?") + idPart); | 
|         oss.setBusiId(busiId); | 
|         oss.setBusiType(busiType); | 
|         oss.setBusiTypeName(busiTypeName); | 
|         oss.setBusiField(busiField); | 
|         oss.setBusiFieldName(busiFieldName); | 
|         oss.setSize(NumberUtil.round(file.getSize() / 1024, 2).doubleValue()); | 
|         oss.setChannel(storageService.getConfig().getType());// 渠道 | 
|         oss.setStatus(OssStatus.TEMPORARY.getValue()); | 
|   | 
|         this.insert(oss); | 
|     } | 
|   | 
|     /** | 
|      * 删除临时文件 | 
|      * | 
|      * @param id | 
|      */ | 
|     public void deleteTemporary(Long id) { | 
|         SysOss oss = getById(id); | 
|         if (!OssStatus.TEMPORARY.getValue().equals(oss.getStatus())) { | 
|             throw new RenException("正式文件不能删除!"); | 
|         } | 
|   | 
|         storageService.delete(oss); | 
|   | 
|         baseDao.deleteById(id); | 
|     } | 
|   | 
|     public void setListOsses(List<? extends BaseEntity> dataList, String busiType) { | 
|         List<Long> ids = dataList.stream().map(f -> f.getId()).collect(Collectors.toList()); | 
|         Map<String, Object> params = new HashMap<String, Object>(); | 
|         params.put("busiIdList", ids); | 
|         params.put("busiType", busiType); | 
|         Map<Long, Map<String, String>> accessoryMap = getOsses(params); | 
|         for (BaseEntity item : dataList) { | 
|             item.setAccessoryMap(accessoryMap.get(item.getId())); | 
|         } | 
|     } | 
|   | 
|     public Map<Long, Map<String, String>> getOsses(Map<String, Object> params) { | 
|         List<SysOss> sysOssList = this.getSysOssByBusiType(params); | 
|         Map<Long, Map<String, String>> accessoryMap = new HashMap<>(); | 
|         String downRouter = storageService.getConfig().getLocalDomain() + "/sys/oss/content?"; | 
|         if (sysOssList != null) { | 
|             for (SysOss sysOss : sysOssList) { | 
|                 String idPart = OssConstant.ID + "=" + sysOss.getId(); | 
|                 String url = downRouter + idPart; | 
|                 if (accessoryMap.containsKey(sysOss.getBusiId())) { | 
|                     accessoryMap.get(sysOss.getBusiId()).put(url, sysOss.getName()); | 
|                 } else { | 
|                     Map<String, String> map = new HashMap<>(); | 
|                     map.put(url, sysOss.getName()); | 
|                     accessoryMap.put(sysOss.getBusiId(), map); | 
|                 } | 
|             } | 
|         } | 
|         return accessoryMap; | 
|     } | 
|   | 
|     @Override | 
|     public List<OssDto> getOsses(Long busiId, String busiType, String busiField) { | 
|         List<OssDto> list = baseDao | 
|                 .selectList( | 
|                         new QueryWrapper<SysOss>().lambda().eq(SysOss::getBusiType, busiType) | 
|                                 .eq(SysOss::getBusiId, busiId).eq(SysOss::getBusiField, busiField) | 
|                                 .orderByAsc(true, SysOss::getSort)).stream().map(d -> { | 
|                     OssDto dto = ossMapper.toDto(d); | 
|                     dto.setUrl(getOssUrl(d)); | 
|                     return dto; | 
|                 }).collect(Collectors.toList()); | 
|         return list; | 
|     } | 
|   | 
|     @Override | 
|     public void setOssField(BaseEntity entity) { | 
|         if (entity == null) { | 
|             return; | 
|         } | 
|         String busiType = entity.getClass().getSimpleName(); | 
|         if (map.containsKey(busiType)) { | 
|             OssFieldDefine define = map.get(entity.getClass().getSimpleName()); | 
|             for (OssFieldDefine.Field field : define.getFields()) { | 
|                 List<OssDto> list = baseDao | 
|                         .selectList( | 
|                                 new QueryWrapper<SysOss>().lambda().eq(SysOss::getBusiType, busiType) | 
|                                         .eq(SysOss::getBusiId, entity.getId()) | 
|                                         .eq(SysOss::getBusiField, field.getField()).orderByAsc(true, SysOss::getSort)) | 
|                         .stream().map(d -> ossMapper.toDto(d)).collect(Collectors.toList()); | 
|   | 
|                 if (CollectionUtil.isNotEmpty(list)) { | 
|                     Class clazz = ReflectUtil.getField(entity.getClass(), field.getField()).getType(); | 
|                     if (clazz.getName().equals(List.class.getName())) { | 
|                         ReflectUtil.setFieldValue(entity, field.getField(), list); | 
|                     } else if (clazz.getName().equals(OssDto.class.getName())) { | 
|                         ReflectUtil.setFieldValue(entity, field.getField(), list.get(0)); | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     } | 
|   | 
|     @Override | 
|     public void updateBusiInfo(BaseEntity entity) { | 
|         if (entity == null) { | 
|             return; | 
|         } | 
|         String busiType = entity.getClass().getSimpleName(); | 
|         if (map.containsKey(busiType)) { | 
|             OssFieldDefine define = map.get(entity.getClass().getSimpleName()); | 
|             for (OssFieldDefine.Field field : define.getFields()) { | 
|                 Object value = ReflectUtil.getFieldValue(entity, field.getField()); | 
|                 List<OssDto> datas = new ArrayList<>(); | 
|                 if (value != null) { | 
|                     if (value instanceof OssDto) { | 
|                         datas.add((OssDto) value); | 
|                     } else if (value instanceof List) { | 
|                         datas.addAll((Collection<? extends OssDto>) value); | 
|                     } else if (value instanceof String) {// 富文本 | 
|                         String text = (String) value; | 
|                         int index; | 
|                         while ((index = text.indexOf(OssConstant.ID)) > 0) { | 
|                             String id = text.substring(index, index + 20); | 
|                             OssDto oss = new OssDto(); | 
|                             oss.setId(Long.parseLong(id)); | 
|                             datas.add(oss); | 
|   | 
|                             text = text.substring(index + 20); | 
|                         } | 
|                     } | 
|                 } | 
|                 List<Long> ids = datas.stream().map(d -> d.getId()).collect(Collectors.toList()); | 
|                 this.updateBusiInfo(entity.getId(), busiType, define.getBusiTypeName(), field.getField(), | 
|                         field.getFieldName(), ids, true); | 
|             } | 
|         } | 
|     } | 
|   | 
|     @Override | 
|     public void updateBusiInfo(Long busiId, String busiType, String busiTypeName, String busiField, | 
|                                String busiFieldName, List<Long> ids, Boolean deleteListNotExists) { | 
|         LambdaQueryWrapper<SysOss> queryWrapper = new LambdaQueryWrapper<SysOss>().and(Wrapper -> Wrapper | 
|                 .eq(SysOss::getBusiType, busiType).eq(SysOss::getBusiId, busiId).eq(SysOss::getBusiField, busiField)); | 
|         if (ids.size() > 0) { | 
|             queryWrapper.or(Wrapper -> Wrapper.in(SysOss::getId, ids)); | 
|         } | 
|         List<SysOss> all = baseDao.selectList(queryWrapper); | 
|         Map<Long, SysOss> map = new HashMap<>(); | 
|         for (SysOss oss : all) { | 
|             map.put(oss.getId(), oss); | 
|         } | 
|         for (int i = 0; i < ids.size(); i++) { | 
|             Long id = ids.get(i); | 
|             if (id != null && map.containsKey(id)) { | 
|                 SysOss db = map.get(id); | 
|                 if (db.getBusiId() != null && db.getBusiId() > 0) {// 原来已保存了业务id的 | 
|                     if (db.getSort() == null || db.getSort() != (i + 1)) {// 排序变了 | 
|                         db.setSort(i + 1); | 
|                         baseDao.updateById(db); | 
|                     } | 
|                 } else {// 新上传需要补充业务id的 | 
|                     db.setBusiType(busiType); | 
|                     db.setBusiTypeName(busiTypeName); | 
|                     db.setBusiId(busiId); | 
|                     db.setBusiField(busiField); | 
|                     db.setBusiFieldName(busiFieldName); | 
|                     db.setStatus(OssStatus.PERMANENT.getValue()); | 
|                     baseDao.updateById(db); | 
|                 } | 
|                 map.remove(id); | 
|             } | 
|         } | 
|         if (deleteListNotExists) { | 
|             for (SysOss oss : map.values()) {// 删除数据库和文件 | 
|                 storageService.delete(oss); | 
|                 baseDao.deleteById(oss.getId()); | 
|             } | 
|         } | 
|     } | 
|   | 
|   | 
|     @Override | 
|     public void deleteBusiInfo(String busiType, Long busiId) { | 
|         if (map.containsKey(busiType)) { | 
|             baseDao.delete(new QueryWrapper<SysOss>().lambda().eq(SysOss::getBusiType, busiType) | 
|                     .eq(SysOss::getBusiId, busiId)); | 
|         } | 
|     } | 
|   | 
|     @Override | 
|     public void deleteBusiInfo(Long busiId, String busiType, String busiField) { | 
|         baseDao.delete(new QueryWrapper<SysOss>().lambda().eq(SysOss::getBusiType, busiType) | 
|                 .eq(SysOss::getBusiId, busiId).eq(SysOss::getBusiField, busiField)); | 
|     } | 
|   | 
|     private String getOssUrl(SysOss oss) { | 
|         String url = oss.getUrl(); | 
|         String idPart = OssConstant.ID + "=" + oss.getId(); | 
|         oss.setUrl(url + (url.indexOf("?") > 0 ? "&" : "?") + idPart); | 
|         if (CloudChannel.LOCAL.getValue().equals(oss.getChannel())) {// 本地 | 
|             url = storageService.getConfig().getLocalDomain() + "/sys/oss/content"; | 
|         } | 
|         return url + (url.indexOf("?") > 0 ? "&" : "?") + idPart; | 
|     } | 
|   | 
|     public String getOssUrlCommon(SysOss oss) { | 
|         String url = oss.getUrl(); | 
|         String idPart = OssConstant.ID + "=" + oss.getId(); | 
|         oss.setUrl(url + (url.indexOf("?") > 0 ? "&" : "?") + idPart); | 
|         if (CloudChannel.LOCAL.getValue().equals(oss.getChannel())) {// 本地 | 
|             url = storageService.getConfig().getLocalDomain() + "/sys/oss/content"; | 
|         } | 
|         return url + (url.indexOf("?") > 0 ? "&" : "?") + idPart; | 
|     } | 
|   | 
|     /** | 
|      * 通过id获取指定数据 | 
|      */ | 
|     public List<SysOss> getBySysOss(List<Long> ids) { | 
|         return baseDao.selectList(new QueryWrapper<SysOss>().eq(Constant.TableColumn.IS_DELETE, Constant.Bool.NO).lambda().in(SysOss::getId, ids)); | 
|     } | 
|   | 
|     public Integer getBusiFieldNameCount(Long busiId, String busiType) { | 
|         return baseDao.getBusiFieldNameCount(busiId, busiType); | 
|     } | 
|   | 
|     public List<SysOss> getSysOssByBusiType(Map<String, Object> params) { | 
|         return baseDao.getSysOssByBusiType(params); | 
|     } | 
|   | 
|     public boolean removeBase64File() { | 
|         List<SysOss> list = baseDao.getOldFileList(); | 
|   | 
|         for (SysOss item : list) { | 
|             try { | 
|                 String localPath = storageService.getConfig().getLocalPath(); | 
|                 String oldFilePath = localPath + "/" + item.getPath(); | 
|                 File oldFile = new File(oldFilePath); | 
|                 System.out.println(oldFilePath); | 
|                 String tempFilePath2 = storageService.getConfig().getLocalPath() + "/tempJx2"; | 
|                 if (oldFile.exists()) { | 
|   | 
|                     SecureRandom sr = new SecureRandom(); | 
|                     Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM); | 
|                     Key secureKey = getKey(key); | 
|                     cipher.init(Cipher.DECRYPT_MODE, secureKey, sr); | 
|                     byte[] res = new BASE64Decoder().decodeBuffer(IoUtil.toStream(oldFile)); | 
|                     res = cipher.doFinal(res); | 
|   | 
|   | 
|                     OutputStream fos = new FileOutputStream(tempFilePath2); | 
|                     fos.write(res);//利 | 
|                     fos.close(); | 
|   | 
|                     InputStream inputStream = new FileInputStream(tempFilePath2); | 
|                     Cipher cipher2 = Cipher.getInstance(CIPHER_ALGORITHM); | 
|                     secureKey = getKey(key); | 
|                     cipher2.init(Cipher.ENCRYPT_MODE, secureKey); | 
|   | 
|                     FileOutputStream outputStream = new FileOutputStream(oldFilePath); | 
|                     byte[] buffer = new byte[8192]; | 
|                     int bytesRead; | 
|   | 
|                     try { | 
|                         while ((bytesRead = inputStream.read(buffer)) != -1) { | 
|                             byte[] encryptedBytes = cipher2.update(buffer, 0, bytesRead); | 
|                             outputStream.write(encryptedBytes); | 
|                         } | 
|                         byte[] finalEncryptedBytes = cipher2.doFinal(); | 
|                         outputStream.write(finalEncryptedBytes); | 
|                     } catch (IOException e) { | 
|                         e.printStackTrace(); | 
|                     } finally { | 
|                         // 关闭资源 | 
|                         try { | 
|                             inputStream.close(); | 
|                         } catch (IOException e) { | 
|                             e.printStackTrace(); | 
|                         } | 
|                         try { | 
|                             outputStream.close(); | 
|                         } catch (IOException e) { | 
|                             e.printStackTrace(); | 
|                         } | 
|                     } | 
|                 } | 
|             } catch (Exception e) { | 
|                 e.printStackTrace(); | 
|             } | 
|         } | 
|         return true; | 
|     } | 
|   | 
|     private Key getKey(String strKey) { | 
|         try { | 
|             if (strKey == null) { | 
|                 strKey = ""; | 
|             } | 
|             KeyGenerator _generator = KeyGenerator.getInstance(CIPHER_ALGORITHM); | 
|             SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); | 
|             secureRandom.setSeed(strKey.getBytes()); | 
|             _generator.init(128, secureRandom); | 
|             return _generator.generateKey(); | 
|         } catch (Exception e) { | 
|             throw new RuntimeException("密钥生成异常"); | 
|         } | 
|     } | 
| } |