From 64309a078a0ecd472748a6fe4599f139d0583f1d Mon Sep 17 00:00:00 2001 From: none Date: Wed, 8 Mar 2023 17:20:39 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B5=84=E6=BA=90=E5=88=86=E7=B1=BB=E6=95=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/ResourceCategoryController.java | 48 +++--- .../backend/ResourceController.java | 64 -------- .../controller/backend/UploadController.java | 20 +-- .../java/xyz/playedu/api/domain/Resource.java | 18 +-- .../playedu/api/domain/ResourceCategory.java | 21 ++- .../api/domain/ResourceCategoryRelation.java | 65 ++++++++ .../api/mapper/ResourceCategoryMapper.java | 2 +- .../ResourceCategoryRelationMapper.java | 20 +++ .../playedu/api/mapper/ResourceMapper.java | 2 +- .../backend/ResourceCategoryRequest.java | 16 +- .../backend/UploadVideoMergeRequest.java | 3 +- .../api/service/ResourceCategoryService.java | 14 +- .../playedu/api/service/ResourceService.java | 4 +- .../playedu/api/service/UploadService.java | 4 +- .../impl/ResourceCategoryServiceImpl.java | 139 +++++++++++++++--- .../api/service/impl/ResourceServiceImpl.java | 29 +++- .../api/service/impl/UploadServiceImpl.java | 23 ++- .../ResourceCategoryRelationServiceImpl.java | 22 +++ .../ResourceCategoryRelationService.java | 13 ++ .../mapper/ResourceCategoryMapper.xml | 8 +- .../mapper/ResourceCategoryRelationMapper.xml | 15 ++ src/main/resources/mapper/ResourceMapper.xml | 10 +- 22 files changed, 372 insertions(+), 188 deletions(-) create mode 100644 src/main/java/xyz/playedu/api/domain/ResourceCategoryRelation.java create mode 100644 src/main/java/xyz/playedu/api/mapper/ResourceCategoryRelationMapper.java create mode 100644 src/main/java/xyz/playedu/api/service/impl/internal/ResourceCategoryRelationServiceImpl.java create mode 100644 src/main/java/xyz/playedu/api/service/internal/ResourceCategoryRelationService.java create mode 100644 src/main/resources/mapper/ResourceCategoryRelationMapper.xml diff --git a/src/main/java/xyz/playedu/api/controller/backend/ResourceCategoryController.java b/src/main/java/xyz/playedu/api/controller/backend/ResourceCategoryController.java index 5e5c131..56d3441 100644 --- a/src/main/java/xyz/playedu/api/controller/backend/ResourceCategoryController.java +++ b/src/main/java/xyz/playedu/api/controller/backend/ResourceCategoryController.java @@ -6,7 +6,6 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import xyz.playedu.api.PlayEduBackendThreadLocal; import xyz.playedu.api.constant.BPermissionConstant; -import xyz.playedu.api.constant.BackendConstant; import xyz.playedu.api.domain.ResourceCategory; import xyz.playedu.api.event.ResourceCategoryDestroyEvent; import xyz.playedu.api.exception.NotFoundException; @@ -15,10 +14,8 @@ import xyz.playedu.api.request.backend.ResourceCategoryRequest; import xyz.playedu.api.service.ResourceCategoryService; import xyz.playedu.api.types.JsonResponse; -import java.util.Arrays; -import java.util.Date; -import java.util.HashMap; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; /** * @Author 杭州白书科技有限公司 @@ -29,62 +26,59 @@ import java.util.List; public class ResourceCategoryController { @Autowired - private ResourceCategoryService resourceCategoryService; + private ResourceCategoryService categoryService; @Autowired private ApplicationContext ctx; @GetMapping("/index") - public JsonResponse index(@RequestParam(name = "type") String type) { - List categories = resourceCategoryService.getByType(type); + public JsonResponse index() { + Map> categories = categoryService.all().stream().collect(Collectors.groupingBy(ResourceCategory::getParentId)); HashMap data = new HashMap<>(); - data.put("data", categories); + data.put("categories", categories); return JsonResponse.data(data); } - @BackendPermissionMiddleware(slug = BPermissionConstant.RESOURCE_CATEGORY) @GetMapping("/create") public JsonResponse create() { + Map> categories = categoryService.all().stream().collect(Collectors.groupingBy(ResourceCategory::getParentId)); + HashMap data = new HashMap<>(); - data.put("types", BackendConstant.RESOURCE_TYPE_WHITELIST); + data.put("categories", categories); + return JsonResponse.data(data); } @BackendPermissionMiddleware(slug = BPermissionConstant.RESOURCE_CATEGORY) @PostMapping("/create") - public JsonResponse store(@RequestBody @Validated ResourceCategoryRequest req) { - if (!Arrays.asList(BackendConstant.RESOURCE_TYPE_WHITELIST).contains(req.getType())) { - return JsonResponse.error("资源类型不支持"); - } - resourceCategoryService.create(req.getType(), req.getSort(), req.getName()); + public JsonResponse store(@RequestBody @Validated ResourceCategoryRequest req) throws NotFoundException { + categoryService.create(req.getName(), req.getParentId(), req.getSort()); return JsonResponse.success(); } @BackendPermissionMiddleware(slug = BPermissionConstant.RESOURCE_CATEGORY) @GetMapping("/{id}") - public JsonResponse edit(@PathVariable(name = "id") Integer id) throws NotFoundException { - ResourceCategory category = resourceCategoryService.findOrFail(id); + public JsonResponse edit(@PathVariable Integer id) throws NotFoundException { + ResourceCategory category = categoryService.findOrFail(id); return JsonResponse.data(category); } @BackendPermissionMiddleware(slug = BPermissionConstant.RESOURCE_CATEGORY) @PutMapping("/{id}") - public JsonResponse update(@PathVariable(name = "id") Integer id, @RequestBody @Validated ResourceCategoryRequest req) throws NotFoundException { - if (!Arrays.asList(BackendConstant.RESOURCE_TYPE_WHITELIST).contains(req.getType())) { - return JsonResponse.error("资源类型不支持"); - } - ResourceCategory category = resourceCategoryService.findOrFail(id); - resourceCategoryService.update(category, req.getSort(), req.getName()); + public JsonResponse update(@PathVariable Integer id, @RequestBody ResourceCategoryRequest req) throws NotFoundException { + ResourceCategory category = categoryService.findOrFail(id); + categoryService.update(category, req.getName(), req.getParentId(), req.getSort()); return JsonResponse.success(); } @BackendPermissionMiddleware(slug = BPermissionConstant.RESOURCE_CATEGORY) @DeleteMapping("/{id}") - public JsonResponse destroy(@PathVariable(name = "id") Integer id) { - resourceCategoryService.removeById(id); - ctx.publishEvent(new ResourceCategoryDestroyEvent(this, PlayEduBackendThreadLocal.getAdminUserID(), id, new Date())); + public JsonResponse destroy(@PathVariable Integer id) throws NotFoundException { + ResourceCategory category = categoryService.findOrFail(id); + categoryService.deleteById(category.getId()); + ctx.publishEvent(new ResourceCategoryDestroyEvent(this, PlayEduBackendThreadLocal.getAdminUserID(), category.getId(), new Date())); return JsonResponse.success(); } diff --git a/src/main/java/xyz/playedu/api/controller/backend/ResourceController.java b/src/main/java/xyz/playedu/api/controller/backend/ResourceController.java index 93cf61a..d624c1d 100644 --- a/src/main/java/xyz/playedu/api/controller/backend/ResourceController.java +++ b/src/main/java/xyz/playedu/api/controller/backend/ResourceController.java @@ -1,19 +1,14 @@ package xyz.playedu.api.controller.backend; -import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.MapUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import xyz.playedu.api.constant.BackendConstant; import xyz.playedu.api.domain.Resource; -import xyz.playedu.api.domain.ResourceCategory; import xyz.playedu.api.domain.ResourceVideo; import xyz.playedu.api.exception.NotFoundException; -import xyz.playedu.api.request.backend.ResourceRequest; import xyz.playedu.api.service.MinioService; -import xyz.playedu.api.service.ResourceCategoryService; import xyz.playedu.api.service.ResourceService; import xyz.playedu.api.service.ResourceVideoService; import xyz.playedu.api.types.JsonResponse; @@ -28,7 +23,6 @@ import java.util.stream.Collectors; * @create 2023/2/23 10:50 */ @RestController -@Slf4j @RequestMapping("/backend/v1/resource") public class ResourceController { @@ -38,9 +32,6 @@ public class ResourceController { @Autowired private ResourceVideoService resourceVideoService; - @Autowired - private ResourceCategoryService categoryService; - @Autowired private MinioService minioService; @@ -61,7 +52,6 @@ public class ResourceController { ResourcePaginateFilter filter = new ResourcePaginateFilter(); filter.setSortAlgo(sortAlgo); filter.setSortField(sortField); - filter.setType(type); if (name != null && name.length() > 0) { filter.setName(name); } @@ -84,60 +74,6 @@ public class ResourceController { return JsonResponse.data(data); } - @GetMapping("/create") - public JsonResponse create(@RequestParam(name = "type") String type) { - List categories = categoryService.getByType(type); - - HashMap data = new HashMap<>(); - data.put("categories", categories); - - return JsonResponse.data(data); - } - - @PostMapping("/create") - @Transactional - public JsonResponse store(@RequestBody @Validated ResourceRequest req) { - String disk = req.getDisk(); - if (!Arrays.asList(BackendConstant.RESOURCE_DISK_WHITELIST).contains(disk)) { - return JsonResponse.error("存储磁盘参数错误"); - } - String extension = req.getExtension().toLowerCase(); - String type = BackendConstant.RESOURCE_EXT_2_TYPE.get(extension); - if (type == null) { - return JsonResponse.error("格式不支持"); - } - - // 如果是视频则必须传递duration参数 - Integer duration = req.getDuration(); - String poster = req.getPoster(); - boolean isVideoType = BackendConstant.RESOURCE_TYPE_VIDEO.equals(type); - if (isVideoType) { - if (duration == null || duration == 0) { - return JsonResponse.error("duration参数必须存在且大于0"); - } - if (poster == null || poster.trim().length() == 0) { - return JsonResponse.error("poster参数值不能为空"); - } - } - - Resource res = resourceService.create( - req.getCategoryId(), - type, req.getName(), - extension, - req.getSize(), - disk, - req.getFileId(), - req.getPath(), - req.getUrl() - ); - - if (isVideoType) { - resourceVideoService.create(res.getId(), duration, poster); - } - - return JsonResponse.data(res); - } - @DeleteMapping("/{id}") @Transactional public JsonResponse destroy(@PathVariable(name = "id") Integer id) throws NotFoundException { diff --git a/src/main/java/xyz/playedu/api/controller/backend/UploadController.java b/src/main/java/xyz/playedu/api/controller/backend/UploadController.java index 07bed25..5064665 100644 --- a/src/main/java/xyz/playedu/api/controller/backend/UploadController.java +++ b/src/main/java/xyz/playedu/api/controller/backend/UploadController.java @@ -11,12 +11,12 @@ import xyz.playedu.api.domain.Resource; import xyz.playedu.api.exception.ServiceException; import xyz.playedu.api.request.backend.UploadVideoMergeRequest; import xyz.playedu.api.service.MinioService; -import xyz.playedu.api.service.ResourceCategoryService; import xyz.playedu.api.service.ResourceService; import xyz.playedu.api.service.UploadService; import xyz.playedu.api.types.JsonResponse; import xyz.playedu.api.util.HelperUtil; + import java.util.HashMap; /** @@ -27,9 +27,6 @@ import java.util.HashMap; @Slf4j @RequestMapping("/backend/v1/upload") public class UploadController { - @Autowired - private ResourceCategoryService resourceCategoryService; - @Autowired private MinioService minioService; @@ -40,9 +37,9 @@ public class UploadController { private ResourceService resourceService; @PostMapping("/file") - public JsonResponse image(@RequestParam HashMap params, MultipartFile file) throws ServiceException { - Integer cid = MapUtils.getInteger(params, "category_id"); - Resource res = uploadService.storeMinio(file, cid); + public JsonResponse file(@RequestParam HashMap params, MultipartFile file) throws ServiceException { + String categoryIds = MapUtils.getString(params, "category_ids"); + Resource res = uploadService.storeMinio(file, categoryIds); return JsonResponse.data(res); } @@ -85,21 +82,16 @@ public class UploadController { @PostMapping("/minio/merge-video") public JsonResponse minioMergeVideo(@RequestBody @Validated UploadVideoMergeRequest req) throws ServiceException { - Integer cid = req.getCategoryId(); String type = BackendConstant.RESOURCE_EXT_2_TYPE.get(req.getExtension()); if (type == null) { return JsonResponse.error("当前格式不支持上传"); } - if (cid != null && resourceCategoryService.find(cid, type) == null) { - return JsonResponse.error("资源分类不存在"); - } - // 合并视频文件 String url = minioService.merge(req.getFilename(), req.getUploadId()); // 视频素材保存 Resource videoResource = resourceService.create( - cid, + req.getCategoryIds(), type, req.getOriginalFilename(), req.getExtension(), @@ -110,7 +102,7 @@ public class UploadController { url ); // 视频封面素材保存 - Resource posterResource = uploadService.storeBase64Image(req.getPoster(), 0); + Resource posterResource = uploadService.storeBase64Image(req.getPoster(), null); // 视频的封面素材改为[隐藏 && 属于视频的子素材] resourceService.changeParentId(posterResource.getId(), videoResource.getId()); // 视频信息 diff --git a/src/main/java/xyz/playedu/api/domain/Resource.java b/src/main/java/xyz/playedu/api/domain/Resource.java index 2dc3244..b912fed 100644 --- a/src/main/java/xyz/playedu/api/domain/Resource.java +++ b/src/main/java/xyz/playedu/api/domain/Resource.java @@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.util.Date; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; @@ -29,12 +28,6 @@ public class Resource implements Serializable { */ private String type; - /** - * 分类id - */ - @JsonProperty("category_id") - private Integer categoryId; - /** * 资源名 */ @@ -71,22 +64,16 @@ public class Resource implements Serializable { */ private String url; - /** - * - */ @JsonProperty("created_at") private Date createdAt; - /** - * 所属素材 - */ @JsonProperty("parent_id") private Integer parentId; /** * 隐藏[0:否,1:是] */ - @JsonIgnore + @JsonProperty("is_hidden") private Integer isHidden; @TableField(exist = false) @@ -106,7 +93,6 @@ public class Resource implements Serializable { Resource other = (Resource) that; return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) && (this.getType() == null ? other.getType() == null : this.getType().equals(other.getType())) - && (this.getCategoryId() == null ? other.getCategoryId() == null : this.getCategoryId().equals(other.getCategoryId())) && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName())) && (this.getExtension() == null ? other.getExtension() == null : this.getExtension().equals(other.getExtension())) && (this.getSize() == null ? other.getSize() == null : this.getSize().equals(other.getSize())) @@ -125,7 +111,6 @@ public class Resource implements Serializable { int result = 1; result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); result = prime * result + ((getType() == null) ? 0 : getType().hashCode()); - result = prime * result + ((getCategoryId() == null) ? 0 : getCategoryId().hashCode()); result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); result = prime * result + ((getExtension() == null) ? 0 : getExtension().hashCode()); result = prime * result + ((getSize() == null) ? 0 : getSize().hashCode()); @@ -147,7 +132,6 @@ public class Resource implements Serializable { sb.append("Hash = ").append(hashCode()); sb.append(", id=").append(id); sb.append(", type=").append(type); - sb.append(", categoryId=").append(categoryId); sb.append(", name=").append(name); sb.append(", extension=").append(extension); sb.append(", size=").append(size); diff --git a/src/main/java/xyz/playedu/api/domain/ResourceCategory.java b/src/main/java/xyz/playedu/api/domain/ResourceCategory.java index 096632c..daccfc1 100644 --- a/src/main/java/xyz/playedu/api/domain/ResourceCategory.java +++ b/src/main/java/xyz/playedu/api/domain/ResourceCategory.java @@ -8,6 +8,7 @@ import java.io.Serializable; import java.util.Date; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; /** @@ -24,9 +25,16 @@ public class ResourceCategory implements Serializable { private Integer id; /** - * 资源类别 + * */ - private String type; + @JsonProperty("parent_id") + private Integer parentId; + + /** + * + */ + @JsonProperty("parent_chain") + private String parentChain; /** * 分类名 @@ -66,7 +74,8 @@ public class ResourceCategory implements Serializable { } ResourceCategory other = (ResourceCategory) that; return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) - && (this.getType() == null ? other.getType() == null : this.getType().equals(other.getType())) + && (this.getParentId() == null ? other.getParentId() == null : this.getParentId().equals(other.getParentId())) + && (this.getParentChain() == null ? other.getParentChain() == null : this.getParentChain().equals(other.getParentChain())) && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName())) && (this.getSort() == null ? other.getSort() == null : this.getSort().equals(other.getSort())) && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt())) @@ -78,7 +87,8 @@ public class ResourceCategory implements Serializable { final int prime = 31; int result = 1; result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); - result = prime * result + ((getType() == null) ? 0 : getType().hashCode()); + result = prime * result + ((getParentId() == null) ? 0 : getParentId().hashCode()); + result = prime * result + ((getParentChain() == null) ? 0 : getParentChain().hashCode()); result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); result = prime * result + ((getSort() == null) ? 0 : getSort().hashCode()); result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode()); @@ -93,7 +103,8 @@ public class ResourceCategory implements Serializable { sb.append(" ["); sb.append("Hash = ").append(hashCode()); sb.append(", id=").append(id); - sb.append(", type=").append(type); + sb.append(", parentId=").append(parentId); + sb.append(", parentChain=").append(parentChain); sb.append(", name=").append(name); sb.append(", sort=").append(sort); sb.append(", createdAt=").append(createdAt); diff --git a/src/main/java/xyz/playedu/api/domain/ResourceCategoryRelation.java b/src/main/java/xyz/playedu/api/domain/ResourceCategoryRelation.java new file mode 100644 index 0000000..1a8b7b7 --- /dev/null +++ b/src/main/java/xyz/playedu/api/domain/ResourceCategoryRelation.java @@ -0,0 +1,65 @@ +package xyz.playedu.api.domain; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import lombok.Data; + +/** + * + * @TableName resource_category + */ +@TableName(value ="resource_category") +@Data +public class ResourceCategoryRelation implements Serializable { + /** + * + */ + private Integer cid; + + /** + * + */ + private Integer rid; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + ResourceCategoryRelation other = (ResourceCategoryRelation) that; + return (this.getCid() == null ? other.getCid() == null : this.getCid().equals(other.getCid())) + && (this.getRid() == null ? other.getRid() == null : this.getRid().equals(other.getRid())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getCid() == null) ? 0 : getCid().hashCode()); + result = prime * result + ((getRid() == null) ? 0 : getRid().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", cid=").append(cid); + sb.append(", rid=").append(rid); + sb.append(", serialVersionUID=").append(serialVersionUID); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/playedu/api/mapper/ResourceCategoryMapper.java b/src/main/java/xyz/playedu/api/mapper/ResourceCategoryMapper.java index a3f3cbc..d0493b9 100644 --- a/src/main/java/xyz/playedu/api/mapper/ResourceCategoryMapper.java +++ b/src/main/java/xyz/playedu/api/mapper/ResourceCategoryMapper.java @@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * @author tengteng * @description 针对表【resource_categories】的数据库操作Mapper -* @createDate 2023-02-23 09:50:18 +* @createDate 2023-03-08 16:50:54 * @Entity xyz.playedu.api.domain.ResourceCategory */ @Mapper diff --git a/src/main/java/xyz/playedu/api/mapper/ResourceCategoryRelationMapper.java b/src/main/java/xyz/playedu/api/mapper/ResourceCategoryRelationMapper.java new file mode 100644 index 0000000..b7e5730 --- /dev/null +++ b/src/main/java/xyz/playedu/api/mapper/ResourceCategoryRelationMapper.java @@ -0,0 +1,20 @@ +package xyz.playedu.api.mapper; + +import org.apache.ibatis.annotations.Mapper; +import xyz.playedu.api.domain.ResourceCategoryRelation; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author tengteng +* @description 针对表【resource_category】的数据库操作Mapper +* @createDate 2023-03-08 16:54:56 +* @Entity xyz.playedu.api.domain.ResourceCategoryRelation +*/ +@Mapper +public interface ResourceCategoryRelationMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/xyz/playedu/api/mapper/ResourceMapper.java b/src/main/java/xyz/playedu/api/mapper/ResourceMapper.java index 842976a..1b2857d 100644 --- a/src/main/java/xyz/playedu/api/mapper/ResourceMapper.java +++ b/src/main/java/xyz/playedu/api/mapper/ResourceMapper.java @@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * @author tengteng * @description 针对表【resources】的数据库操作Mapper -* @createDate 2023-03-08 13:43:00 +* @createDate 2023-03-08 16:55:59 * @Entity xyz.playedu.api.domain.Resource */ @Mapper diff --git a/src/main/java/xyz/playedu/api/request/backend/ResourceCategoryRequest.java b/src/main/java/xyz/playedu/api/request/backend/ResourceCategoryRequest.java index 2243a2c..6219a4c 100644 --- a/src/main/java/xyz/playedu/api/request/backend/ResourceCategoryRequest.java +++ b/src/main/java/xyz/playedu/api/request/backend/ResourceCategoryRequest.java @@ -1,5 +1,7 @@ package xyz.playedu.api.request.backend; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import lombok.Data; import org.hibernate.validator.constraints.Length; @@ -11,14 +13,16 @@ import org.hibernate.validator.constraints.Length; @Data public class ResourceCategoryRequest { - @NotNull(message = "资源类型不能为空") - private String type; - - @NotNull(message = "分类名不能为空") - @Length(min = 1, max = 12, message = "分类名长度在1-12个字符之间") + @NotNull(message = "name参数不存在") + @NotBlank(message = "请输入分类名") + @Length(min = 1, max = 20, message = "分类名长度在1-20个字符之间") private String name; - @NotNull(message = "请输入排序值") + @JsonProperty("parent_id") + @NotNull(message = "parent_id参数不存在") + private Integer parentId; + + @NotNull(message = "sort参数不存在") private Integer sort; } diff --git a/src/main/java/xyz/playedu/api/request/backend/UploadVideoMergeRequest.java b/src/main/java/xyz/playedu/api/request/backend/UploadVideoMergeRequest.java index e2009ec..37d182c 100644 --- a/src/main/java/xyz/playedu/api/request/backend/UploadVideoMergeRequest.java +++ b/src/main/java/xyz/playedu/api/request/backend/UploadVideoMergeRequest.java @@ -32,7 +32,8 @@ public class UploadVideoMergeRequest { @NotBlank(message = "请输入extension") private String extension; - private Integer categoryId; + @JsonProperty("category_ids") + private String categoryIds; @NotNull(message = "请上传视频封面") private String poster; diff --git a/src/main/java/xyz/playedu/api/service/ResourceCategoryService.java b/src/main/java/xyz/playedu/api/service/ResourceCategoryService.java index a6920fb..2e87249 100644 --- a/src/main/java/xyz/playedu/api/service/ResourceCategoryService.java +++ b/src/main/java/xyz/playedu/api/service/ResourceCategoryService.java @@ -13,14 +13,20 @@ import java.util.List; */ public interface ResourceCategoryService extends IService { - List getByType(String type); + List listByParentId(Integer id); - void create(String type, Integer sort, String name); + List all(); ResourceCategory findOrFail(Integer id) throws NotFoundException; - ResourceCategory find(Integer id, String type); + void deleteById(Integer id) throws NotFoundException; - void update(ResourceCategory category, Integer sort, String name); + void update(ResourceCategory category, String name, Integer parentId, Integer sort) throws NotFoundException; + + void create(String name, Integer parentId, Integer sort) throws NotFoundException; + + String childrenParentChain(ResourceCategory category); + + String compParentChain(Integer parentId) throws NotFoundException; } diff --git a/src/main/java/xyz/playedu/api/service/ResourceService.java b/src/main/java/xyz/playedu/api/service/ResourceService.java index ae6afde..253d3d6 100644 --- a/src/main/java/xyz/playedu/api/service/ResourceService.java +++ b/src/main/java/xyz/playedu/api/service/ResourceService.java @@ -6,6 +6,8 @@ import xyz.playedu.api.exception.NotFoundException; import xyz.playedu.api.types.paginate.PaginationResult; import xyz.playedu.api.types.paginate.ResourcePaginateFilter; +import java.util.List; + /** * @author tengteng * @description 针对表【resources】的数据库操作Service @@ -15,7 +17,7 @@ public interface ResourceService extends IService { PaginationResult paginate(int page, int size, ResourcePaginateFilter filter); - Resource create(Integer categoryId, String type, String filename, String ext, Long size, String disk, String fileId, String path, String url); + Resource create(String categoryIds, String type, String filename, String ext, Long size, String disk, String fileId, String path, String url); Resource findOrFail(Integer id) throws NotFoundException; diff --git a/src/main/java/xyz/playedu/api/service/UploadService.java b/src/main/java/xyz/playedu/api/service/UploadService.java index 07b9f98..7e6038c 100644 --- a/src/main/java/xyz/playedu/api/service/UploadService.java +++ b/src/main/java/xyz/playedu/api/service/UploadService.java @@ -9,7 +9,7 @@ import xyz.playedu.api.exception.ServiceException; * @create 2023/3/8 14:02 */ public interface UploadService { - Resource storeMinio(MultipartFile file, Integer categoryId) throws ServiceException; + Resource storeMinio(MultipartFile file, String categoryIds) throws ServiceException; - Resource storeBase64Image(String content,Integer categoryId) throws ServiceException; + Resource storeBase64Image(String content, String categoryIds) throws ServiceException; } diff --git a/src/main/java/xyz/playedu/api/service/impl/ResourceCategoryServiceImpl.java b/src/main/java/xyz/playedu/api/service/impl/ResourceCategoryServiceImpl.java index f518235..4a8b407 100644 --- a/src/main/java/xyz/playedu/api/service/impl/ResourceCategoryServiceImpl.java +++ b/src/main/java/xyz/playedu/api/service/impl/ResourceCategoryServiceImpl.java @@ -1,12 +1,14 @@ package xyz.playedu.api.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.transaction.annotation.Transactional; import xyz.playedu.api.domain.ResourceCategory; import xyz.playedu.api.exception.NotFoundException; import xyz.playedu.api.service.ResourceCategoryService; import xyz.playedu.api.mapper.ResourceCategoryMapper; import org.springframework.stereotype.Service; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -18,27 +20,20 @@ import java.util.List; @Service public class ResourceCategoryServiceImpl extends ServiceImpl implements ResourceCategoryService { + @Override - public List getByType(String type) { - return list(query().getWrapper().eq("type", type).orderByAsc("sort")); + public List listByParentId(Integer id) { + return list(query().getWrapper().eq("parent_id", id).orderByAsc("sort")); } @Override - public void create(String type, Integer sort, String name) { - ResourceCategory category = new ResourceCategory(); - - category.setType(type); - category.setSort(sort); - category.setName(name); - category.setCreatedAt(new Date()); - category.setUpdatedAt(new Date()); - - save(category); + public List all() { + return list(query().getWrapper().orderByAsc("sort")); } @Override public ResourceCategory findOrFail(Integer id) throws NotFoundException { - ResourceCategory category = getOne(query().getWrapper().eq("id", id)); + ResourceCategory category = getById(id); if (category == null) { throw new NotFoundException("分类不存在"); } @@ -46,18 +41,120 @@ public class ResourceCategoryServiceImpl extends ServiceImpl children = list(query().getWrapper().like("parent_chain", oldChildrenPC + "%")); + if (children.size() == 0) { + return; + } + + ArrayList updateRows = new ArrayList<>(); + for (ResourceCategory tmpResourceCategory : children) { + ResourceCategory tmpUpdateResourceCategory = new ResourceCategory(); + tmpUpdateResourceCategory.setId(tmpResourceCategory.getId()); + + // parentChain计算 + String pc = newChildrenPC; + if (!tmpResourceCategory.getParentChain().equals(oldChildrenPC)) { + pc = tmpResourceCategory.getParentChain().replaceFirst(oldChildrenPC + ",", newChildrenPC.length() == 0 ? newChildrenPC : newChildrenPC + ','); + } + tmpUpdateResourceCategory.setParentChain(pc); + + // parentId计算 + int parentId = 0; + if (pc != null && pc.length() > 0) { + String[] parentIds = pc.split(","); + parentId = Integer.parseInt(parentIds[parentIds.length - 1]); + } + tmpUpdateResourceCategory.setParentId(parentId); + + updateRows.add(tmpUpdateResourceCategory); + } + updateBatchById(updateRows); + } + + + @Override + public void create(String name, Integer parentId, Integer sort) throws NotFoundException { + String parentChain = ""; + if (parentId != 0) { + parentChain = compParentChain(parentId); + } + + ResourceCategory category = new ResourceCategory(); + category.setName(name); + category.setParentId(parentId); + category.setParentChain(parentChain); + category.setSort(sort); + category.setCreatedAt(new Date()); + category.setUpdatedAt(new Date()); + + save(category); + } + + @Override + public String childrenParentChain(ResourceCategory category) { + String prefix = category.getId() + ""; + if (category.getParentChain() != null && category.getParentChain().length() > 0) { + prefix = category.getParentChain() + "," + prefix; + } + return prefix; + } + + @Override + public String compParentChain(Integer parentId) throws NotFoundException { + String parentChain = ""; + if (parentId != 0) { + ResourceCategory parentResourceCategory = getById(parentId); + if (parentResourceCategory == null) { + throw new NotFoundException("父级分类不存在"); + } + String pc = parentResourceCategory.getParentChain(); + parentChain = pc == null || pc.length() == 0 ? parentId + "" : pc + "," + parentId; + } + return parentChain; + } + } diff --git a/src/main/java/xyz/playedu/api/service/impl/ResourceServiceImpl.java b/src/main/java/xyz/playedu/api/service/impl/ResourceServiceImpl.java index a3c4e39..f052f09 100644 --- a/src/main/java/xyz/playedu/api/service/impl/ResourceServiceImpl.java +++ b/src/main/java/xyz/playedu/api/service/impl/ResourceServiceImpl.java @@ -5,18 +5,23 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.transaction.annotation.Transactional; import xyz.playedu.api.domain.Resource; +import xyz.playedu.api.domain.ResourceCategoryRelation; import xyz.playedu.api.exception.NotFoundException; import xyz.playedu.api.service.ResourceService; import xyz.playedu.api.mapper.ResourceMapper; import org.springframework.stereotype.Service; import xyz.playedu.api.service.ResourceVideoService; +import xyz.playedu.api.service.internal.ResourceCategoryRelationService; import xyz.playedu.api.types.paginate.PaginationResult; import xyz.playedu.api.types.paginate.ResourcePaginateFilter; import java.lang.reflect.Array; +import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; /** * @author tengteng @@ -29,6 +34,9 @@ public class ResourceServiceImpl extends ServiceImpl i @Autowired private ResourceVideoService resourceVideoService; + @Autowired + private ResourceCategoryRelationService relationService; + @Override public PaginationResult paginate(int page, int size, ResourcePaginateFilter filter) { QueryWrapper wrapper = query().getWrapper().eq("is_hidden", 0); @@ -46,7 +54,7 @@ public class ResourceServiceImpl extends ServiceImpl i wrapper.eq("type", filter.getType()); } if (filter.getCategoryIds() != null && filter.getCategoryIds().length > 0) { - wrapper.in("category_id", Arrays.asList(filter.getCategoryIds())); + // todo 资源分类过滤 } String sortFiled = filter.getSortField(); @@ -74,10 +82,10 @@ public class ResourceServiceImpl extends ServiceImpl i } @Override - public Resource create(Integer categoryId, String type, String filename, String ext, Long size, String disk, String fileId, String path, String url) { + @Transactional + public Resource create(String categoryIds, String type, String filename, String ext, Long size, String disk, String fileId, String path, String url) { Resource resource = new Resource(); resource.setType(type); - resource.setCategoryId(categoryId); resource.setName(filename); resource.setExtension(ext); resource.setSize(size); @@ -87,6 +95,21 @@ public class ResourceServiceImpl extends ServiceImpl i resource.setUrl(url); resource.setCreatedAt(new Date()); save(resource); + + + if (categoryIds != null && categoryIds.trim().length() > 0) { + String[] idArray = categoryIds.split(","); + List relations = new ArrayList<>(); + for (int i = 0; i < idArray.length; i++) { + String tmpId = idArray[i]; + + relations.add(new ResourceCategoryRelation() {{ + setCid(Integer.valueOf(tmpId)); + setRid(resource.getId()); + }}); + } + relationService.saveBatch(relations); + } return resource; } diff --git a/src/main/java/xyz/playedu/api/service/impl/UploadServiceImpl.java b/src/main/java/xyz/playedu/api/service/impl/UploadServiceImpl.java index b076b7d..fe7f804 100644 --- a/src/main/java/xyz/playedu/api/service/impl/UploadServiceImpl.java +++ b/src/main/java/xyz/playedu/api/service/impl/UploadServiceImpl.java @@ -13,6 +13,8 @@ import xyz.playedu.api.service.UploadService; import xyz.playedu.api.util.Base64Util; import xyz.playedu.api.util.HelperUtil; +import java.util.List; + /** * @Author 杭州白书科技有限公司 * @create 2023/3/8 14:02 @@ -20,9 +22,6 @@ import xyz.playedu.api.util.HelperUtil; @Service public class UploadServiceImpl implements UploadService { - @Autowired - private ResourceCategoryService resourceCategoryService; - @Autowired private ResourceService resourceService; @@ -30,7 +29,7 @@ public class UploadServiceImpl implements UploadService { private MinioService minioService; @Override - public Resource storeMinio(MultipartFile file, Integer cid) throws ServiceException { + public Resource storeMinio(MultipartFile file, String categoryIds) throws ServiceException { if (file == null || file.isEmpty() || file.getOriginalFilename() == null) { throw new ServiceException("请上传文件"); } @@ -50,11 +49,6 @@ public class UploadServiceImpl implements UploadService { throw new ServiceException("格式不支持"); } - // 分类校验 - if (cid != null && !cid.equals(0) && resourceCategoryService.find(cid, type) == null) { - throw new ServiceException("分类不存在"); - } - // 上传原文件的文件名 String oFilename = filename.replaceAll("." + ext, ""); // 自定义新的存储文件名 @@ -64,17 +58,22 @@ public class UploadServiceImpl implements UploadService { // 保存文件 String url = minioService.saveFile(file, savePath, contentType); // 上传记录 - return resourceService.create(cid, type, oFilename, ext, file.getSize(), BackendConstant.STORAGE_DRIVER_MINIO, "", savePath, url); + return resourceService.create(categoryIds, type, oFilename, ext, file.getSize(), BackendConstant.STORAGE_DRIVER_MINIO, "", savePath, url); } @Override - public Resource storeBase64Image(String content, Integer categoryId) throws ServiceException { + public Resource storeBase64Image(String content, String categoryIds) throws ServiceException { // data:image/jpeg;base64, String[] base64Rows = content.split(","); + // 解析出content-type String contentType = base64Rows[0].replaceAll("data:", "").replaceAll(";base64", "").toLowerCase(); + // 解析出文件格式 String ext = contentType.replaceAll("image/", ""); + // 通过文件格式解析资源类型 String type = BackendConstant.RESOURCE_EXT_2_TYPE.get(ext); + // 通过资源类型获取安全的content-type String safeContentType = BackendConstant.RESOURCE_EXT_2_CONTENT_TYPE.get(ext); + // 资源类型必须存在 && 安全的 content-type 必须存在 且与解析出来的 content-type 一致 if (type == null || safeContentType == null || !safeContentType.equals(contentType)) { throw new ServiceException("格式不支持"); } @@ -86,6 +85,6 @@ public class UploadServiceImpl implements UploadService { // 保存文件 String url = minioService.saveBytes(binary, savePath, contentType); // 上传记录 - return resourceService.create(categoryId, type, filename, ext, (long) binary.length, BackendConstant.STORAGE_DRIVER_MINIO, "", savePath, url); + return resourceService.create(categoryIds, type, filename, ext, (long) binary.length, BackendConstant.STORAGE_DRIVER_MINIO, "", savePath, url); } } diff --git a/src/main/java/xyz/playedu/api/service/impl/internal/ResourceCategoryRelationServiceImpl.java b/src/main/java/xyz/playedu/api/service/impl/internal/ResourceCategoryRelationServiceImpl.java new file mode 100644 index 0000000..ae4a087 --- /dev/null +++ b/src/main/java/xyz/playedu/api/service/impl/internal/ResourceCategoryRelationServiceImpl.java @@ -0,0 +1,22 @@ +package xyz.playedu.api.service.impl.internal; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import xyz.playedu.api.domain.ResourceCategoryRelation; +import xyz.playedu.api.service.internal.ResourceCategoryRelationService; +import xyz.playedu.api.mapper.ResourceCategoryRelationMapper; +import org.springframework.stereotype.Service; + +/** +* @author tengteng +* @description 针对表【resource_category】的数据库操作Service实现 +* @createDate 2023-03-08 16:54:56 +*/ +@Service +public class ResourceCategoryRelationServiceImpl extends ServiceImpl + implements ResourceCategoryRelationService{ + +} + + + + diff --git a/src/main/java/xyz/playedu/api/service/internal/ResourceCategoryRelationService.java b/src/main/java/xyz/playedu/api/service/internal/ResourceCategoryRelationService.java new file mode 100644 index 0000000..36b66b9 --- /dev/null +++ b/src/main/java/xyz/playedu/api/service/internal/ResourceCategoryRelationService.java @@ -0,0 +1,13 @@ +package xyz.playedu.api.service.internal; + +import xyz.playedu.api.domain.ResourceCategoryRelation; +import com.baomidou.mybatisplus.extension.service.IService; + +/** +* @author tengteng +* @description 针对表【resource_category】的数据库操作Service +* @createDate 2023-03-08 16:54:56 +*/ +public interface ResourceCategoryRelationService extends IService { + +} diff --git a/src/main/resources/mapper/ResourceCategoryMapper.xml b/src/main/resources/mapper/ResourceCategoryMapper.xml index 5a85527..888eb87 100644 --- a/src/main/resources/mapper/ResourceCategoryMapper.xml +++ b/src/main/resources/mapper/ResourceCategoryMapper.xml @@ -6,7 +6,8 @@ - + + @@ -14,7 +15,8 @@ - id,type,name, - sort,created_at,updated_at + id,parent_id,parent_chain, + name,sort,created_at, + updated_at diff --git a/src/main/resources/mapper/ResourceCategoryRelationMapper.xml b/src/main/resources/mapper/ResourceCategoryRelationMapper.xml new file mode 100644 index 0000000..c5ce37f --- /dev/null +++ b/src/main/resources/mapper/ResourceCategoryRelationMapper.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + cid,rid + + diff --git a/src/main/resources/mapper/ResourceMapper.xml b/src/main/resources/mapper/ResourceMapper.xml index 41a20c8..1712aff 100644 --- a/src/main/resources/mapper/ResourceMapper.xml +++ b/src/main/resources/mapper/ResourceMapper.xml @@ -7,7 +7,6 @@ - @@ -21,10 +20,9 @@ - id,type,category_id, - name,extension,size, - disk,file_id,path, - url,created_at,parent_id, - is_hidden + id,type,name, + extension,size,disk, + file_id,path,url, + created_at,parent_id,is_hidden