|
|
@@ -0,0 +1,331 @@
|
|
|
+package cn.xyh.oss.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.crypto.SecureUtil;
|
|
|
+import cn.xyh.common.config.VberConfig;
|
|
|
+import cn.xyh.common.core.domain.R;
|
|
|
+import cn.xyh.common.exception.ServiceException;
|
|
|
+import cn.xyh.common.helper.LoginHelper;
|
|
|
+import cn.xyh.common.utils.EncryptUtils;
|
|
|
+import cn.xyh.common.utils.StringUtils;
|
|
|
+import cn.xyh.common.utils.file.FileUtils;
|
|
|
+import cn.xyh.oss.common.constants.ExplorerConstants;
|
|
|
+import cn.xyh.oss.core.file.OFile;
|
|
|
+import cn.xyh.oss.core.file.vo.UploadFileVo;
|
|
|
+import cn.xyh.oss.domain.OssFile;
|
|
|
+import cn.xyh.oss.domain.OssFileShort;
|
|
|
+import cn.xyh.oss.mapper.OssFileMapper;
|
|
|
+import cn.xyh.oss.mapper.OssFileShortMapper;
|
|
|
+import cn.xyh.oss.service.IOssFileService;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * ossService业务层处理
|
|
|
+ *
|
|
|
+ * @author Yue
|
|
|
+ * @date 2024-01-20
|
|
|
+ */
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class OssFileServiceImpl implements IOssFileService {
|
|
|
+
|
|
|
+ private final static String KEY = "IWBNETVBERYUEVBIWBYUNNET";
|
|
|
+ private final OssFileMapper baseMapper;
|
|
|
+ private final OssFileShortMapper shortMapper;
|
|
|
+
|
|
|
+ private static String getUnionDateTimeId() {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssSSS");
|
|
|
+ return sdf.format(new Date()) + (new Random().nextInt(9000) + 10000);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public OssFile preview(String shortUrl) {
|
|
|
+ OssFileShort sFile = shortMapper.selectOne(new LambdaQueryWrapper<OssFileShort>().eq(OssFileShort::getShortUrl, shortUrl));
|
|
|
+ if (sFile == null) {
|
|
|
+ throw new ServiceException("无效的短链接");
|
|
|
+ }
|
|
|
+ String url = EncryptUtils.decryptByAes(sFile.getUrl(), KEY);
|
|
|
+ String[] info = url.split("\\|");
|
|
|
+ String uName = info[0];
|
|
|
+ String objectId = info[1];
|
|
|
+ String fName = info[2].replaceAll("/", "");
|
|
|
+ return baseMapper.selectOne(new LambdaQueryWrapper<OssFile>()
|
|
|
+ .eq(OssFile::getFName, fName)
|
|
|
+ .eq(OssFile::getUName, uName)
|
|
|
+ .eq(OssFile::getObjectId, objectId));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean download(String objectId, OutputStream out) {
|
|
|
+ String realPath = VberConfig.getFilesDepotPath() + objectId.replaceAll("(.{3})", "$1/") + "/" + objectId;
|
|
|
+ OutputStream toClient = new BufferedOutputStream(out);
|
|
|
+ try {
|
|
|
+ RandomAccessFile raf = new RandomAccessFile(realPath, "r");
|
|
|
+ byte[] bytes = new byte[1024];
|
|
|
+ int size = 0;
|
|
|
+ try {
|
|
|
+ while ((size = raf.read(bytes, 0, bytes.length)) != -1) {
|
|
|
+ toClient.write(bytes, 0, size);
|
|
|
+ toClient.flush();
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ toClient.close();
|
|
|
+ raf.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (IOException e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<UploadFileVo> upload(MultipartFile file, String path) {
|
|
|
+ Map<String, File> uploads = new HashMap<String, File>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ final int bufferSize = 1024 * 100;
|
|
|
+ InputStream stream = file.getInputStream();
|
|
|
+ String fileName = file.getOriginalFilename();
|
|
|
+ File dir = new File(VberConfig.getUploadPath());
|
|
|
+ if (!dir.exists()) {
|
|
|
+ dir.mkdirs();
|
|
|
+ }
|
|
|
+ String filePath = VberConfig.getUploadPath() + getUnionDateTimeId() + ".temp";
|
|
|
+ File f = new File(filePath);
|
|
|
+ OutputStream bos = new FileOutputStream(f);
|
|
|
+ int bytesRead = 0;
|
|
|
+ byte[] buffer = new byte[bufferSize];
|
|
|
+ while ((bytesRead = stream.read(buffer, 0, bufferSize)) != -1) {
|
|
|
+ bos.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ bos.close();
|
|
|
+ stream.close();
|
|
|
+ uploads.put(fileName, f);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ R<List<UploadFileVo>> res = upload(ExplorerConstants.FILE_GROUP_USERS, LoginHelper.getUsername(), path, uploads);
|
|
|
+ if (res.getCode() == R.FAIL) {
|
|
|
+ return R.fail(res.getMsg());
|
|
|
+ }
|
|
|
+ return R.ok(res.getData().get(0));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<List<UploadFileVo>> upload(MultipartFile[] files, String path) {
|
|
|
+ Map<String, File> uploads = new HashMap<String, File>();
|
|
|
+ final int bufferSize = 1024 * 100;
|
|
|
+
|
|
|
+ for (MultipartFile file : files) {
|
|
|
+ try {
|
|
|
+ InputStream stream = file.getInputStream();
|
|
|
+ String fileName = file.getOriginalFilename();
|
|
|
+ File dir = new File(VberConfig.getUploadPath());
|
|
|
+ if (!dir.exists()) {
|
|
|
+ dir.mkdirs();
|
|
|
+ }
|
|
|
+ String filePath = VberConfig.getUploadPath() + getUnionDateTimeId() + ".temp";
|
|
|
+ File f = new File(filePath);
|
|
|
+ OutputStream bos = new FileOutputStream(f);
|
|
|
+ int bytesRead = 0;
|
|
|
+ byte[] buffer = new byte[bufferSize];
|
|
|
+ while ((bytesRead = stream.read(buffer, 0, bufferSize)) != -1) {
|
|
|
+ bos.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ bos.close();
|
|
|
+ stream.close();
|
|
|
+ uploads.put(fileName, f);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return upload(ExplorerConstants.FILE_GROUP_USERS, LoginHelper.getUsername(), path, uploads);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private R<List<UploadFileVo>> upload(String group, String uname, String path, Map<String, File> files) {
|
|
|
+ List<String> errors = new ArrayList<String>();
|
|
|
+ List<UploadFileVo> result = new ArrayList<>();
|
|
|
+ List<OssFileShort> urls = new ArrayList<OssFileShort>();
|
|
|
+ for (String fileName : files.keySet()) {
|
|
|
+ File src = files.get(fileName);
|
|
|
+ fileName = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "_" + fileName;
|
|
|
+ String realPath = VberConfig.getUserRootPath() + uname.replaceAll("@|\\.", "/") + "/" + path + "/";
|
|
|
+ File uDir = new File(realPath.replaceAll("//", "/"));
|
|
|
+ if (!uDir.exists()) {
|
|
|
+ uDir.mkdirs();
|
|
|
+ }
|
|
|
+ OFile f = new OFile(src.getPath());
|
|
|
+ FileUtils.copyFile(src.getAbsolutePath(), realPath + fileName);
|
|
|
+ f.save(VberConfig.getFilesDepotPath());
|
|
|
+ String objectId = f.getInfo().getFileCode();
|
|
|
+
|
|
|
+ R res = createFile(group, uname, path + fileName, objectId, new File(realPath + fileName));
|
|
|
+ if (res.getCode() == R.FAIL) {
|
|
|
+ errors.add(res.getMsg());
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String url = EncryptUtils.encryptByAes(uname + "|" + objectId + "|" + path + "/" + fileName, KEY);
|
|
|
+
|
|
|
+ String short_url = SecureUtil.md5(url);
|
|
|
+ urls.add(new OssFileShort(short_url, url));
|
|
|
+ String ext = fileName.substring(fileName.lastIndexOf("."));
|
|
|
+
|
|
|
+ UploadFileVo vo = new UploadFileVo();
|
|
|
+ vo.setOriginalName(path + fileName);
|
|
|
+ vo.setName(fileName);
|
|
|
+ vo.setUrl(short_url);
|
|
|
+ vo.setSize(f.length());
|
|
|
+ vo.setType(ext);
|
|
|
+ vo.setLast(f.lastModified());
|
|
|
+
|
|
|
+
|
|
|
+ result.add(vo);
|
|
|
+ }
|
|
|
+ if (urls.size() > 0) {
|
|
|
+ shortMapper.insertBatch(urls);
|
|
|
+ }
|
|
|
+ if (errors.size() > 0) {
|
|
|
+ return R.fail("有文件上传失败:" + StringUtils.joinWith(",", errors));
|
|
|
+ }
|
|
|
+
|
|
|
+ return R.ok(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ private R createFile(String group, String uname, String path, String objectId, File file) {
|
|
|
+ OssFile oFile = OssFile.Create(path);
|
|
|
+ oFile.setObjectId(objectId);
|
|
|
+ oFile.setFGroup(group);
|
|
|
+ oFile.setUName(uname);
|
|
|
+ if (null != file && file.isFile()) {
|
|
|
+ oFile.setFSize(file.length());
|
|
|
+ oFile.setUpdateTime(new Date(file.lastModified()));
|
|
|
+ }
|
|
|
+ OssFile parent = null;
|
|
|
+ if (StringUtils.isNotEmpty(oFile.getXPath())) {
|
|
|
+ parent = baseMapper.selectOne(new LambdaQueryWrapper<OssFile>()
|
|
|
+ .eq(StringUtils.isNotEmpty(group), OssFile::getFGroup, group)
|
|
|
+ .eq(StringUtils.isNotEmpty(uname), OssFile::getUName, uname)
|
|
|
+ .and(StringUtils.isNotEmpty(oFile.getXPath()), w -> {
|
|
|
+ OssFile p = OssFile.Create(oFile.getXPath());
|
|
|
+ w.eq(OssFile::getXPath, p.getXPath())
|
|
|
+ .eq(OssFile::getFName, p.getFName());
|
|
|
+ })
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (null != parent) {
|
|
|
+ oFile.setPid(parent.getId());
|
|
|
+ oFile.setXCode(parent.getXCode() + oFile.getPid() + "/");
|
|
|
+ } else {
|
|
|
+ oFile.setPid(0L);
|
|
|
+ oFile.setXCode("/");
|
|
|
+ }
|
|
|
+ if (baseMapper.exists(new LambdaQueryWrapper<OssFile>()
|
|
|
+ .eq(OssFile::getFName, oFile.getFName())
|
|
|
+ .eq(OssFile::getFGroup, oFile.getFGroup())
|
|
|
+ .eq(OssFile::getUName, oFile.getUName())
|
|
|
+ .eq(OssFile::getXPath, oFile.getXPath())
|
|
|
+ )) {
|
|
|
+ return R.fail("[" + file.getName() + "]文件已存在");
|
|
|
+ }
|
|
|
+ return baseMapper.insert(oFile) > 0 ? R.ok() : R.fail("[" + file.getName() + "]保存数据库失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ ///**
|
|
|
+ // * 查询oss
|
|
|
+ // */
|
|
|
+ //@Override
|
|
|
+ //public OssFileVo queryById(String id) {
|
|
|
+ // return baseMapper.selectVoById(id);
|
|
|
+ //}
|
|
|
+ ///**
|
|
|
+ // * 查询oss列表
|
|
|
+ // */
|
|
|
+ //@Override
|
|
|
+ //public TableDataInfo<OssFileVo> queryPageList(OssFileBo bo, PageQuery pageQuery) {
|
|
|
+ // LambdaQueryWrapper<OssFile> lqw = buildQueryWrapper(bo);
|
|
|
+ // Page<OssFileVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
+ // return TableDataInfo.build(result);
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ ///**
|
|
|
+ // * 查询oss列表
|
|
|
+ // */
|
|
|
+ //@Override
|
|
|
+ //public List<OssFileVo> queryList(OssFileBo bo) {
|
|
|
+ // LambdaQueryWrapper<OssFile> lqw = buildQueryWrapper(bo);
|
|
|
+ // return baseMapper.selectVoList(lqw);
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ //private LambdaQueryWrapper<OssFile> buildQueryWrapper(OssFileBo bo) {
|
|
|
+ // Map<String, Object> params = bo.getParams();
|
|
|
+ // LambdaQueryWrapper<OssFile> lqw = Wrappers.lambdaQuery();
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getPid()), OssFile::getPid, bo.getPid());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getXPath()), OssFile::getXPath, bo.getXPath());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getXCode()), OssFile::getXCode, bo.getXCode());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getAlias()), OssFile::getAlias, bo.getAlias());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getObjectId()), OssFile::getObjectId, bo.getObjectId());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getIco()), OssFile::getIco, bo.getIco());
|
|
|
+ // lqw.like(StringUtils.isNotBlank(bo.getFName()), OssFile::getFName, bo.getFName());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getFType()), OssFile::getFType, bo.getFType());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getFExt()), OssFile::getFExt, bo.getFExt());
|
|
|
+ // lqw.eq(bo.getFSize() != null, OssFile::getFSize, bo.getFSize());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getFGroup()), OssFile::getFGroup, bo.getFGroup());
|
|
|
+ // lqw.eq(StringUtils.isNotBlank(bo.getFsGroup()), OssFile::getFsGroup, bo.getFsGroup());
|
|
|
+ // lqw.like(StringUtils.isNotBlank(bo.getUName()), OssFile::getUName, bo.getUName());
|
|
|
+ // return lqw;
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ ///**
|
|
|
+ // * 新增oss
|
|
|
+ // */
|
|
|
+ //@Override
|
|
|
+ //public Boolean insertByBo(OssFileBo bo) {
|
|
|
+ // OssFile add = BeanUtil.toBean(bo, OssFile.class);
|
|
|
+ // validEntityBeforeSave(add);
|
|
|
+ // boolean flag = baseMapper.insert(add) > 0;
|
|
|
+ // if (flag) {
|
|
|
+ // bo.setId(add.getId());
|
|
|
+ // }
|
|
|
+ // return flag;
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ ///**
|
|
|
+ // * 修改oss
|
|
|
+ // */
|
|
|
+ //@Override
|
|
|
+ //public Boolean updateByBo(OssFileBo bo) {
|
|
|
+ // OssFile update = BeanUtil.toBean(bo, OssFile.class);
|
|
|
+ // validEntityBeforeSave(update);
|
|
|
+ // return baseMapper.updateById(update) > 0;
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ ///**
|
|
|
+ // * 保存前的数据校验
|
|
|
+ // */
|
|
|
+ //private void validEntityBeforeSave(OssFile entity) {
|
|
|
+ // //TODO 做一些数据校验,如唯一约束
|
|
|
+ //}
|
|
|
+ //
|
|
|
+ ///**
|
|
|
+ // * 批量删除oss
|
|
|
+ // */
|
|
|
+ //@Override
|
|
|
+ //public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
|
|
|
+ // if (isValid) {
|
|
|
+ // //TODO 做一些业务上的校验,判断是否需要校验
|
|
|
+ // }
|
|
|
+ // return baseMapper.deleteBatchIds(ids) > 0;
|
|
|
+ //}
|
|
|
+}
|