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 implements ISysOssService { @Autowired private AbstractStorageService storageService; @Autowired private DataFieldParser dataFieldParser; @Autowired private OssMapper ossMapper; private Map 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 page(QueryFilter queryFilter) { List 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 getSysOssByBusiIdAnd(Long busiId, String busiType) { return baseDao.selectList(new QueryWrapper().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 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 dataList, String busiType) { List ids = dataList.stream().map(f -> f.getId()).collect(Collectors.toList()); Map params = new HashMap(); params.put("busiIdList", ids); params.put("busiType", busiType); Map> accessoryMap = getOsses(params); for (BaseEntity item : dataList) { item.setAccessoryMap(accessoryMap.get(item.getId())); } } public Map> getOsses(Map params) { List sysOssList = this.getSysOssByBusiType(params); Map> 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 map = new HashMap<>(); map.put(url, sysOss.getName()); accessoryMap.put(sysOss.getBusiId(), map); } } } return accessoryMap; } @Override public List getOsses(Long busiId, String busiType, String busiField) { List list = baseDao .selectList( new QueryWrapper().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 list = baseDao .selectList( new QueryWrapper().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 datas = new ArrayList<>(); if (value != null) { if (value instanceof OssDto) { datas.add((OssDto) value); } else if (value instanceof List) { datas.addAll((Collection) 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 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 ids, Boolean deleteListNotExists) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().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 all = baseDao.selectList(queryWrapper); Map 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().lambda().eq(SysOss::getBusiType, busiType) .eq(SysOss::getBusiId, busiId)); } } @Override public void deleteBusiInfo(Long busiId, String busiType, String busiField) { baseDao.delete(new QueryWrapper().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 getBySysOss(List ids) { return baseDao.selectList(new QueryWrapper().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 getSysOssByBusiType(Map params) { return baseDao.getSysOssByBusiType(params); } public boolean removeBase64File() { List 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("密钥生成异常"); } } }