This commit is contained in:
ran.shang
2025-12-31 18:10:10 +08:00
parent d8cecbe135
commit e99b717e48
49 changed files with 2626 additions and 11 deletions

101
db/file-postgres.sql Normal file
View File

@@ -0,0 +1,101 @@
-- ----------------------------
-- Table structure for x_file_category
-- ----------------------------
DROP TABLE IF EXISTS x_file_category;
CREATE TABLE x_file_category (
id BIGSERIAL PRIMARY KEY,
file_category VARCHAR(32) DEFAULT NULL,
file_suffix VARCHAR(32) DEFAULT NULL,
deleted BOOLEAN DEFAULT FALSE,
create_by BIGINT DEFAULT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_by BIGINT DEFAULT NULL,
update_time TIMESTAMP DEFAULT NULL,
proxy_by BIGINT DEFAULT NULL
);
COMMENT ON TABLE x_file_category IS '文件种类';
COMMENT ON COLUMN x_file_category.id IS '主键ID';
COMMENT ON COLUMN x_file_category.file_category IS '文件种类';
COMMENT ON COLUMN x_file_category.file_suffix IS '文件后缀';
COMMENT ON COLUMN x_file_category.deleted IS '是否删除';
COMMENT ON COLUMN x_file_category.create_by IS '创建人';
COMMENT ON COLUMN x_file_category.create_time IS '创建时间';
COMMENT ON COLUMN x_file_category.update_by IS '修改人';
COMMENT ON COLUMN x_file_category.update_time IS '修改时间';
COMMENT ON COLUMN x_file_category.proxy_by IS '代理人';
-- ----------------------------
-- Table structure for x_user_space
-- ----------------------------
DROP TABLE IF EXISTS x_user_space;
CREATE TABLE x_user_space (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT DEFAULT NULL,
total_size BIGINT DEFAULT NULL,
used_size BIGINT DEFAULT NULL,
deleted BOOLEAN DEFAULT FALSE,
create_by BIGINT DEFAULT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_by BIGINT DEFAULT NULL,
update_time TIMESTAMP DEFAULT NULL,
proxy_by BIGINT DEFAULT NULL
);
COMMENT ON TABLE x_user_space IS '用户空间';
COMMENT ON COLUMN x_user_space.id IS '主键ID';
COMMENT ON COLUMN x_user_space.user_id IS '用户id';
COMMENT ON COLUMN x_user_space.total_size IS '总容量';
COMMENT ON COLUMN x_user_space.used_size IS '已使用容量';
COMMENT ON COLUMN x_user_space.deleted IS '是否删除';
COMMENT ON COLUMN x_user_space.create_by IS '创建人';
COMMENT ON COLUMN x_user_space.create_time IS '创建时间';
COMMENT ON COLUMN x_user_space.update_by IS '修改人';
COMMENT ON COLUMN x_user_space.update_time IS '修改时间';
COMMENT ON COLUMN x_user_space.proxy_by IS '代理人';
-- ----------------------------
-- Table structure for x_user_file
-- ----------------------------
DROP TABLE IF EXISTS x_user_file;
CREATE TABLE x_user_file (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT DEFAULT NULL,
root_type VARCHAR(2) DEFAULT NULL,
file_type VARCHAR(32) DEFAULT NULL,
file_name VARCHAR(256) DEFAULT NULL,
parent_id BIGINT DEFAULT NULL,
file_code VARCHAR(32) DEFAULT NULL,
file_status VARCHAR(2) DEFAULT NULL,
path VARCHAR(255) DEFAULT NULL,
end_time TIMESTAMP DEFAULT NULL,
access_code VARCHAR(6) DEFAULT NULL,
deleted BOOLEAN DEFAULT FALSE,
create_by BIGINT DEFAULT NULL,
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
update_by BIGINT DEFAULT NULL,
update_time TIMESTAMP DEFAULT NULL,
proxy_by BIGINT DEFAULT NULL
);
COMMENT ON TABLE x_user_file IS '用户文件';
COMMENT ON COLUMN x_user_file.id IS '主键ID';
COMMENT ON COLUMN x_user_file.user_id IS '用户id';
COMMENT ON COLUMN x_user_file.root_type IS '根类型:1普通/2内穿外/3外传内/4我的分享';
COMMENT ON COLUMN x_user_file.file_type IS '文件大类:1文件/2文件夹';
COMMENT ON COLUMN x_user_file.file_name IS '文件名';
COMMENT ON COLUMN x_user_file.parent_id IS '父id';
COMMENT ON COLUMN x_user_file.file_code IS '文件编码';
COMMENT ON COLUMN x_user_file.file_status IS '文件状态:1正常2失效11解析中12待审核13传输中';
COMMENT ON COLUMN x_user_file.path IS '路径';
COMMENT ON COLUMN x_user_file.end_time IS '有效期';
COMMENT ON COLUMN x_user_file.access_code IS '访问码';
COMMENT ON COLUMN x_user_file.deleted IS '是否删除';
COMMENT ON COLUMN x_user_file.create_by IS '创建人';
COMMENT ON COLUMN x_user_file.create_time IS '创建时间';
COMMENT ON COLUMN x_user_file.update_by IS '修改人';
COMMENT ON COLUMN x_user_file.update_time IS '修改时间';
COMMENT ON COLUMN x_user_file.proxy_by IS '代理人';

50
db/file.sql Normal file
View File

