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("密钥生成异常");
|
}
|
}
|
}
|