diff --git a/db/file-postgres.sql b/db/file-postgres.sql new file mode 100644 index 0000000..61f1eaf --- /dev/null +++ b/db/file-postgres.sql @@ -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 '代理人'; + + + diff --git a/db/file.sql b/db/file.sql new file mode 100644 index 0000000..4094b39 --- /dev/null +++ b/db/file.sql @@ -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='用户文件'; diff --git a/db/init-data.sql b/db/init-data.sql new file mode 100644 index 0000000..0c92fe9 --- /dev/null +++ b/db/init-data.sql @@ -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); \ No newline at end of file diff --git a/src/main/java/com/senmesh/sfile/constant/FileStatusEnum.java b/src/main/java/com/senmesh/sfile/constant/FileStatusEnum.java new file mode 100644 index 0000000..cab6c10 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/constant/FileStatusEnum.java @@ -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); + } +} + diff --git a/src/main/java/com/senmesh/sfile/constant/FileTypeEnum.java b/src/main/java/com/senmesh/sfile/constant/FileTypeEnum.java new file mode 100644 index 0000000..d970f70 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/constant/FileTypeEnum.java @@ -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); + } +} + diff --git a/src/main/java/com/senmesh/sfile/constant/RootTypeEnum.java b/src/main/java/com/senmesh/sfile/constant/RootTypeEnum.java new file mode 100644 index 0000000..02fb79d --- /dev/null +++ b/src/main/java/com/senmesh/sfile/constant/RootTypeEnum.java @@ -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); + } +} + diff --git a/src/main/java/com/senmesh/sfile/controller/FileCategoryController.java b/src/main/java/com/senmesh/sfile/controller/FileCategoryController.java new file mode 100644 index 0000000..37fa71a --- /dev/null +++ b/src/main/java/com/senmesh/sfile/controller/FileCategoryController.java @@ -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 create(@Validated @RequestBody FileCategoryCreateDTO createDTO) { + return AlitaResult.success(fileCategoryService.create(createDTO)); + } + + @PostMapping("/modify") + @ApiOperation("修改") + public AlitaResult modify(@Validated @RequestBody FileCategoryModifyDTO modifyDTO) { + fileCategoryService.modify(modifyDTO); + return AlitaResult.success(true); + } + + @DeleteMapping("/remove/{id}") + @ApiOperation("删除") + public AlitaResult remove(@PathVariable Long id) { + fileCategoryService.remove(id); + return AlitaResult.success(true); + } + + @GetMapping("/find") + @ApiOperation("查询") + public AlitaResult find(FileCategoryQueryDTO queryDTO) { + return AlitaResult.success(fileCategoryService.find(queryDTO)); + } + + @GetMapping("/list") + @ApiOperation("列表查询") + public AlitaResult> list(FileCategoryQueryDTO queryDTO) { + return AlitaResult.success(fileCategoryService.list(queryDTO)); + } + + @GetMapping("/page") + @ApiOperation("分页查询") + public AlitaResult> page(FileCategoryQueryDTO queryDTO) { + fileCategoryService.page(queryDTO); + return AlitaResult.success(queryDTO.getPageResult()); + } +} + diff --git a/src/main/java/com/senmesh/sfile/controller/NormalUserFileController.java b/src/main/java/com/senmesh/sfile/controller/NormalUserFileController.java new file mode 100644 index 0000000..5097ccc --- /dev/null +++ b/src/main/java/com/senmesh/sfile/controller/NormalUserFileController.java @@ -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 create(@Validated @RequestBody UserFileCreateDTO createDTO) { + return AlitaResult.success(normalUserFileService.create(createDTO)); + } + + + @PutMapping("/recover/{id}") + @ApiOperation("恢复") + public AlitaResult 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); + } + + +} + diff --git a/src/main/java/com/senmesh/sfile/controller/ShareUserFileController.java b/src/main/java/com/senmesh/sfile/controller/ShareUserFileController.java new file mode 100644 index 0000000..c76b6a3 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/controller/ShareUserFileController.java @@ -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 create(@Validated @RequestBody ShareUserFileCreateDTO createDTO) { + return AlitaResult.success(shareUserFileService.create(createDTO)); + } + + + +} + diff --git a/src/main/java/com/senmesh/sfile/controller/UserFileController.java b/src/main/java/com/senmesh/sfile/controller/UserFileController.java new file mode 100644 index 0000000..d93cadd --- /dev/null +++ b/src/main/java/com/senmesh/sfile/controller/UserFileController.java @@ -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 create(@Validated @RequestBody UserFileCreateDTO createDTO) { + return AlitaResult.success(userFileService.create(createDTO)); + } + + @PostMapping("/modify") + @ApiOperation("修改") + public AlitaResult modify(@Validated @RequestBody UserFileModifyDTO modifyDTO) { + modifyDTO.setUserId(UserContextHolder.getExistLoginUserId()); + userFileService.modify(modifyDTO); + return AlitaResult.success(true); + } + + @DeleteMapping("/remove/{id}") + @ApiOperation("删除") + public AlitaResult remove(@PathVariable Long id) { + Long userId = UserContextHolder.getExistLoginUserId(); + userFileService.remove(id, userId); + return AlitaResult.success(true); + } + + @PutMapping("/invalid/{id}") + @ApiOperation("失效") + public AlitaResult 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 find(UserFileQueryDTO queryDTO) { + queryDTO.setUserId(UserContextHolder.getExistLoginUserId()); + return AlitaResult.success(userFileService.find(queryDTO)); + } + + @GetMapping("/list") + @ApiOperation("列表查询") + public AlitaResult> list(UserFileQueryDTO queryDTO) { + queryDTO.setUserId(UserContextHolder.getExistLoginUserId()); + return AlitaResult.success(userFileService.list(queryDTO)); + } + + @GetMapping("/page") + @ApiOperation("分页查询") + public AlitaResult> page(UserFileQueryDTO queryDTO) { + queryDTO.setUserId(UserContextHolder.getExistLoginUserId()); + userFileService.page(queryDTO); + return AlitaResult.success(queryDTO.getPageResult()); + } +} + diff --git a/src/main/java/com/senmesh/sfile/controller/UserSpaceController.java b/src/main/java/com/senmesh/sfile/controller/UserSpaceController.java new file mode 100644 index 0000000..d4bb8a5 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/controller/UserSpaceController.java @@ -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 create(@Validated @RequestBody UserSpaceCreateDTO createDTO) { + + return AlitaResult.success(userSpaceService.create(createDTO)); + } + + @PostMapping("/modify") + @ApiOperation("修改") + public AlitaResult modify(@Validated @RequestBody UserSpaceModifyDTO modifyDTO) { + userSpaceService.modify(modifyDTO); + return AlitaResult.success(true); + } + + @DeleteMapping("/remove/{id}") + @ApiOperation("删除") + public AlitaResult remove(@PathVariable Long id) { + userSpaceService.remove(id); + return AlitaResult.success(true); + } + + @GetMapping("/find") + @ApiOperation("查询") + public AlitaResult find(UserSpaceQueryDTO queryDTO) { + return AlitaResult.success(userSpaceService.find(queryDTO)); + } + + @GetMapping("/list") + @ApiOperation("列表查询") + public AlitaResult> list(UserSpaceQueryDTO queryDTO) { + return AlitaResult.success(userSpaceService.list(queryDTO)); + } + + @GetMapping("/page") + @ApiOperation("分页查询") + public AlitaResult> page(UserSpaceQueryDTO queryDTO) { + userSpaceService.page(queryDTO); + return AlitaResult.success(queryDTO.getPageResult()); + } +} + diff --git a/src/main/java/com/senmesh/sfile/convert/FileCategoryConvert.java b/src/main/java/com/senmesh/sfile/convert/FileCategoryConvert.java new file mode 100644 index 0000000..c5ed49a --- /dev/null +++ b/src/main/java/com/senmesh/sfile/convert/FileCategoryConvert.java @@ -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); +} + diff --git a/src/main/java/com/senmesh/sfile/convert/UserFileConvert.java b/src/main/java/com/senmesh/sfile/convert/UserFileConvert.java new file mode 100644 index 0000000..8cc89e5 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/convert/UserFileConvert.java @@ -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); +} + diff --git a/src/main/java/com/senmesh/sfile/convert/UserSpaceConvert.java b/src/main/java/com/senmesh/sfile/convert/UserSpaceConvert.java new file mode 100644 index 0000000..1c46fa4 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/convert/UserSpaceConvert.java @@ -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); +} + diff --git a/src/main/java/com/senmesh/sfile/dao/FileCategoryMapper.java b/src/main/java/com/senmesh/sfile/dao/FileCategoryMapper.java new file mode 100644 index 0000000..e04ad78 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dao/FileCategoryMapper.java @@ -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 { + + /** + * 查询列表(PageHelper会根据queryDTO自动判断是否分页) + * + * @param queryDTO 查询DTO + * @return List + */ + List list(@Param("param") FileCategoryQueryDTO queryDTO); +} + diff --git a/src/main/java/com/senmesh/sfile/dao/UserFileMapper.java b/src/main/java/com/senmesh/sfile/dao/UserFileMapper.java new file mode 100644 index 0000000..04b1f8e --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dao/UserFileMapper.java @@ -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 { + + /** + * 查询列表(PageHelper会根据queryDTO自动判断是否分页) + * + * @param queryDTO 查询DTO + * @return List + */ + List 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); +} + diff --git a/src/main/java/com/senmesh/sfile/dao/UserSpaceMapper.java b/src/main/java/com/senmesh/sfile/dao/UserSpaceMapper.java new file mode 100644 index 0000000..0168b4e --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dao/UserSpaceMapper.java @@ -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 { + + /** + * 查询列表(PageHelper会根据queryDTO自动判断是否分页) + * + * @param queryDTO 查询DTO + * @return List + */ + List list(@Param("param") UserSpaceQueryDTO queryDTO); +} + diff --git a/src/main/java/com/senmesh/sfile/dto/ExpandUserFileCreateDTO.java b/src/main/java/com/senmesh/sfile/dto/ExpandUserFileCreateDTO.java new file mode 100644 index 0000000..adc021e --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/ExpandUserFileCreateDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/FileCategoryCreateDTO.java b/src/main/java/com/senmesh/sfile/dto/FileCategoryCreateDTO.java new file mode 100644 index 0000000..4d0d6ea --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/FileCategoryCreateDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/FileCategoryDTO.java b/src/main/java/com/senmesh/sfile/dto/FileCategoryDTO.java new file mode 100644 index 0000000..aad1bce --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/FileCategoryDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/FileCategoryModifyDTO.java b/src/main/java/com/senmesh/sfile/dto/FileCategoryModifyDTO.java new file mode 100644 index 0000000..a632b65 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/FileCategoryModifyDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/FileCategoryQueryDTO.java b/src/main/java/com/senmesh/sfile/dto/FileCategoryQueryDTO.java new file mode 100644 index 0000000..2269628 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/FileCategoryQueryDTO.java @@ -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 { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键ID") + private Long id; + + @ApiModelProperty("文件种类") + private String fileCategory; + + @ApiModelProperty("文件后缀") + private String fileSuffix; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/ShareUserFileCreateDTO.java b/src/main/java/com/senmesh/sfile/dto/ShareUserFileCreateDTO.java new file mode 100644 index 0000000..d124d1f --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/ShareUserFileCreateDTO.java @@ -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; + +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserFileCreateDTO.java b/src/main/java/com/senmesh/sfile/dto/UserFileCreateDTO.java new file mode 100644 index 0000000..acd2eb4 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserFileCreateDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserFileDTO.java b/src/main/java/com/senmesh/sfile/dto/UserFileDTO.java new file mode 100644 index 0000000..2adf585 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserFileDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserFileModifyDTO.java b/src/main/java/com/senmesh/sfile/dto/UserFileModifyDTO.java new file mode 100644 index 0000000..de9b296 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserFileModifyDTO.java @@ -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; + + +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserFileModifyStatusDTO.java b/src/main/java/com/senmesh/sfile/dto/UserFileModifyStatusDTO.java new file mode 100644 index 0000000..6e36348 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserFileModifyStatusDTO.java @@ -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; + +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserFileQueryDTO.java b/src/main/java/com/senmesh/sfile/dto/UserFileQueryDTO.java new file mode 100644 index 0000000..8303be7 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserFileQueryDTO.java @@ -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 { + + 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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserSpaceCreateDTO.java b/src/main/java/com/senmesh/sfile/dto/UserSpaceCreateDTO.java new file mode 100644 index 0000000..8c93b2a --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserSpaceCreateDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserSpaceDTO.java b/src/main/java/com/senmesh/sfile/dto/UserSpaceDTO.java new file mode 100644 index 0000000..34f1c4c --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserSpaceDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserSpaceModifyDTO.java b/src/main/java/com/senmesh/sfile/dto/UserSpaceModifyDTO.java new file mode 100644 index 0000000..5c803de --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserSpaceModifyDTO.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/dto/UserSpaceQueryDTO.java b/src/main/java/com/senmesh/sfile/dto/UserSpaceQueryDTO.java new file mode 100644 index 0000000..7d80f5e --- /dev/null +++ b/src/main/java/com/senmesh/sfile/dto/UserSpaceQueryDTO.java @@ -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 { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty("主键ID") + private Long id; + + @ApiModelProperty("用户id") + private Long userId; +} + diff --git a/src/main/java/com/senmesh/sfile/entity/FileCategory.java b/src/main/java/com/senmesh/sfile/entity/FileCategory.java new file mode 100644 index 0000000..bfec5cc --- /dev/null +++ b/src/main/java/com/senmesh/sfile/entity/FileCategory.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/entity/UserFile.java b/src/main/java/com/senmesh/sfile/entity/UserFile.java new file mode 100644 index 0000000..4f86be9 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/entity/UserFile.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/entity/UserSpace.java b/src/main/java/com/senmesh/sfile/entity/UserSpace.java new file mode 100644 index 0000000..dcb1e38 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/entity/UserSpace.java @@ -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; +} + diff --git a/src/main/java/com/senmesh/sfile/mapper/FileCategoryMapper.xml b/src/main/java/com/senmesh/sfile/mapper/FileCategoryMapper.xml new file mode 100644 index 0000000..82857d9 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/mapper/FileCategoryMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + + FROM x_file_category t + WHERE t.deleted = 0 + + AND t.id = #{param.id} + + + AND t.file_category = #{param.fileCategory} + + + AND t.file_suffix = #{param.fileSuffix} + + + + diff --git a/src/main/java/com/senmesh/sfile/mapper/UserFileMapper.xml b/src/main/java/com/senmesh/sfile/mapper/UserFileMapper.xml new file mode 100644 index 0000000..c4e3616 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/mapper/UserFileMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + FROM x_user_file t + WHERE t.deleted = 0 + + AND t.id = #{param.id} + + + AND t.user_id = #{param.userId} + + + AND t.root_type = #{param.rootType} + + + AND t.file_type = #{param.fileType} + + + AND t.file_name = #{param.fileName} + + + + AND t.file_name LIKE #{fileNameLike} + + + AND t.parent_id = #{param.parentId} + + + AND t.file_code = #{param.fileCode} + + + AND t.file_status = #{param.fileStatus} + + + + AND t.path LIKE #{pathLike} + + + + + 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 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 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 + + + diff --git a/src/main/java/com/senmesh/sfile/mapper/UserSpaceMapper.xml b/src/main/java/com/senmesh/sfile/mapper/UserSpaceMapper.xml new file mode 100644 index 0000000..bcdaa3a --- /dev/null +++ b/src/main/java/com/senmesh/sfile/mapper/UserSpaceMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + FROM x_user_space t + WHERE t.deleted = 0 + + AND t.id = #{param.id} + + + AND t.user_id = #{param.userId} + + + + diff --git a/src/main/java/com/senmesh/sfile/service/FileCategoryService.java b/src/main/java/com/senmesh/sfile/service/FileCategoryService.java new file mode 100644 index 0000000..add8672 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/FileCategoryService.java @@ -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 + */ + List list(FileCategoryQueryDTO queryDTO); + + /** + * 分页查询 + * + * @param queryDTO 查询DTO + */ + void page(FileCategoryQueryDTO queryDTO); + + /** + * 单个查询 + * + * @param queryDTO 查询DTO + * @return FileCategoryDTO + */ + FileCategoryDTO find(FileCategoryQueryDTO queryDTO); +} + diff --git a/src/main/java/com/senmesh/sfile/service/NormalUserFileService.java b/src/main/java/com/senmesh/sfile/service/NormalUserFileService.java new file mode 100644 index 0000000..e154846 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/NormalUserFileService.java @@ -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); +} + diff --git a/src/main/java/com/senmesh/sfile/service/ShareUserFileService.java b/src/main/java/com/senmesh/sfile/service/ShareUserFileService.java new file mode 100644 index 0000000..a6e596b --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/ShareUserFileService.java @@ -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); +} + diff --git a/src/main/java/com/senmesh/sfile/service/UserFileService.java b/src/main/java/com/senmesh/sfile/service/UserFileService.java new file mode 100644 index 0000000..d8005b6 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/UserFileService.java @@ -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 + */ + List 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); +} + diff --git a/src/main/java/com/senmesh/sfile/service/UserSpaceService.java b/src/main/java/com/senmesh/sfile/service/UserSpaceService.java new file mode 100644 index 0000000..6dff348 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/UserSpaceService.java @@ -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 + */ + List list(UserSpaceQueryDTO queryDTO); + + /** + * 分页查询 + * + * @param queryDTO 查询DTO + */ + void page(UserSpaceQueryDTO queryDTO); + + /** + * 单个查询 + * + * @param queryDTO 查询DTO + * @return UserSpaceDTO + */ + UserSpaceDTO find(UserSpaceQueryDTO queryDTO); +} + diff --git a/src/main/java/com/senmesh/sfile/service/impl/FileCategoryServiceImpl.java b/src/main/java/com/senmesh/sfile/service/impl/FileCategoryServiceImpl.java new file mode 100644 index 0000000..1385115 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/impl/FileCategoryServiceImpl.java @@ -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 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 fileCategoryDTOs = this.list(queryDTO); + return ListUtil.first(fileCategoryDTOs); + } +} + diff --git a/src/main/java/com/senmesh/sfile/service/impl/NormalUserFileServiceImpl.java b/src/main/java/com/senmesh/sfile/service/impl/NormalUserFileServiceImpl.java new file mode 100644 index 0000000..ec16e74 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/impl/NormalUserFileServiceImpl.java @@ -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); + } +} + diff --git a/src/main/java/com/senmesh/sfile/service/impl/ShareUserFileServiceImpl.java b/src/main/java/com/senmesh/sfile/service/impl/ShareUserFileServiceImpl.java new file mode 100644 index 0000000..a9ec84b --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/impl/ShareUserFileServiceImpl.java @@ -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); + } +} + diff --git a/src/main/java/com/senmesh/sfile/service/impl/UserFileServiceImpl.java b/src/main/java/com/senmesh/sfile/service/impl/UserFileServiceImpl.java new file mode 100644 index 0000000..66040d0 --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/impl/UserFileServiceImpl.java @@ -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 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 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 userFileDTOs = this.list(queryDTO); + return ListUtil.first(userFileDTOs); + } + + @Override + public UserFileDTO findOne(UserFileQueryDTO queryDTO) { + UserFileDTO userFileDTO = this.find(queryDTO); + Assert.notNull(userFileDTO, "文件不存在"); + return userFileDTO; + } +} + diff --git a/src/main/java/com/senmesh/sfile/service/impl/UserSpaceServiceImpl.java b/src/main/java/com/senmesh/sfile/service/impl/UserSpaceServiceImpl.java new file mode 100644 index 0000000..d23b88e --- /dev/null +++ b/src/main/java/com/senmesh/sfile/service/impl/UserSpaceServiceImpl.java @@ -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 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 userSpaceDTOs = this.list(queryDTO); + return ListUtil.first(userSpaceDTOs); + } +} + diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 802fb3b..929a147 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -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