@@ -0,0 +1,50 @@
CREATE TABLE `x_file_category` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`file_category` varchar(32) DEFAULT NULL COMMENT '文件种类',
`file_suffix` varchar(32) DEFAULT NULL COMMENT '文件后缀',
`deleted` bit(1) DEFAULT b'0' COMMENT '是否删除',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`proxy_by` bigint(20) DEFAULT NULL COMMENT '代理人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文件种类';
CREATE TABLE `x_user_space` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
`total_size` bigint DEFAULT NULL COMMENT '总容量',
`used_size` bigint DEFAULT NULL COMMENT '已使用容量',
`deleted` bit(1) DEFAULT b'0' COMMENT '是否删除',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`proxy_by` bigint(20) DEFAULT NULL COMMENT '代理人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户空间';
CREATE TABLE `x_user_file` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
`root_type` varchar(2) DEFAULT NULL COMMENT '根类型:1普通/2内穿外/3外传内/4我的分享',
`file_type` varchar(32) DEFAULT NULL COMMENT '文件大类:1文件/2文件夹',
`file_name` varchar(256) DEFAULT NULL COMMENT '文件名',
`parent_id` bigint(20) DEFAULT NULL COMMENT '父id',
`file_code` varchar(32) DEFAULT NULL COMMENT '文件编码',
`file_status` varchar(2) DEFAULT NULL COMMENT '文件状态:1正常2失效11解析中12待审核13传输中',
`path` varchar(255) DEFAULT NULL COMMENT '路径',
`end_time` datetime DEFAULT NULL COMMENT '有效期',
`access_code` varchar(6) DEFAULT NULL COMMENT '访问码',
`deleted` bit(1) DEFAULT b'0' COMMENT '是否删除',
`create_by` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint(20) DEFAULT NULL COMMENT '修改人',
`update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`proxy_by` bigint(20) DEFAULT NULL COMMENT '代理人',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户文件';

20
db/init-data.sql Normal file
View File

@@ -0,0 +1,20 @@
-- 系统uc_platform
INSERT INTO uc_platform
(platform_code, name, full_name, short_name, business, deleted, create_time)
VALUES(1, '文档系统', 's-file', 'file', 1, 0, now());
-- 平台机构/平台机构管理员
INSERT INTO xs_org
(org_name, org_code, type, address_code, address_name, description, quality, enable, activated, parent_id, credit_code, trade, deleted, create_by, create_time, update_by, update_time, proxy_by, activation_code, phone, query_children, org_logo, registered_address, company_size, business_license, recruit_position_type)
VALUES('senmesh', 'O001', '1', '440232', NULL, NULL, 0, 1, 1, NULL, '', NULL, 0, 0, now(), 1, now(), null, NULL, null, NULL, null, '1234', '6', null, '1');
INSERT INTO uc_user
(username, password, type, supeiror, security_code, nickname, avatar, phone, phone_binding, real_name, card_no, authenticated, status, email, address, education, init_user_id, enabled, account_non_expired, account_non_locked, credentials_non_expired, deleted, create_by, create_time, update_by, update_time, proxy_by, gender, birthday)
VALUES('admin', '$2a$10$0N3iaxx2sYv0hXvYzS4.6.yriL.DfjRTjED7Y4vkqxzbxi2dNpBou', 1, 1, '$2a$10$992AErI/g5nnfGnraSh7NuoeZVOXYcPuPQ3hqi5FjjIlU0Dwfk0/a', '平台管理员', '20d78fb6abe9478cadc2e1cb5bf93a35', '13611806907', 1, '平台管理员', NULL, 0, 2, null, NULL, NULL, NULL, 1, 1, 1, 1, 0, 0, now(), 1, NULL, NULL, NULL, NULL);
INSERT INTO uc_org_user
(user_id, org_id, administrator, deleted, create_by, create_time, update_by, update_time, proxy_by)
VALUES(1, 1, 1, 0, 0, now(), NULL, NULL, NULL);
-- 平台uc_org_relation
INSERT INTO uc_org_relation
(org_id, org_type, parent_id, path, platform_code, platform_name, deleted, create_by, create_time, update_by, update_time, proxy_by)
VALUES(1, 1, 0, '1', 1, NULL, 0, NULL, NULL, NULL, NULL, NULL);

View File

@@ -0,0 +1,79 @@
package com.senmesh.sfile.constant;
/**
* 文件状态枚举
*/
public enum FileStatusEnum {
/**
* 正常
*/
NORMAL("1", "正常"),
/**
* 失效
*/
INVALID("2", "失效"),
/**
* 解析中
*/
PARSING("11", "解析中"),
/**
* 待审核
*/
PENDING_REVIEW("12", "待审核"),
/**
* 传输中
*/
TRANSFERRING("13", "传输中"),
/**
* 失败
*/
FAILED("14", "失败");
private final String status;
private final String desc;
FileStatusEnum(String status, String desc) {
this.status = status;
this.desc = desc;
}
public String getStatus() {
return status;
}
public String getDesc() {
return desc;
}
/**
* 根据状态获取枚举
*
* @param status 状态
* @return FileStatusEnum
*/
public static FileStatusEnum getByStatus(String status) {
for (FileStatusEnum fileStatusEnum : FileStatusEnum.values()) {
if (fileStatusEnum.getStatus().equals(status)) {
return fileStatusEnum;
}
}
return null;
}
/**
* 判断是否为正常状态
*
* @param status 状态
* @return true-正常,false-不正常
*/
public static boolean isNormal(String status) {
return NORMAL.getStatus().equals(status);
}
}

View File

@@ -0,0 +1,69 @@
package com.senmesh.sfile.constant;
/**
* 文件类型枚举
*/
public enum FileTypeEnum {
/**
* 文件
*/
FILE("1", "文件"),
/**
* 文件夹
*/
FOLDER("2", "文件夹");
private final String type;
private final String desc;
FileTypeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
/**
* 根据类型获取枚举
*
* @param type 类型
* @return FileTypeEnum
*/
public static FileTypeEnum getByType(String type) {
for (FileTypeEnum fileTypeEnum : FileTypeEnum.values()) {
if (fileTypeEnum.getType().equals(type)) {
return fileTypeEnum;
}
}
return null;
}
/**
* 判断是否为文件
*
* @param type 类型
* @return true-是文件,false-不是文件
*/
public static boolean isFile(String type) {
return FILE.getType().equals(type);
}
/**
* 判断是否为文件夹
*
* @param type 类型
* @return true-是文件夹,false-不是文件夹
*/
public static boolean isFolder(String type) {
return FOLDER.getType().equals(type);
}
}

View File

@@ -0,0 +1,69 @@
package com.senmesh.sfile.constant;
/**
* 根类型枚举
*/
public enum RootTypeEnum {
/**
* 普通
*/
NORMAL("1", "普通"),
/**
* 内穿外
*/
INTERNAL_TO_EXTERNAL("2", "内穿外"),
/**
* 外传内
*/
EXTERNAL_TO_INTERNAL("3", "外传内"),
/**
* 分享
*/
SHARE("4", "分享");
private final String type;
private final String desc;
RootTypeEnum(String type, String desc) {
this.type = type;
this.desc = desc;
}
public String getType() {
return type;
}
public String getDesc() {
return desc;
}
/**
* 根据类型获取枚举
*
* @param type 类型
* @return RootTypeEnum
*/
public static RootTypeEnum getByType(String type) {
for (RootTypeEnum rootTypeEnum : RootTypeEnum.values()) {
if (rootTypeEnum.getType().equals(type)) {
return rootTypeEnum;
}
}
return null;
}
/**
* 判断是否为普通类型
*
* @param type 类型
* @return true-是普通类型,false-不是普通类型
*/
public static boolean isNormal(String type) {
return NORMAL.getType().equals(type);
}
}

View File

@@ -0,0 +1,68 @@
package com.senmesh.sfile.controller;
import com.senmesh.common.AlitaResult;
import com.senmesh.sfile.dto.FileCategoryCreateDTO;
import com.senmesh.sfile.dto.FileCategoryDTO;
import com.senmesh.sfile.dto.FileCategoryModifyDTO;
import com.senmesh.sfile.dto.FileCategoryQueryDTO;
import com.senmesh.sfile.service.FileCategoryService;
import com.senmesh.tkmybatis.pojo.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 文件种类Controller
*/
@Api(tags = "文件种类")
@RestController
@RequestMapping("file_category")
public class FileCategoryController {
@Autowired
private FileCategoryService fileCategoryService;
@PostMapping("/create")
@ApiOperation("创建")
public AlitaResult<Long> create(@Validated @RequestBody FileCategoryCreateDTO createDTO) {
return AlitaResult.success(fileCategoryService.create(createDTO));
}
@PostMapping("/modify")
@ApiOperation("修改")
public AlitaResult<Boolean> modify(@Validated @RequestBody FileCategoryModifyDTO modifyDTO) {
fileCategoryService.modify(modifyDTO);
return AlitaResult.success(true);
}
@DeleteMapping("/remove/{id}")
@ApiOperation("删除")
public AlitaResult<Boolean> remove(@PathVariable Long id) {
fileCategoryService.remove(id);
return AlitaResult.success(true);
}
@GetMapping("/find")
@ApiOperation("查询")
public AlitaResult<FileCategoryDTO> find(FileCategoryQueryDTO queryDTO) {
return AlitaResult.success(fileCategoryService.find(queryDTO));
}
@GetMapping("/list")
@ApiOperation("列表查询")
public AlitaResult<List<FileCategoryDTO>> list(FileCategoryQueryDTO queryDTO) {
return AlitaResult.success(fileCategoryService.list(queryDTO));
}
@GetMapping("/page")
@ApiOperation("分页查询")
public AlitaResult<Page<FileCategoryDTO>> page(FileCategoryQueryDTO queryDTO) {
fileCategoryService.page(queryDTO);
return AlitaResult.success(queryDTO.getPageResult());
}
}

View File

@@ -0,0 +1,65 @@
package com.senmesh.sfile.controller;
import com.senmesh.common.AlitaResult;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.constant.FileStatusEnum;
import com.senmesh.sfile.constant.RootTypeEnum;
import com.senmesh.sfile.dto.UserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileDTO;
import com.senmesh.sfile.dto.UserFileModifyDTO;
import com.senmesh.sfile.dto.UserFileModifyStatusDTO;
import com.senmesh.sfile.dto.UserFileQueryDTO;
import com.senmesh.sfile.service.NormalUserFileService;
import com.senmesh.sfile.service.UserFileService;
import com.senmesh.tkmybatis.pojo.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 普通用户文件Controller
*/
@RestController
@RequestMapping("normal_user_file")
@Api(tags = "普通用户文件")
public class NormalUserFileController {
@Autowired
private NormalUserFileService normalUserFileService;
@Autowired
private UserFileService userFileService;
@PostMapping("/create")
@ApiOperation("创建")
public AlitaResult<Long> create(@Validated @RequestBody UserFileCreateDTO createDTO) {
return AlitaResult.success(normalUserFileService.create(createDTO));
}
@PutMapping("/recover/{id}")
@ApiOperation("恢复")
public AlitaResult<Boolean> recover(@PathVariable Long id) {
UserFileModifyStatusDTO modifyStatusDTO = UserFileModifyStatusDTO.builder()
.id(id)
.oldStatus(FileStatusEnum.INVALID.getStatus())
.newStatus(FileStatusEnum.NORMAL.getStatus())
.build();
userFileService.modifyStatus(modifyStatusDTO);
return AlitaResult.success(true);
}
}

View File

@@ -0,0 +1,46 @@
package com.senmesh.sfile.controller;
import com.senmesh.common.AlitaResult;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.constant.FileStatusEnum;
import com.senmesh.sfile.constant.RootTypeEnum;
import com.senmesh.sfile.dto.ShareUserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileModifyDTO;
import com.senmesh.sfile.dto.UserFileModifyStatusDTO;
import com.senmesh.sfile.service.ShareUserFileService;
import com.senmesh.sfile.service.UserFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 分享用户文件Controller
*/
@RestController
@RequestMapping("share_user_file")
@Api(tags = "分享用户文件")
public class ShareUserFileController {
@Autowired
private ShareUserFileService shareUserFileService;
@Autowired
private UserFileService userFileService;
@PostMapping("/create")
@ApiOperation("创建")
public AlitaResult<Long> create(@Validated @RequestBody ShareUserFileCreateDTO createDTO) {
return AlitaResult.success(shareUserFileService.create(createDTO));
}
}

View File

@@ -0,0 +1,88 @@
package com.senmesh.sfile.controller;
import com.senmesh.common.AlitaResult;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.constant.FileStatusEnum;
import com.senmesh.sfile.dto.UserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileDTO;
import com.senmesh.sfile.dto.UserFileModifyDTO;
import com.senmesh.sfile.dto.UserFileModifyStatusDTO;
import com.senmesh.sfile.dto.UserFileQueryDTO;
import com.senmesh.sfile.service.UserFileService;
import com.senmesh.tkmybatis.pojo.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户文件Controller
*/
@Api(tags = "用户文件")
@RestController
@RequestMapping("user_file")
public class UserFileController {
@Autowired
private UserFileService userFileService;
@PostMapping("/create")
@ApiOperation("创建")
public AlitaResult<Long> create(@Validated @RequestBody UserFileCreateDTO createDTO) {
return AlitaResult.success(userFileService.create(createDTO));
}
@PostMapping("/modify")
@ApiOperation("修改")
public AlitaResult<Boolean> modify(@Validated @RequestBody UserFileModifyDTO modifyDTO) {
modifyDTO.setUserId(UserContextHolder.getExistLoginUserId());
userFileService.modify(modifyDTO);
return AlitaResult.success(true);
}
@DeleteMapping("/remove/{id}")
@ApiOperation("删除")
public AlitaResult<Boolean> remove(@PathVariable Long id) {
Long userId = UserContextHolder.getExistLoginUserId();
userFileService.remove(id, userId);
return AlitaResult.success(true);
}
@PutMapping("/invalid/{id}")
@ApiOperation("失效")
public AlitaResult<Boolean> invalid(@PathVariable Long id) {
UserFileModifyStatusDTO modifyStatusDTO = UserFileModifyStatusDTO.builder()
.id(id)
.oldStatus(FileStatusEnum.NORMAL.getStatus())
.newStatus(FileStatusEnum.INVALID.getStatus())
.build();
userFileService.modifyStatus(modifyStatusDTO);
return AlitaResult.success(true);
}
@GetMapping("/find")
@ApiOperation("查询")
public AlitaResult<UserFileDTO> find(UserFileQueryDTO queryDTO) {
queryDTO.setUserId(UserContextHolder.getExistLoginUserId());
return AlitaResult.success(userFileService.find(queryDTO));
}
@GetMapping("/list")
@ApiOperation("列表查询")
public AlitaResult<List<UserFileDTO>> list(UserFileQueryDTO queryDTO) {
queryDTO.setUserId(UserContextHolder.getExistLoginUserId());
return AlitaResult.success(userFileService.list(queryDTO));
}
@GetMapping("/page")
@ApiOperation("分页查询")
public AlitaResult<Page<UserFileDTO>> page(UserFileQueryDTO queryDTO) {
queryDTO.setUserId(UserContextHolder.getExistLoginUserId());
userFileService.page(queryDTO);
return AlitaResult.success(queryDTO.getPageResult());
}
}

View File

@@ -0,0 +1,69 @@
package com.senmesh.sfile.controller;
import com.senmesh.common.AlitaResult;
import com.senmesh.sfile.dto.UserSpaceCreateDTO;
import com.senmesh.sfile.dto.UserSpaceDTO;
import com.senmesh.sfile.dto.UserSpaceModifyDTO;
import com.senmesh.sfile.dto.UserSpaceQueryDTO;
import com.senmesh.sfile.service.UserSpaceService;
import com.senmesh.tkmybatis.pojo.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 用户空间Controller
*/
@Api(tags = "用户空间")
@RestController
@RequestMapping("user_space")
public class UserSpaceController {
@Autowired
private UserSpaceService userSpaceService;
@PostMapping("/create")
@ApiOperation("创建")
public AlitaResult<Long> create(@Validated @RequestBody UserSpaceCreateDTO createDTO) {
return AlitaResult.success(userSpaceService.create(createDTO));
}
@PostMapping("/modify")
@ApiOperation("修改")
public AlitaResult<Boolean> modify(@Validated @RequestBody UserSpaceModifyDTO modifyDTO) {
userSpaceService.modify(modifyDTO);
return AlitaResult.success(true);
}
@DeleteMapping("/remove/{id}")
@ApiOperation("删除")
public AlitaResult<Boolean> remove(@PathVariable Long id) {
userSpaceService.remove(id);
return AlitaResult.success(true);
}
@GetMapping("/find")
@ApiOperation("查询")
public AlitaResult<UserSpaceDTO> find(UserSpaceQueryDTO queryDTO) {
return AlitaResult.success(userSpaceService.find(queryDTO));
}
@GetMapping("/list")
@ApiOperation("列表查询")
public AlitaResult<List<UserSpaceDTO>> list(UserSpaceQueryDTO queryDTO) {
return AlitaResult.success(userSpaceService.list(queryDTO));
}
@GetMapping("/page")
@ApiOperation("分页查询")
public AlitaResult<Page<UserSpaceDTO>> page(UserSpaceQueryDTO queryDTO) {
userSpaceService.page(queryDTO);
return AlitaResult.success(queryDTO.getPageResult());
}
}

View File

@@ -0,0 +1,26 @@
package com.senmesh.sfile.convert;
import com.senmesh.sfile.dto.FileCategoryCreateDTO;
import com.senmesh.sfile.dto.FileCategoryDTO;
import com.senmesh.sfile.dto.FileCategoryModifyDTO;
import com.senmesh.sfile.entity.FileCategory;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 文件种类转换器
*/
@Mapper
public interface FileCategoryConvert {
FileCategoryConvert INSTANCE = Mappers.getMapper(FileCategoryConvert.class);
FileCategory toEntity(FileCategoryDTO dto);
FileCategoryDTO toDto(FileCategory entity);
FileCategory toEntity(FileCategoryCreateDTO dto);
FileCategory toEntity(FileCategoryModifyDTO dto);
}

View File

@@ -0,0 +1,26 @@
package com.senmesh.sfile.convert;
import com.senmesh.sfile.dto.UserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileDTO;
import com.senmesh.sfile.dto.UserFileModifyDTO;
import com.senmesh.sfile.entity.UserFile;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 用户文件转换器
*/
@Mapper
public interface UserFileConvert {
UserFileConvert INSTANCE = Mappers.getMapper(UserFileConvert.class);
UserFile toEntity(UserFileDTO dto);
UserFileDTO toDto(UserFile entity);
UserFile toEntity(UserFileCreateDTO dto);
UserFile toEntity(UserFileModifyDTO dto);
}

View File

@@ -0,0 +1,26 @@
package com.senmesh.sfile.convert;
import com.senmesh.sfile.dto.UserSpaceCreateDTO;
import com.senmesh.sfile.dto.UserSpaceDTO;
import com.senmesh.sfile.dto.UserSpaceModifyDTO;
import com.senmesh.sfile.entity.UserSpace;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* 用户空间转换器
*/
@Mapper
public interface UserSpaceConvert {
UserSpaceConvert INSTANCE = Mappers.getMapper(UserSpaceConvert.class);
UserSpace toEntity(UserSpaceDTO dto);
UserSpaceDTO toDto(UserSpace entity);
UserSpace toEntity(UserSpaceCreateDTO dto);
UserSpace toEntity(UserSpaceModifyDTO dto);
}

View File

@@ -0,0 +1,26 @@
package com.senmesh.sfile.dao;
import com.senmesh.sfile.dto.FileCategoryDTO;
import com.senmesh.sfile.dto.FileCategoryQueryDTO;
import com.senmesh.sfile.entity.FileCategory;
import com.senmesh.tkmybatis.mybatis.MyMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 文件种类Mapper
*/
@Mapper
public interface FileCategoryMapper extends MyMapper<FileCategory> {
/**
* 查询列表(PageHelper会根据queryDTO自动判断是否分页)
*
* @param queryDTO 查询DTO
* @return List<FileCategoryDTO>
*/
List<FileCategoryDTO> list(@Param("param") FileCategoryQueryDTO queryDTO);
}

View File

@@ -0,0 +1,58 @@
package com.senmesh.sfile.dao;
import com.senmesh.sfile.dto.UserFileDTO;
import com.senmesh.sfile.dto.UserFileQueryDTO;
import com.senmesh.sfile.entity.UserFile;
import com.senmesh.tkmybatis.mybatis.MyMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 用户文件Mapper
*/
@Mapper
public interface UserFileMapper extends MyMapper<UserFile> {
/**
* 查询列表(PageHelper会根据queryDTO自动判断是否分页)
*
* @param queryDTO 查询DTO
* @return List<UserFileDTO>
*/
List<UserFileDTO> list(@Param("param") UserFileQueryDTO queryDTO);
/**
* 根据父节点变化更新路径(包含当前节点和所有子孙节点)
* 只更新与当前文件相同 userId 和 rootType 的子节点
*
* @param fileId 文件ID
* @param newParentId 新父节点ID
*/
void updatePathByParentIdChange(@Param("fileId") Long fileId, @Param("newParentId") Long newParentId);
/**
* 删除文件及其所有子文件(逻辑删除)
* 只删除与当前文件相同 userId 和 rootType 的子节点
*
* @param fileId 文件ID
* @param operateUserId 操作用户ID
*/
void deleteFileWithChildren(@Param("fileId") Long fileId, @Param("operateUserId") Long operateUserId);
/**
* 更新文件状态及其所有子文件状态
* 只更新与当前文件相同 userId 和 rootType 的子节点
*
* @param fileId 文件ID
* @param oldStatus 老状态
* @param newStatus 新状态
* @param operateUserId 操作用户ID
*/
void updateStatusWithChildren(@Param("fileId") Long fileId,
@Param("oldStatus") String oldStatus,
@Param("newStatus") String newStatus,
@Param("operateUserId") Long operateUserId);
}

View File

@@ -0,0 +1,26 @@
package com.senmesh.sfile.dao;
import com.senmesh.sfile.dto.UserSpaceDTO;
import com.senmesh.sfile.dto.UserSpaceQueryDTO;
import com.senmesh.sfile.entity.UserSpace;
import com.senmesh.tkmybatis.mybatis.MyMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 用户空间Mapper
*/
@Mapper
public interface UserSpaceMapper extends MyMapper<UserSpace> {
/**
* 查询列表(PageHelper会根据queryDTO自动判断是否分页)
*
* @param queryDTO 查询DTO
* @return List<UserSpaceDTO>
*/
List<UserSpaceDTO> list(@Param("param") UserSpaceQueryDTO queryDTO);
}

View File

@@ -0,0 +1,54 @@
package com.senmesh.sfile.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;
/**
* 扩展用户文件创建DTO
* 根据普通文件创建新的文件(复制)
*/
@ApiModel("扩展用户文件创建DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ExpandUserFileCreateDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户文件ID")
@NotNull(message = "用户文件ID不能为空")
private Long userFileId;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("根类型:1普通/2内穿外/3外传内/4分享")
@NotEmpty(message = "根类型不能为空")
private String rootType;
@ApiModelProperty("文件状态:1正常2失效11解析中12待审核13传输中14失败")
private String fileStatus;
@ApiModelProperty("有效期")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
@ApiModelProperty("访问码")
private String accessCode;
}

View File

@@ -0,0 +1,34 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
/**
* 文件种类创建DTO
*/
@ApiModel("文件种类创建DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class FileCategoryCreateDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("文件种类")
@NotEmpty(message = "文件种类不能为空")
private String fileCategory;
@ApiModelProperty("文件后缀")
private String fileSuffix;
}

View File

@@ -0,0 +1,31 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 文件种类
*/
@ApiModel("文件种类")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class FileCategoryDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("文件种类")
private String fileCategory;
@ApiModelProperty("文件后缀")
private String fileSuffix;
}

View File

@@ -0,0 +1,39 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 文件种类修改DTO
*/
@ApiModel("文件种类修改DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class FileCategoryModifyDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键ID")
@NotNull(message = "主键ID不能为空")
private Long id;
@ApiModelProperty("文件种类")
@NotEmpty(message = "文件种类不能为空")
private String fileCategory;
@ApiModelProperty("文件后缀")
private String fileSuffix;
}

View File

@@ -0,0 +1,35 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.PageQueryDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 文件种类查询DTO
*/
@ApiModel("文件种类查询DTO")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class FileCategoryQueryDTO extends PageQueryDTO<FileCategoryDTO> {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键ID")
private Long id;
@ApiModelProperty("文件种类")
private String fileCategory;
@ApiModelProperty("文件后缀")
private String fileSuffix;
}

View File

@@ -0,0 +1,36 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* 分享用户文件创建DTO
*/
@ApiModel("分享用户文件创建DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class ShareUserFileCreateDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户文件ID")
@NotNull(message = "用户文件ID不能为空")
private Long userFileId;
@ApiModelProperty("有效天数")
@NotNull(message = "有效天数不能为空")
private Integer validDays;
}

View File

@@ -0,0 +1,69 @@
package com.senmesh.sfile.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Builder.Default;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 用户文件创建DTO
*/
@ApiModel("用户文件创建DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserFileCreateDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户id")
@NotNull(message = "用户id不能为空")
private Long userId;
@ApiModelProperty("根类型:1普通/2内穿外/3外传内/4我的分享")
// @NotEmpty(message = "根类型不能为空")
private String rootType;
@ApiModelProperty("文件大类:1文件/2文件夹")
@NotEmpty(message = "文件大类不能为空")
private String fileType;
@ApiModelProperty("文件名")
@NotEmpty(message = "文件名不能为空")
private String fileName;
@ApiModelProperty("父id")
@Default
private Long parentId = 0L;
@ApiModelProperty("文件编码")
private String fileCode;
@ApiModelProperty("文件状态:1正常2失效11解析中12待审核13传输中14失败")
private String fileStatus;
@ApiModelProperty("父路径(可选,用于优化性能,避免查询父节点)")
private String parentPath;
@ApiModelProperty("有效期")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
@ApiModelProperty("访问码")
private String accessCode;
}

View File

@@ -0,0 +1,61 @@
package com.senmesh.sfile.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.senmesh.common.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* 用户文件
*/
@ApiModel("用户文件")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserFileDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("根类型:1普通/2内穿外/3外传内/4我的分享")
private String rootType;
@ApiModelProperty("文件大类:1文件/2文件夹")
private String fileType;
@ApiModelProperty("文件名")
private String fileName;
@ApiModelProperty("父id")
private Long parentId;
@ApiModelProperty("文件编码")
private String fileCode;
@ApiModelProperty("文件状态:1正常2失效11解析中12待审核13传输中14失败")
private String fileStatus;
@ApiModelProperty("路径")
private String path;
@ApiModelProperty("有效期")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
@ApiModelProperty("访问码")
private String accessCode;
}

View File

@@ -0,0 +1,50 @@
package com.senmesh.sfile.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Date;
/**
* 用户文件修改DTO
*/
@ApiModel("用户文件修改DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserFileModifyDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键ID")
@NotNull(message = "主键ID不能为空")
private Long id;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("根类型:1普通/2内穿外/3外传内/4我的分享")
@NotEmpty(message = "根类型不能为空")
private String rootType;
@ApiModelProperty("文件名")
private String fileName;
@ApiModelProperty("父id")
private Long parentId;
}

View File

@@ -0,0 +1,41 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 用户文件修改状态DTO
*/
@ApiModel("用户文件修改状态DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserFileModifyStatusDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键ID")
@NotNull(message = "主键ID不能为空")
private Long id;
@ApiModelProperty("老状态:1正常2失效11解析中12待审核13传输中14失败")
@NotEmpty(message = "老状态不能为空")
private String oldStatus;
@ApiModelProperty("新状态:1正常2失效11解析中12待审核13传输中14失败")
@NotEmpty(message = "新状态不能为空")
private String newStatus;
}

View File

@@ -0,0 +1,55 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.PageQueryDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 用户文件查询DTO
*/
@ApiModel("用户文件查询DTO")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserFileQueryDTO extends PageQueryDTO<UserFileDTO> {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键ID")
private Long id;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("根类型:1普通/2内穿外/3外传内/4我的分享")
private String rootType;
@ApiModelProperty("文件大类:1文件/2文件夹")
private String fileType;
@ApiModelProperty("文件名")
private String fileName;
@ApiModelProperty("文件名(模糊查询)")
private String fileNameLike;
@ApiModelProperty("父id")
private Long parentId;
@ApiModelProperty("文件编码")
private String fileCode;
@ApiModelProperty("文件状态:1正常2失效11解析中12待审核13传输中")
private String fileStatus;
@ApiModelProperty("路径(模糊查询,用于查询某个文件夹下的所有子文件)")
private String pathLike;
}

View File

@@ -0,0 +1,31 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* 用户空间创建DTO
*/
@ApiModel("用户空间创建DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserSpaceCreateDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户id")
@NotNull(message = "用户id不能为空")
private Long userId;
}

View File

@@ -0,0 +1,34 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 用户空间
*/
@ApiModel("用户空间")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserSpaceDTO extends BaseDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("总容量")
private Long totalSize;
@ApiModelProperty("已使用容量")
private Long usedSize;
}

View File

@@ -0,0 +1,35 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.BaseOperateDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
/**
* 用户空间修改DTO
*/
@ApiModel("用户空间修改DTO")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserSpaceModifyDTO extends BaseOperateDTO {
private static final long serialVersionUID = 1L;
@ApiModelProperty("用户id")
@NotNull(message = "用户id不能为空")
private Long userId;
@ApiModelProperty("已使用容量")
@NotNull(message = "已使用容量不能为空")
private Long usedSize;
}

View File

@@ -0,0 +1,31 @@
package com.senmesh.sfile.dto;
import com.senmesh.common.dto.PageQueryDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 用户空间查询DTO
*/
@ApiModel("用户空间查询DTO")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserSpaceQueryDTO extends PageQueryDTO<UserSpaceDTO> {
private static final long serialVersionUID = 1L;
@ApiModelProperty("主键ID")
private Long id;
@ApiModelProperty("用户id")
private Long userId;
}

View File

@@ -0,0 +1,34 @@
package com.senmesh.sfile.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.senmesh.common.entity.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 文件种类
*/
@TableName("x_file_category")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class FileCategory extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 文件种类
*/
private String fileCategory;
/**
* 文件后缀
*/
private String fileSuffix;
}

View File

@@ -0,0 +1,76 @@
package com.senmesh.sfile.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.senmesh.common.entity.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Date;
/**
* 用户文件
*/
@TableName("x_user_file")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserFile extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
private Long userId;
/**
* 根类型:1普通/2内穿外/3外传内/4我的分享
*/
private String rootType;
/**
* 文件大类:1文件/2文件夹
*/
private String fileType;
/**
* 文件名
*/
private String fileName;
/**
* 父id
*/
private Long parentId;
/**
* 文件编码
*/
private String fileCode;
/**
* 文件状态:1正常2失效11解析中12待审核13传输中14失败
*/
private String fileStatus;
/**
* 路径
*/
private String path;
/**
* 有效期
*/
private Date endTime;
/**
* 访问码
*/
private String accessCode;
}

View File

@@ -0,0 +1,39 @@
package com.senmesh.sfile.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.senmesh.common.entity.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* 用户空间
*/
@TableName("x_user_space")
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class UserSpace extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 用户id
*/
private Long userId;
/**
* 总容量
*/
private Long totalSize;
/**
* 已使用容量
*/
private Long usedSize;
}

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.senmesh.sfile.dao.FileCategoryMapper">
<select id="list" resultType="com.senmesh.sfile.dto.FileCategoryDTO">
SELECT t.*
<include refid="queryFromSql"></include>
ORDER BY t.id DESC
</select>
<sql id="queryFromSql">
FROM x_file_category t
WHERE t.deleted = 0
<if test='param.id != null'>
AND t.id = #{param.id}
</if>
<if test='param.fileCategory != null and param.fileCategory.trim() != ""'>
AND t.file_category = #{param.fileCategory}
</if>
<if test='param.fileSuffix != null and param.fileSuffix.trim() != ""'>
AND t.file_suffix = #{param.fileSuffix}
</if>
</sql>
</mapper>

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.senmesh.sfile.dao.UserFileMapper">
<select id="list" resultType="com.senmesh.sfile.dto.UserFileDTO">
SELECT t.*
<include refid="queryFromSql"></include>
ORDER BY t.id DESC
</select>
<sql id="queryFromSql">
FROM x_user_file t
WHERE t.deleted = 0
<if test='param.id != null'>
AND t.id = #{param.id}
</if>
<if test='param.userId != null'>
AND t.user_id = #{param.userId}
</if>
<if test='param.rootType != null and param.rootType.trim() != ""'>
AND t.root_type = #{param.rootType}
</if>
<if test='param.fileType != null and param.fileType.trim() != ""'>
AND t.file_type = #{param.fileType}
</if>
<if test='param.fileName != null and param.fileName.trim() != ""'>
AND t.file_name = #{param.fileName}
</if>
<if test='param.fileNameLike != null and param.fileNameLike.trim() != ""'>
<bind name="fileNameLike" value="'%' + param.fileNameLike + '%'"/>
AND t.file_name LIKE #{fileNameLike}
</if>
<if test='param.parentId != null'>
AND t.parent_id = #{param.parentId}
</if>
<if test='param.fileCode != null and param.fileCode.trim() != ""'>
AND t.file_code = #{param.fileCode}
</if>
<if test='param.fileStatus != null and param.fileStatus.trim() != ""'>
AND t.file_status = #{param.fileStatus}
</if>
<if test='param.pathLike != null and param.pathLike.trim() != ""'>
<bind name="pathLike" value="param.pathLike + '%'"/>
AND t.path LIKE #{pathLike}
</if>
</sql>
<update id="updatePathByParentIdChange">
UPDATE x_user_file child
INNER JOIN x_user_file current ON current.id = #{fileId} AND current.deleted = 0
LEFT JOIN x_user_file parent ON parent.id = #{newParentId} AND parent.deleted = 0
SET child.path = CASE
WHEN child.id = #{fileId} THEN
CASE
WHEN #{newParentId} = 0 THEN CAST(#{fileId} AS CHAR)
ELSE CONCAT(parent.path, ',', #{fileId})
END
ELSE
REPLACE(child.path,
CONCAT(current.path, ','),
CASE
WHEN #{newParentId} = 0 THEN CONCAT(#{fileId}, ',')
ELSE CONCAT(parent.path, ',', #{fileId}, ',')
END)
END
WHERE (child.id = #{fileId} OR child.path LIKE CONCAT(current.path, ',%'))
AND child.deleted = 0
AND child.user_id = current.user_id
AND child.root_type = current.root_type
</update>
<update id="deleteFileWithChildren">
UPDATE x_user_file child
INNER JOIN x_user_file current ON current.id = #{fileId} AND current.deleted = 0
SET child.deleted = 1,
child.update_by = #{operateUserId},
child.update_time = NOW()
WHERE (child.id = #{fileId} OR child.path LIKE CONCAT(current.path, ',%'))
AND child.deleted = 0
AND child.user_id = current.user_id
AND child.root_type = current.root_type
</update>
<update id="updateStatusWithChildren">
UPDATE x_user_file child
INNER JOIN x_user_file current ON current.id = #{fileId}
AND current.deleted = 0
AND current.file_status = #{oldStatus}
SET child.file_status = #{newStatus},
child.update_by = #{operateUserId},
child.update_time = NOW()
WHERE (child.id = #{fileId} OR child.path LIKE CONCAT(current.path, ',%'))
AND child.deleted = 0
AND child.user_id = current.user_id
AND child.root_type = current.root_type
</update>
</mapper>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.senmesh.sfile.dao.UserSpaceMapper">
<select id="list" resultType="com.senmesh.sfile.dto.UserSpaceDTO">
SELECT t.*
<include refid="queryFromSql"></include>
ORDER BY t.id DESC
</select>
<sql id="queryFromSql">
FROM x_user_space t
WHERE t.deleted = 0
<if test='param.id != null'>
AND t.id = #{param.id}
</if>
<if test='param.userId != null'>
AND t.user_id = #{param.userId}
</if>
</sql>
</mapper>

View File

@@ -0,0 +1,60 @@
package com.senmesh.sfile.service;
import com.senmesh.sfile.dto.FileCategoryCreateDTO;
import com.senmesh.sfile.dto.FileCategoryDTO;
import com.senmesh.sfile.dto.FileCategoryModifyDTO;
import com.senmesh.sfile.dto.FileCategoryQueryDTO;
import java.util.List;
/**
* 文件种类Service
*/
public interface FileCategoryService {
/**
* 创建文件种类
*
* @param createDTO 创建DTO
* @return 主键ID
*/
Long create(FileCategoryCreateDTO createDTO);
/**
* 修改文件种类
*
* @param modifyDTO 修改DTO
*/
void modify(FileCategoryModifyDTO modifyDTO);
/**
* 删除文件种类
*
* @param id 主键ID
*/
void remove(Long id);
/**
* 列表查询
*
* @param queryDTO 查询DTO
* @return List<FileCategoryDTO>
*/
List<FileCategoryDTO> list(FileCategoryQueryDTO queryDTO);
/**
* 分页查询
*
* @param queryDTO 查询DTO
*/
void page(FileCategoryQueryDTO queryDTO);
/**
* 单个查询
*
* @param queryDTO 查询DTO
* @return FileCategoryDTO
*/
FileCategoryDTO find(FileCategoryQueryDTO queryDTO);
}

View File

@@ -0,0 +1,18 @@
package com.senmesh.sfile.service;
import com.senmesh.sfile.dto.UserFileCreateDTO;
/**
* 普通用户文件Service
*/
public interface NormalUserFileService {
/**
* 创建普通用户文件
*
* @param createDTO 创建DTO
* @return 主键ID
*/
Long create(UserFileCreateDTO createDTO);
}

View File

@@ -0,0 +1,19 @@
package com.senmesh.sfile.service;
import com.senmesh.sfile.dto.ShareUserFileCreateDTO;
/**
* 分享用户文件Service
*/
public interface ShareUserFileService {
/**
* 创建分享用户文件
* 根据普通文件ID创建分享文件夹,并复制其下所有文件类型的子文件
*
* @param createDTO 创建DTO
* @return 分享文件夹ID
*/
Long create(ShareUserFileCreateDTO createDTO);
}

View File

@@ -0,0 +1,102 @@
package com.senmesh.sfile.service;
import com.senmesh.sfile.dto.ExpandUserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileDTO;
import com.senmesh.sfile.dto.UserFileModifyDTO;
import com.senmesh.sfile.dto.UserFileModifyStatusDTO;
import com.senmesh.sfile.dto.UserFileQueryDTO;
import java.util.List;
/**
* 用户文件Service
*/
public interface UserFileService {
/**
* 创建用户文件
*
* @param createDTO 创建DTO
* @return 主键ID
*/
Long create(UserFileCreateDTO createDTO);
/**
* 根据普通文件创建新的文件(复制)
* 创建一个文件夹,文件名为原文件名+时间戳,然后复制原文件下所有文件类型的子文件
*
* @param expandCreateDTO 扩展创建DTO
* @return 新创建的文件夹ID
*/
Long create(ExpandUserFileCreateDTO expandCreateDTO);
/**
* 修改用户文件
*
* @param modifyDTO 修改DTO
*/
void modify(UserFileModifyDTO modifyDTO);
/**
* 修改用户文件状态
*
* @param modifyStatusDTO 修改状态DTO
*/
void modifyStatus(UserFileModifyStatusDTO modifyStatusDTO);
/**
* 修改用户文件状态(校验用户权限)
*
* @param modifyStatusDTO 修改状态DTO
* @param userId 用户ID
*/
void modifyStatus(UserFileModifyStatusDTO modifyStatusDTO, Long userId);
/**
* 删除用户文件
*
* @param id 主键ID
*/
void remove(Long id);
/**
* 删除用户文件(校验用户权限)
*
* @param id 主键ID
* @param userId 用户ID
*/
void remove(Long id, Long userId);
/**
* 列表查询
*
* @param queryDTO 查询DTO
* @return List<UserFileDTO>
*/
List<UserFileDTO> list(UserFileQueryDTO queryDTO);
/**
* 分页查询
*
* @param queryDTO 查询DTO
*/
void page(UserFileQueryDTO queryDTO);
/**
* 单个查询
*
* @param queryDTO 查询DTO
* @return UserFileDTO
*/
UserFileDTO find(UserFileQueryDTO queryDTO);
/**
* 单个查询(不存在抛异常)
*
* @param queryDTO 查询DTO
* @return UserFileDTO
*/
UserFileDTO findOne(UserFileQueryDTO queryDTO);
}

View File

@@ -0,0 +1,60 @@
package com.senmesh.sfile.service;
import com.senmesh.sfile.dto.UserSpaceCreateDTO;
import com.senmesh.sfile.dto.UserSpaceDTO;
import com.senmesh.sfile.dto.UserSpaceModifyDTO;
import com.senmesh.sfile.dto.UserSpaceQueryDTO;
import java.util.List;
/**
* 用户空间Service
*/
public interface UserSpaceService {
/**
* 创建用户空间
*
* @param createDTO 创建DTO
* @return 主键ID
*/
Long create(UserSpaceCreateDTO createDTO);
/**
* 修改用户空间
*
* @param modifyDTO 修改DTO
*/
void modify(UserSpaceModifyDTO modifyDTO);
/**
* 删除用户空间
*
* @param id 主键ID
*/
void remove(Long id);
/**
* 列表查询
*
* @param queryDTO 查询DTO
* @return List<UserSpaceDTO>
*/
List<UserSpaceDTO> list(UserSpaceQueryDTO queryDTO);
/**
* 分页查询
*
* @param queryDTO 查询DTO
*/
void page(UserSpaceQueryDTO queryDTO);
/**
* 单个查询
*
* @param queryDTO 查询DTO
* @return UserSpaceDTO
*/
UserSpaceDTO find(UserSpaceQueryDTO queryDTO);
}

View File

@@ -0,0 +1,67 @@
package com.senmesh.sfile.service.impl;
import com.senmesh.common.util.ListUtil;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.convert.FileCategoryConvert;
import com.senmesh.sfile.dao.FileCategoryMapper;
import com.senmesh.sfile.dto.FileCategoryCreateDTO;
import com.senmesh.sfile.dto.FileCategoryDTO;
import com.senmesh.sfile.dto.FileCategoryModifyDTO;
import com.senmesh.sfile.dto.FileCategoryQueryDTO;
import com.senmesh.sfile.entity.FileCategory;
import com.senmesh.sfile.service.FileCategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 文件种类ServiceImpl
*/
@Service
public class FileCategoryServiceImpl implements FileCategoryService {
@Autowired
private FileCategoryMapper fileCategoryMapper;
@Override
@Transactional
public Long create(FileCategoryCreateDTO createDTO) {
FileCategory fileCategory = FileCategoryConvert.INSTANCE.toEntity(createDTO);
fileCategoryMapper.saveEntity(fileCategory);
return fileCategory.getId();
}
@Override
@Transactional
public void modify(FileCategoryModifyDTO modifyDTO) {
FileCategory fileCategory = FileCategoryConvert.INSTANCE.toEntity(modifyDTO);
fileCategoryMapper.updateEntitySelective(fileCategory);
}
@Override
@Transactional
public void remove(Long id) {
fileCategoryMapper.deleteEntity(FileCategory.builder().id(id).build(),
UserContextHolder.getLoginUserId());
}
@Override
public List<FileCategoryDTO> list(FileCategoryQueryDTO queryDTO) {
queryDTO.disablePage();
return fileCategoryMapper.list(queryDTO);
}
@Override
public void page(FileCategoryQueryDTO queryDTO) {
fileCategoryMapper.list(queryDTO);
}
@Override
public FileCategoryDTO find(FileCategoryQueryDTO queryDTO) {
List<FileCategoryDTO> fileCategoryDTOs = this.list(queryDTO);
return ListUtil.first(fileCategoryDTOs);
}
}

View File

@@ -0,0 +1,34 @@
package com.senmesh.sfile.service.impl;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.constant.FileStatusEnum;
import com.senmesh.sfile.constant.RootTypeEnum;
import com.senmesh.sfile.dto.UserFileCreateDTO;
import com.senmesh.sfile.service.NormalUserFileService;
import com.senmesh.sfile.service.UserFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* 普通用户文件ServiceImpl
*/
@Service
public class NormalUserFileServiceImpl implements NormalUserFileService {
@Autowired
private UserFileService userFileService;
@Override
@Transactional
public Long create(UserFileCreateDTO createDTO) {
createDTO.setUserId(UserContextHolder.getExistLoginUserId());
// 设置根类型为普通
createDTO.setRootType(RootTypeEnum.NORMAL.getType());
// TODO 扫描文件审核
createDTO.setFileStatus(FileStatusEnum.NORMAL.getStatus());
// 创建用户文件
return userFileService.create(createDTO);
}
}

View File

@@ -0,0 +1,50 @@
package com.senmesh.sfile.service.impl;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.constant.FileStatusEnum;
import com.senmesh.sfile.constant.RootTypeEnum;
import com.senmesh.sfile.dto.ExpandUserFileCreateDTO;
import com.senmesh.sfile.dto.ShareUserFileCreateDTO;
import com.senmesh.sfile.service.ShareUserFileService;
import com.senmesh.sfile.service.UserFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Calendar;
import java.util.Date;
/**
* 分享用户文件ServiceImpl
*/
@Service
public class ShareUserFileServiceImpl implements ShareUserFileService {
@Autowired
private UserFileService userFileService;
@Override
@Transactional
public Long create(ShareUserFileCreateDTO createDTO) {
Long userFileId = createDTO.getUserFileId();
Long userId = UserContextHolder.getExistLoginUserId();
Integer validDays = createDTO.getValidDays();
// 根据有效天数计算过期时间
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
calendar.add(Calendar.DAY_OF_MONTH, validDays);
Date endTime = calendar.getTime();
// 调用UserFileService的重载create方法,根据普通文件创建分享文件
ExpandUserFileCreateDTO expandCreateDTO = ExpandUserFileCreateDTO.builder()
.userFileId(userFileId)
.userId(userId)
.rootType(RootTypeEnum.SHARE.getType())
.fileStatus(FileStatusEnum.NORMAL.getStatus())
.endTime(endTime)
.build();
return userFileService.create(expandCreateDTO);
}
}

View File

@@ -0,0 +1,261 @@
package com.senmesh.sfile.service.impl;
import com.senmesh.common.constant.CommonConstants;
import com.senmesh.common.exception.util.Assert;
import com.senmesh.common.util.ListUtil;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.sfile.constant.FileTypeEnum;
import com.senmesh.sfile.constant.RootTypeEnum;
import com.senmesh.sfile.convert.UserFileConvert;
import com.senmesh.sfile.dao.UserFileMapper;
import com.senmesh.sfile.dto.ExpandUserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileCreateDTO;
import com.senmesh.sfile.dto.UserFileDTO;
import com.senmesh.sfile.dto.UserFileModifyDTO;
import com.senmesh.sfile.dto.UserFileModifyStatusDTO;
import com.senmesh.sfile.dto.UserFileQueryDTO;
import com.senmesh.sfile.entity.UserFile;
import com.senmesh.sfile.service.UserFileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* 用户文件ServiceImpl
*/
@Service
public class UserFileServiceImpl implements UserFileService {
@Autowired
private UserFileMapper userFileMapper;
@Override
@Transactional
public Long create(UserFileCreateDTO createDTO) {
Long parentId = createDTO.getParentId();
String parentPath = createDTO.getParentPath();
Long userId = createDTO.getUserId();
String rootType = createDTO.getRootType();
// 1. 校验文件类型时fileCode不能为空
if (FileTypeEnum.isFile(createDTO.getFileType())) {
Assert.notBlank(createDTO.getFileCode(), "文件编码不能为空");
}
// 2. 校验父节点(如果不是根目录)
if (parentId != null && parentId != 0L) {
// 如果没有提供parentPath,需要查询父节点
if (StringUtils.isBlank(parentPath)) {
UserFileDTO parentFile = this.findOne(UserFileQueryDTO.builder()
.id(parentId)
.userId(userId)
.rootType(rootType)
.build());
Assert.isTrue(FileTypeEnum.isFolder(parentFile.getFileType()), "父节点必须是文件夹");
// 获取父路径用于后续拼接
parentPath = parentFile.getPath();
}
// 如果提供了parentPath,信任调用方,不做校验
}
// 3. 插入数据获取ID
UserFile userFile = UserFileConvert.INSTANCE.toEntity(createDTO);
userFileMapper.saveEntity(userFile);
Long newId = userFile.getId();
// 4. 构建path
String path = StringUtils.isNotBlank(parentPath)
? parentPath + CommonConstants.COMMA + newId
: String.valueOf(newId);
// 5. 更新path
userFile.setPath(path);
userFileMapper.updateEntitySelective(userFile);
return newId;
}
@Override
@Transactional
public Long create(ExpandUserFileCreateDTO expandCreateDTO) {
Long userFileId = expandCreateDTO.getUserFileId();
Long userId = expandCreateDTO.getUserId();
String rootType = expandCreateDTO.getRootType();
// 1. 查询普通文件(限制rootType为普通)
UserFileDTO normalFile = this.findOne(UserFileQueryDTO.builder()
.id(userFileId)
.userId(userId)
.rootType(RootTypeEnum.NORMAL.getType())
.build());
// 2. 创建文件夹,文件名 = 原文件名 + 当前时间
String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
String folderName = normalFile.getFileName() + "_" + timestamp;
UserFileCreateDTO folderCreateDTO = UserFileCreateDTO.builder()
.userId(userId)
.rootType(rootType)
.fileType(FileTypeEnum.FOLDER.getType())
.fileName(folderName)
.parentId(0L)
.endTime(expandCreateDTO.getEndTime())
.accessCode(expandCreateDTO.getAccessCode())
.build();
Long folderId = this.create(folderCreateDTO);
String folderPath = String.valueOf(folderId);
// 3. 查询需要复制的文件列表
// 查询条件:path LIKE 'xxx%' AND fileType = '1'
// 如果是文件:会查到自己
// 如果是文件夹:会查到其下所有文件类型的子文件
UserFileQueryDTO queryDTO = UserFileQueryDTO.builder()
.userId(userId)
.rootType(RootTypeEnum.NORMAL.getType())
.fileType(FileTypeEnum.FILE.getType())
.pathLike(normalFile.getPath())
.build();
queryDTO.disablePage();
List<UserFileDTO> filesToCopy = this.list(queryDTO);
// 4. 在文件夹下创建文件对象
for (UserFileDTO fileDTO : filesToCopy) {
UserFileCreateDTO fileCreateDTO = UserFileCreateDTO.builder()
.userId(userId)
.rootType(rootType)
.fileType(FileTypeEnum.FILE.getType())
.fileName(fileDTO.getFileName())
.fileCode(fileDTO.getFileCode())
.parentPath(folderPath)
.build();
this.create(fileCreateDTO);
}
return folderId;
}
@Override
@Transactional
public void modify(UserFileModifyDTO modifyDTO) {
Long id = modifyDTO.getId();
Long userId = modifyDTO.getUserId();
Long newParentId = modifyDTO.getParentId();
String rootType = modifyDTO.getRootType();
// 1. 根据id+userId+rootType查询文件是否存在
UserFileDTO existFile = this.findOne(UserFileQueryDTO.builder()
.id(id)
.userId(userId)
.rootType(rootType)
.build());
// 2. 判断是否需要更新path(parentId有值且与现存的parentId不一致)
boolean needUpdatePath = newParentId != null
&& !newParentId.equals(existFile.getParentId());
if (needUpdatePath) {
// 2.1 校验新父节点(如果不是根目录)
if (newParentId != 0L) {
UserFileDTO newParentFile = this.findOne(UserFileQueryDTO.builder()
.id(newParentId)
.userId(userId)
.rootType(rootType)
.build());
Assert.isTrue(FileTypeEnum.isFolder(newParentFile.getFileType()), "父节点必须是文件夹");
// 校验新父节点的rootType必须与当前文件相同
Assert.isTrue(existFile.getRootType().equals(newParentFile.getRootType()),
"不能将文件移动到不同类型的文件夹");
}
// 2.2 在SQL中一次性更新当前节点和所有子孙节点的path(SQL内部会限制相同userId和rootType)
userFileMapper.updatePathByParentIdChange(id, newParentId);
}
// 3. 更新文件信息
UserFile userFile = UserFileConvert.INSTANCE.toEntity(modifyDTO);
userFileMapper.updateEntitySelective(userFile);
}
@Override
@Transactional
public void modifyStatus(UserFileModifyStatusDTO modifyStatusDTO) {
Long id = modifyStatusDTO.getId();
String oldStatus = modifyStatusDTO.getOldStatus();
String newStatus = modifyStatusDTO.getNewStatus();
Long operateUserId = UserContextHolder.getLoginUserId();
// 更新文件状态及其所有子文件状态(SQL内部会校验oldStatus并限制相同userId和rootType)
userFileMapper.updateStatusWithChildren(id, oldStatus, newStatus, operateUserId);
}
@Override
@Transactional
public void modifyStatus(UserFileModifyStatusDTO modifyStatusDTO, Long userId) {
Assert.notNull(userId, "用户ID不能为空");
Long id = modifyStatusDTO.getId();
// 校验文件是否存在且属于该用户
this.findOne(UserFileQueryDTO.builder()
.id(id)
.userId(userId)
.build());
// 调用原方法修改状态
modifyStatus(modifyStatusDTO);
}
@Override
@Transactional
public void remove(Long id) {
// 删除文件及其所有子文件(SQL内部会限制相同userId和rootType)
userFileMapper.deleteFileWithChildren(id, UserContextHolder.getLoginUserId());
}
@Override
@Transactional
public void remove(Long id, Long userId) {
Assert.notNull(id, "文件ID不能为空");
Assert.notNull(userId, "用户ID不能为空");
// 校验文件是否存在且属于该用户
this.findOne(UserFileQueryDTO.builder()
.id(id)
.userId(userId)
.build());
// 删除文件及其所有子文件(SQL内部会限制相同userId和rootType)
remove(id);
}
@Override
public List<UserFileDTO> list(UserFileQueryDTO queryDTO) {
queryDTO.disablePage();
return userFileMapper.list(queryDTO);
}
@Override
public void page(UserFileQueryDTO queryDTO) {
userFileMapper.list(queryDTO);
}
@Override
public UserFileDTO find(UserFileQueryDTO queryDTO) {
List<UserFileDTO> userFileDTOs = this.list(queryDTO);
return ListUtil.first(userFileDTOs);
}
@Override
public UserFileDTO findOne(UserFileQueryDTO queryDTO) {
UserFileDTO userFileDTO = this.find(queryDTO);
Assert.notNull(userFileDTO, "文件不存在");
return userFileDTO;
}
}

View File

@@ -0,0 +1,100 @@
package com.senmesh.sfile.service.impl;
import com.senmesh.common.exception.util.Assert;
import com.senmesh.common.util.ListUtil;
import com.senmesh.common.util.UserContextHolder;
import com.senmesh.frame.redis.dto.LockDTO;
import com.senmesh.frame.redis.redisson.RedissonUtils;
import com.senmesh.sfile.convert.UserSpaceConvert;
import com.senmesh.sfile.dao.UserSpaceMapper;
import com.senmesh.sfile.dto.UserSpaceCreateDTO;
import com.senmesh.sfile.dto.UserSpaceDTO;
import com.senmesh.sfile.dto.UserSpaceModifyDTO;
import com.senmesh.sfile.dto.UserSpaceQueryDTO;
import com.senmesh.sfile.entity.UserSpace;
import com.senmesh.sfile.service.UserSpaceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 用户空间ServiceImpl
*/
@Service
public class UserSpaceServiceImpl implements UserSpaceService {
@Autowired
private UserSpaceMapper userSpaceMapper;
/**
* 默认总容量:5GB
*/
private static final Long DEFAULT_TOTAL_SIZE = 5L * 1024 * 1024 * 1024;
public static LockDTO getLockDTO(Long userId) {
Assert.notNull(userId, "用户id不能为空");
return LockDTO.builder().methodName("userspace").tryLockWaitTime(0L)
.arg(userId.toString())
.failMsg("该用户空间正在被操作")
.build();
}
@Override
@Transactional
public Long create(UserSpaceCreateDTO createDTO) {
Long userId = createDTO.getUserId();
UserSpaceQueryDTO queryDTO = UserSpaceQueryDTO.builder().userId(userId).build();
return RedissonUtils.lockAndSave(getLockDTO(userId),
() -> this.find(queryDTO), () -> {
UserSpace userSpace = UserSpaceConvert.INSTANCE.toEntity(createDTO);
userSpace.setTotalSize(DEFAULT_TOTAL_SIZE);
userSpace.setUsedSize(0L);
userSpaceMapper.saveEntity(userSpace);
return userSpace.getId();
});
}
@Override
@Transactional
public void modify(UserSpaceModifyDTO modifyDTO) {
Long userId = modifyDTO.getUserId();
UserSpaceQueryDTO queryDTO = UserSpaceQueryDTO.builder().userId(userId).build();
UserSpaceDTO userSpaceDTO = this.find(queryDTO);
Assert.notNull(userSpaceDTO, "用户空间不存在");
UserSpace userSpace = UserSpace.builder()
.id(userSpaceDTO.getId())
.usedSize(modifyDTO.getUsedSize())
.build();
userSpaceMapper.updateEntitySelective(userSpace);
}
@Override
@Transactional
public void remove(Long id) {
userSpaceMapper.deleteEntity(UserSpace.builder().id(id).build(),
UserContextHolder.getLoginUserId());
}
@Override
public List<UserSpaceDTO> list(UserSpaceQueryDTO queryDTO) {
queryDTO.disablePage();
return userSpaceMapper.list(queryDTO);
}
@Override
public void page(UserSpaceQueryDTO queryDTO) {
userSpaceMapper.list(queryDTO);
}
@Override
public UserSpaceDTO find(UserSpaceQueryDTO queryDTO) {
List<UserSpaceDTO> userSpaceDTOs = this.list(queryDTO);
return ListUtil.first(userSpaceDTOs);
}
}

View File

@@ -1,12 +1,11 @@
spring.application.name=demo
spring.application.name=s-file
system.code=1
##数据源
spring.datasource.url=jdbc:mysql://121.37.2.171:3306/uygur-job?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true&allowMultiQueries=true&useSSL=false
#&useAffectedRows=true
spring.datasource.username=root
spring.datasource.password=xinshan888
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:postgresql://139.159.237.199:8608/f?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=postgres
spring.datasource.password=f123456
spring.datasource.driverClassName=org.postgresql.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 初始化时建立物理连接的个数
@@ -25,7 +24,7 @@ spring.cloud.config.overrideNone=true
# mybatis
mybatis.mapperLocations=classpath*:com/newyetai/**/mapper/*Mapper.xml
mybatis.configuration.map-underscore-to-camel-case=true
pagehelper.helperDialect=mysql
pagehelper.helperDialect=postgresql
pagehelper.reasonable=true
#mybatis plus
@@ -55,14 +54,14 @@ code.snowflake.workid.139.159.237.199=2
##redis配置
spring.redis.password=Xinshan888
spring.redis.host=121.37.2.171
spring.redis.port=6379
spring.redis.password=
spring.redis.host=139.159.237.199
spring.redis.port=8607
spring.redis.lettuce.pool.min-idle=2
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-active=10
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.database=13
spring.redis.database=1
##mq
spring.rabbitmq.host=121.37.2.171