package cn.xiaosm.cloud.core.service.impl;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.xiaosm.cloud.common.exception.CanShowException;
import cn.xiaosm.cloud.common.exception.ResourceException;
import cn.xiaosm.cloud.common.util.FileUtil;
import cn.xiaosm.cloud.core.config.EditableType;
import cn.xiaosm.cloud.core.config.security.SecurityUtils;
import cn.xiaosm.cloud.core.entity.Bucket;
import cn.xiaosm.cloud.core.entity.Resource;
import cn.xiaosm.cloud.core.entity.dto.ResourceDTO;
import cn.xiaosm.cloud.core.entity.dto.ResourceParentDTO;
import cn.xiaosm.cloud.core.entity.dto.UploadDTO;
import cn.xiaosm.cloud.core.mapper.ResourceMapper;
import cn.xiaosm.cloud.core.service.ChunkService;
import cn.xiaosm.cloud.core.service.ResourceService;
import cn.xiaosm.cloud.core.storage.FileStorageUtil;
import cn.xiaosm.cloud.core.storage.UploadConfig;
import cn.xiaosm.cloud.core.util.download.DlTaskInfo;
import cn.xiaosm.cloud.core.util.download.DownloadService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Young
* @create 2022/3/24
* @since 1.0.0
*/
@Slf4j
@Service
public class ResourceServiceImpl extends ServiceImpl<ResourceMapper, Resource> implements ResourceService {
/**
* 文件名不可用字符
*/
public final static String ILLEGAL_CHAR = "\\/:*\"<>|";
private final static Long ROOT_ID = 0L;
@Autowired
LocalBucketServiceImpl bucketService;
@Autowired
ChunkService chunkService;
@Autowired
ResourceMapper resourceMapper;
@Autowired
DownloadService downloadService;
/**
* 通过 id 获取当前登录用户的资源
*/
@Override
public Resource getByCurrentUser(Long id) {
return resourceMapper.selectByIdAndUser(id, SecurityUtils.getLoginUserId());
}
@Override
public List<Resource> getByCurrentUser(String ids) {
return resourceMapper.selectByIdsAndUser(ids, SecurityUtils.getLoginUserId());
}
@Override
public List<Resource> listByIds(String ids) {
return resourceMapper.selectByIdsAndUser(ids, null);
}
@Override
public List<Resource> list(ResourceDTO resource) {
// 查询当前仓库
Bucket bucket = bucketService.getBucket(resource.getBucketName());
// 后续的接口不需要再使用 userId 来查询,因为在上面的仓库查询中使用过 userId 筛选过了
List<Resource> resources = new ArrayList<>();
if (resource.getParentId() != null && resource.getParentId() > 0) { // 如果有父级 id,则根据父级 id 查询
QueryWrapper<Resource> wrapper = new QueryWrapper<>();
wrapper.select("id").eq("id", resource.getParentId())
.eq("user_id", SecurityUtils.getLoginUserId());
Resource db = resourceMapper.selectOne(wrapper);
// 判断当前用户是否拥有 parentId 的资源
Assert.notNull(db, "目录不存在");
resources = resourceMapper.listByParentId(resource.getParentId());
} else if (StrUtil.isBlank(resource.getPath()) || "/".equals(resource.getPath())) { // 检索根目录文件
// 获取当前仓库根目录下所有文件
resources = resourceMapper.listRoot(0, bucket.getId());
} else if (StrUtil.isNotBlank(resource.getPath())) { // 检索指定目录下的文件
Long parentId = getIdByPath(bucket.getId(), resource.getPath());
resources = resourceMapper.listByParentId(parentId);
}
// 根据类型过滤
if (StrUtil.isNotBlank(resource.getType())) {
resources = resources.stream().filter(el -> resource.getType().equals(el.getType())).collect(Collectors.toList());
}
resources.sort((el1, el2) -> {
// 如果文件同类型,则按照文件首字母排序
if (el1.isDir() == el2.isDir()) return el1.getName().compareToIgnoreCase(el2.getName());
// 文件夹在前,文件在后
return el1.isDir() ? -1 : 1;
});
return resources;
}
private Long getIdByPath(Integer bucketId, String fullPath) {
if (fullPath.length() == 0 || "/".equals(fullPath)) return ROOT_ID;
// 暂时先使用java循环来找进入文件夹叭
String[] dirs = fullPath.split("/");
Long parentId = ROOT_ID;
for (String dir : dirs) {
if ("".equals(dir)) continue;
parentId = resourceMapper.selectIdByBucketAndNameAndDir(bucketId, parentId, dir);
if (null == parentId) throw new ResourceException(dir + "-目录不存在");
}
return parentId;
}
@Override
public Long create(ResourceDTO resource) {
// 校验文件名
if (!checkName(resource.getName())) throw new ResourceException("文件名不能包含:" + ILLEGAL_CHAR);
// 查询当前仓库
Bucket bucket = bucketService.getBucket(resource.getBucketName());
// 获取父级菜单
Long parentId = getIdByPath(bucket.getId(), resource.getPath());
if (null == parentId) throw new ResourceException(resource.getPath() + "目录不存在");
// 校验名字是否重复
Resource exist = resourceMapper.selectOne(new QueryWrapper<Resource>().eq("parent_id", parentId).eq("name", resource.getName()).select("id"));
// 当文件名重复时
if (!(null == exist || null == exist.getId())) {
throw new ResourceException("文件名重复");
}
Resource db = new Resource(bucket);
db.setName(resource.getName());
db.setParentId(parentId);
// 处理文件或目录
String path = suffixPath();
String fileName = null;
if (resource.isDir()) {
db.setType("dir");
} else {
String uuid = IdUtil.simpleUUID();
// 本地文件名格式:uuid.[fileType]
String fileType = FileUtil.extName(resource.getName());
if (StrUtil.isBlank(fileType)) {
fileName = uuid;
db.setType("txt");
} else {
fileName = uuid + "." + fileType;
db.setType(fileType);
}
db.setPath(path + "/" + fileName);
db.setSize(0L);
// 因为刚开始创建的是空文件,所以不计算hash,使用 uuid
db.setHash(uuid);
}
try {
// 数据库中创建数据后创建文件
if (resourceMapper.insert(db) == 1) {
// 创建文件
if (!db.isDir()) {
FileStorageUtil.of(new byte[1]).setPath(path).setFilename(fileName).upload();
}
log.info("文件创建成功");
}
} catch (Exception e) {
e.printStackTrace();
log.error("文件创建失败");
throw new ResourceException("文件【" + resource.getName() + "】创建失败");
}
return db.getId();
}
@Override
public boolean saveContent(ResourceDTO dto) {
// 获取数据库中的数据
QueryWrapper<Resource> wrapper = ne
程序员奇奇
- 粉丝: 3w+
- 资源: 302
最新资源
- 没有样板的Python类.zip
- BP神经网络预测,MATLAB代码 多输入单输出,结果如图,数据直接用,附样本数据
- 基于ReliefF算法的分类数据特征选择算法 matlab代码,输出为选择的特征序号
- 光伏并网逆变器资料,包含原理图,pcb,源码以及元器件明细表 如下: 1) 功率接口板原理图和pcb,元器件明细表 2) 主控DSP板原理图(pdf);如果有需要,可发mentor版本的原
- 十篇年度报告模板,简略版
- 哈里斯鹰HHO优化LSSVM模型,建立多特征输入单个因变量输出的拟合预测模型 程序内注释详细直接替数据就可以用 不会替数据的可以指导免费指导如何替数据 想要的加好友我吧
- 先利用DWT对收盘价做分解,然后将分解后其中一个分量结合SVM建立股票收盘价时间序列预测模型,将数据划分为训练集,测试集,验证集三个数据集进行分析建模 整个程序已经写在了一起,直接替数据就可以做预测
- 飞蛾扑火MFO算法对BP的权值和阈值做寻优,建立多分类和二分类的分类模型 程序内注释详细直接替数据就可以用 数据要求多输入单输出 程序语言为matlab 程序运行具体效果图如下所示 想要的加
- 对原始鲸鱼优化算法进行改进的一种全局搜索策略的鲸鱼优化算法GSWOA对LSTM的超参数进行寻优,建立多特征输入,单个因变量输出的拟合预测模型 程序内注释详细,直接替数据就可以用 程序语言为matl
- 台达组态软件DIAVIEW 输入输出I O分解脚本 说明:由于组态软件的每一个点都是收费的,点数越多就越贵, 但是工程项目中,往往有些IO点不是需要那么重要,(不需要很实时刷新)比如:IO监控点位
- LSTM长短期记忆神经网络做时间序列预测模型 数据是单维输入单维输出,可自行替数据和其他参数,操作简单,标价即为实际价格,联系直接发邮箱 代码内有详细的注释,替数据即可直接使用,可以用来做交通流量,股
- Video-2024-09-26下午-刷题课1.wmv
- c++例题课本源代码所有章节
- Linux操作系统实战-习题答案
- 死区补偿三种算法打包,全部都是从实际量产项目中提取出来,可以对比优劣,可仿真也可以生成代码,内含FOC电流环
- 蜻蜓优化算法DA优化BP做多分类建模,同样可以用于二分类建模 程序内注释详细直接替数据就可以用 可学习性强 程序是matlab语言 想要的加好友我吧
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