3.25 空间模块 增删查改基础代码
This commit is contained in:
parent
1026b764dd
commit
c2d8391166
@ -62,3 +62,31 @@ ALTER TABLE picture
|
||||
-- 添加新列
|
||||
ADD COLUMN original_url varchar(512) NULL COMMENT '原图 url',
|
||||
ADD COLUMN thumbnail_url varchar(512) NULL COMMENT '缩略图 url';
|
||||
|
||||
-- 空间表
|
||||
create table if not exists space
|
||||
(
|
||||
id bigint auto_increment comment 'id' primary key,
|
||||
space_name varchar(128) null comment '空间名称',
|
||||
space_level int default 0 null comment '空间级别:0-普通版 1-专业版 2-旗舰版',
|
||||
max_size bigint default 0 null comment '空间图片的最大总大小',
|
||||
max_count bigint default 0 null comment '空间图片的最大数量',
|
||||
total_size bigint default 0 null comment '当前空间下图片的总大小',
|
||||
total_count bigint default 0 null comment '当前空间下的图片数量',
|
||||
user_id bigint not null comment '创建用户 id',
|
||||
create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
|
||||
edit_time datetime default CURRENT_TIMESTAMP not null comment '编辑时间',
|
||||
update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
|
||||
is_delete tinyint default 0 not null comment '是否删除',
|
||||
-- 索引设计
|
||||
index idx_userId (user_id), -- 提升基于用户的查询效率
|
||||
index idx_spaceName (space_name), -- 提升基于空间名称的查询效率
|
||||
index idx_spaceLevel (space_level) -- 提升按空间级别查询的效率
|
||||
) comment '空间' collate = utf8mb4_unicode_ci;
|
||||
|
||||
-- 添加新列
|
||||
ALTER TABLE picture
|
||||
ADD COLUMN space_id bigint null comment '空间 id(为空表示公共空间)';
|
||||
|
||||
-- 创建索引
|
||||
CREATE INDEX idx_spaceId ON picture (space_id);
|
@ -84,6 +84,19 @@ public class PictureController {
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑图片(给用户使用)或创建图片时,编辑标签、分类的时候
|
||||
*/
|
||||
@PostMapping("/edit")
|
||||
public BaseResponse<Boolean> editPicture(@RequestBody PictureEditRequest pictureEditRequest, HttpServletRequest request) {
|
||||
if (pictureEditRequest == null || pictureEditRequest.getId() <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
User loginUser = userService.getLoginUser(request);
|
||||
pictureService.editPicture(pictureEditRequest, loginUser);
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新图片(仅管理员可用)
|
||||
*
|
||||
@ -196,18 +209,6 @@ public class PictureController {
|
||||
return ResultUtils.success(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑图片(给用户使用)或创建图片时,编辑标签、分类的时候
|
||||
*/
|
||||
@PostMapping("/edit")
|
||||
public BaseResponse<Boolean> editPicture(@RequestBody PictureEditRequest pictureEditRequest, HttpServletRequest request) {
|
||||
if (pictureEditRequest == null || pictureEditRequest.getId() <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
User loginUser = userService.getLoginUser(request);
|
||||
pictureService.editPicture(pictureEditRequest, loginUser);
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/tag_category")
|
||||
public BaseResponse<PictureTagCategory> listPictureTagCategory() {
|
||||
|
@ -0,0 +1,190 @@
|
||||
package edu.whut.smilepicturebackend.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import edu.whut.smilepicturebackend.annotation.AuthCheck;
|
||||
import edu.whut.smilepicturebackend.common.BaseResponse;
|
||||
import edu.whut.smilepicturebackend.common.DeleteRequest;
|
||||
import edu.whut.smilepicturebackend.common.ResultUtils;
|
||||
import edu.whut.smilepicturebackend.constant.UserConstant;
|
||||
import edu.whut.smilepicturebackend.exception.BusinessException;
|
||||
import edu.whut.smilepicturebackend.exception.ErrorCode;
|
||||
import edu.whut.smilepicturebackend.exception.ThrowUtils;
|
||||
import edu.whut.smilepicturebackend.model.dto.space.*;
|
||||
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.enums.SpaceLevelEnum;
|
||||
import edu.whut.smilepicturebackend.model.vo.SpaceVO;
|
||||
import edu.whut.smilepicturebackend.service.SpaceService;
|
||||
import edu.whut.smilepicturebackend.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 程序员鱼皮 <a href="https://www.codefather.cn">编程导航原创项目</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/space")
|
||||
public class SpaceController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
private final SpaceService spaceService;
|
||||
|
||||
|
||||
@PostMapping("/add")
|
||||
public BaseResponse<Long> addSpace(@RequestBody SpaceAddRequest spaceAddRequest, HttpServletRequest request) {
|
||||
ThrowUtils.throwIf(spaceAddRequest == null, ErrorCode.PARAMS_ERROR);
|
||||
User loginUser = userService.getLoginUser(request);
|
||||
long newId = spaceService.addSpace(spaceAddRequest, loginUser);
|
||||
return ResultUtils.success(newId);
|
||||
}
|
||||
|
||||
@PostMapping("/delete")
|
||||
public BaseResponse<Boolean> deleteSpace(@RequestBody DeleteRequest deleteRequest
|
||||
, HttpServletRequest request) {
|
||||
if (deleteRequest == null || deleteRequest.getId() <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
User loginUser = userService.getLoginUser(request);
|
||||
Long id = deleteRequest.getId();
|
||||
// 判断是否存在
|
||||
Space oldSpace = spaceService.getById(id);
|
||||
ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
// 仅本人或者管理员可删除
|
||||
spaceService.checkSpaceAuth(loginUser, oldSpace);
|
||||
// 操作数据库
|
||||
boolean result = spaceService.removeById(id);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新空间(仅管理员可用)
|
||||
*
|
||||
* @param spaceUpdateRequest
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||
public BaseResponse<Boolean> updateSpace(@RequestBody SpaceUpdateRequest spaceUpdateRequest,
|
||||
HttpServletRequest request) {
|
||||
if (spaceUpdateRequest == null || spaceUpdateRequest.getId() <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
// 将实体类和 DTO 进行转换
|
||||
Space space = new Space();
|
||||
BeanUtils.copyProperties(spaceUpdateRequest, space);
|
||||
// 自动填充数据
|
||||
spaceService.fillSpaceBySpaceLevel(space);
|
||||
// 数据校验
|
||||
spaceService.validSpace(space, false); //不是新增时的操作
|
||||
// 判断是否存在
|
||||
long id = spaceUpdateRequest.getId();
|
||||
Space oldSpace = spaceService.getById(id);
|
||||
ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
// 操作数据库
|
||||
boolean result = spaceService.updateById(space);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 id 获取空间(仅管理员可用)
|
||||
*/
|
||||
@GetMapping("/get")
|
||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||
public BaseResponse<Space> getSpaceById(long id, HttpServletRequest request) {
|
||||
ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
|
||||
// 查询数据库
|
||||
Space space = spaceService.getById(id);
|
||||
ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
// 获取封装类
|
||||
return ResultUtils.success(space);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 id 获取空间(封装类)
|
||||
*/
|
||||
@GetMapping("/get/vo")
|
||||
public BaseResponse<SpaceVO> getSpaceVOById(long id, HttpServletRequest request) {
|
||||
ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
|
||||
// 查询数据库
|
||||
Space space = spaceService.getById(id);
|
||||
ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
return ResultUtils.success(spaceService.getSpaceVO(space,request));
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页获取空间列表(仅管理员可用)
|
||||
*/
|
||||
@PostMapping("/list/page")
|
||||
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
|
||||
public BaseResponse<Page<Space>> listSpaceByPage(@RequestBody SpaceQueryRequest spaceQueryRequest) {
|
||||
long current = spaceQueryRequest.getCurrent();
|
||||
long size = spaceQueryRequest.getPageSize();
|
||||
// 查询数据库
|
||||
Page<Space> spacePage = spaceService.page(new Page<>(current, size),
|
||||
spaceService.getQueryWrapper(spaceQueryRequest));
|
||||
return ResultUtils.success(spacePage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页获取空间列表(封装类) 用户使用
|
||||
*/
|
||||
@PostMapping("/list/page/vo")
|
||||
public BaseResponse<Page<SpaceVO>> listSpaceVOByPage(@RequestBody SpaceQueryRequest spaceQueryRequest,
|
||||
HttpServletRequest request) {
|
||||
long current = spaceQueryRequest.getCurrent();
|
||||
long size = spaceQueryRequest.getPageSize();
|
||||
// 限制爬虫
|
||||
ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
|
||||
// 查询数据库
|
||||
Page<Space> spacePage = spaceService.page(new Page<>(current, size),
|
||||
spaceService.getQueryWrapper(spaceQueryRequest));
|
||||
// 获取封装类
|
||||
return ResultUtils.success(spaceService.getSpaceVOPage(spacePage, request));
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑空间(给用户使用)
|
||||
*/
|
||||
@PostMapping("/edit")
|
||||
public BaseResponse<Boolean> editSpace(@RequestBody SpaceEditRequest spaceEditRequest, HttpServletRequest request) {
|
||||
if (spaceEditRequest == null || spaceEditRequest.getId() <= 0) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR);
|
||||
}
|
||||
// 在此处将实体类和 DTO 进行转换
|
||||
Space space = new Space();
|
||||
BeanUtils.copyProperties(spaceEditRequest, space);
|
||||
// 自动填充数据
|
||||
spaceService.fillSpaceBySpaceLevel(space);
|
||||
// 设置编辑时间
|
||||
space.setEditTime(new Date());
|
||||
// 数据校验
|
||||
spaceService.validSpace(space, false);
|
||||
User loginUser = userService.getLoginUser(request);
|
||||
// 判断是否存在
|
||||
long id = spaceEditRequest.getId();
|
||||
Space oldSpace = spaceService.getById(id);
|
||||
ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
// 仅本人或管理员可编辑
|
||||
spaceService.checkSpaceAuth(loginUser, oldSpace);
|
||||
// 操作数据库
|
||||
boolean result = spaceService.updateById(space);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||
return ResultUtils.success(true);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package edu.whut.smilepicturebackend.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||
|
||||
/**
|
||||
* @author 张三
|
||||
* @description 针对表【space(空间)】的数据库操作Mapper
|
||||
* @createDate 2025-06-16 16:49:09
|
||||
* @Entity generator.domain.Space
|
||||
*/
|
||||
public interface SpaceMapper extends BaseMapper<Space> {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -27,5 +27,10 @@ public class PictureUploadRequest implements Serializable {
|
||||
*/
|
||||
private String picName;
|
||||
|
||||
/**
|
||||
* 空间 id
|
||||
*/
|
||||
private Long spaceId;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
package edu.whut.smilepicturebackend.model.dto.space;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 创建空间请求
|
||||
*/
|
||||
@Data
|
||||
public class SpaceAddRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* 空间名称
|
||||
*/
|
||||
private String spaceName;
|
||||
|
||||
/**
|
||||
* 空间级别:0-普通版 1-专业版 2-旗舰版
|
||||
*/
|
||||
private Integer spaceLevel;
|
||||
|
||||
/**
|
||||
* 空间类型:0-私有 1-团队
|
||||
*/
|
||||
private Integer spaceType;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package edu.whut.smilepicturebackend.model.dto.space;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 编辑空间请求
|
||||
*/
|
||||
@Data
|
||||
public class SpaceEditRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* 空间 id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 空间名称
|
||||
*/
|
||||
private String spaceName;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package edu.whut.smilepicturebackend.model.dto.space;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 空间级别
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class SpaceLevel {
|
||||
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private int value;
|
||||
|
||||
/**
|
||||
* 中文
|
||||
*/
|
||||
private String text;
|
||||
|
||||
/**
|
||||
* 最大数量
|
||||
*/
|
||||
private long maxCount;
|
||||
|
||||
/**
|
||||
* 最大容量
|
||||
*/
|
||||
private long maxSize;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package edu.whut.smilepicturebackend.model.dto.space;
|
||||
|
||||
import edu.whut.smilepicturebackend.common.PageRequest;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 查询空间请求
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class SpaceQueryRequest extends PageRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 用户 id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 空间名称
|
||||
*/
|
||||
private String spaceName;
|
||||
|
||||
/**
|
||||
* 空间级别:0-普通版 1-专业版 2-旗舰版
|
||||
*/
|
||||
private Integer spaceLevel;
|
||||
|
||||
/**
|
||||
* 空间类型:0-私有 1-团队
|
||||
*/
|
||||
private Integer spaceType;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package edu.whut.smilepicturebackend.model.dto.space;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 更新空间请求
|
||||
*/
|
||||
@Data
|
||||
public class SpaceUpdateRequest implements Serializable {
|
||||
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 空间名称
|
||||
*/
|
||||
private String spaceName;
|
||||
|
||||
/**
|
||||
* 空间级别:0-普通版 1-专业版 2-旗舰版
|
||||
*/
|
||||
private Integer spaceLevel;
|
||||
|
||||
/**
|
||||
* 空间图片的最大总大小
|
||||
*/
|
||||
private Long maxSize;
|
||||
|
||||
/**
|
||||
* 空间图片的最大数量
|
||||
*/
|
||||
private Long maxCount;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -84,6 +84,11 @@ public class Picture implements Serializable {
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 空间 id
|
||||
*/
|
||||
private Long spaceId;
|
||||
|
||||
/**
|
||||
* 审核状态:0-待审核; 1-通过; 2-拒绝
|
||||
*/
|
||||
|
@ -0,0 +1,80 @@
|
||||
package edu.whut.smilepicturebackend.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 空间
|
||||
* @TableName space
|
||||
*/
|
||||
@TableName(value ="space")
|
||||
@Data
|
||||
public class Space implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 空间名称
|
||||
*/
|
||||
private String spaceName;
|
||||
|
||||
/**
|
||||
* 空间级别:0-普通版 1-专业版 2-旗舰版
|
||||
*/
|
||||
private Integer spaceLevel;
|
||||
|
||||
/**
|
||||
* 空间图片的最大总大小
|
||||
*/
|
||||
private Long maxSize;
|
||||
|
||||
/**
|
||||
* 空间图片的最大数量
|
||||
*/
|
||||
private Long maxCount;
|
||||
|
||||
/**
|
||||
* 当前空间下图片的总大小
|
||||
*/
|
||||
private Long totalSize;
|
||||
|
||||
/**
|
||||
* 当前空间下的图片数量
|
||||
*/
|
||||
private Long totalCount;
|
||||
|
||||
/**
|
||||
* 创建用户 id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 编辑时间
|
||||
*/
|
||||
private Date editTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 是否删除
|
||||
*/
|
||||
@TableLogic
|
||||
private Integer isDelete;
|
||||
|
||||
@TableField(exist = false)
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package edu.whut.smilepicturebackend.model.enums;
|
||||
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 空间级别枚举
|
||||
*/
|
||||
@Getter
|
||||
public enum SpaceLevelEnum {
|
||||
|
||||
COMMON("普通版", 0, 100, 100L * 1024 * 1024),
|
||||
PROFESSIONAL("专业版", 1, 1000, 1000L * 1024 * 1024),
|
||||
FLAGSHIP("旗舰版", 2, 10000, 10000L * 1024 * 1024);
|
||||
|
||||
private final String text;
|
||||
|
||||
private final int value;
|
||||
|
||||
private final long maxCount;
|
||||
|
||||
private final long maxSize;
|
||||
|
||||
|
||||
/**
|
||||
* @param text 文本
|
||||
* @param value 值
|
||||
* @param maxSize 最大图片总大小
|
||||
* @param maxCount 最大图片总数量
|
||||
*/
|
||||
SpaceLevelEnum(String text, int value, long maxCount, long maxSize) {
|
||||
this.text = text;
|
||||
this.value = value;
|
||||
this.maxCount = maxCount;
|
||||
this.maxSize = maxSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 value 获取枚举
|
||||
*/
|
||||
public static SpaceLevelEnum getEnumByValue(Integer value) {
|
||||
if (ObjUtil.isEmpty(value)) {
|
||||
return null;
|
||||
}
|
||||
for (SpaceLevelEnum spaceLevelEnum : SpaceLevelEnum.values()) {
|
||||
if (spaceLevelEnum.value == value) {
|
||||
return spaceLevelEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
117
src/main/java/edu/whut/smilepicturebackend/model/vo/SpaceVO.java
Normal file
117
src/main/java/edu/whut/smilepicturebackend/model/vo/SpaceVO.java
Normal file
@ -0,0 +1,117 @@
|
||||
package edu.whut.smilepicturebackend.model.vo;
|
||||
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 空间视图
|
||||
*/
|
||||
@Data
|
||||
public class SpaceVO implements Serializable {
|
||||
/**
|
||||
* id
|
||||
*/
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 空间名称
|
||||
*/
|
||||
private String spaceName;
|
||||
|
||||
/**
|
||||
* 空间级别:0-普通版 1-专业版 2-旗舰版
|
||||
*/
|
||||
private Integer spaceLevel;
|
||||
|
||||
/**
|
||||
* 空间类型:0-私有 1-团队
|
||||
*/
|
||||
private Integer spaceType;
|
||||
|
||||
/**
|
||||
* 空间图片的最大总大小
|
||||
*/
|
||||
private Long maxSize;
|
||||
|
||||
/**
|
||||
* 空间图片的最大数量
|
||||
*/
|
||||
private Long maxCount;
|
||||
|
||||
/**
|
||||
* 当前空间下图片的总大小
|
||||
*/
|
||||
private Long totalSize;
|
||||
|
||||
/**
|
||||
* 当前空间下的图片数量
|
||||
*/
|
||||
private Long totalCount;
|
||||
|
||||
/**
|
||||
* 创建用户 id
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 编辑时间
|
||||
*/
|
||||
private Date editTime;
|
||||
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
private Date updateTime;
|
||||
|
||||
/**
|
||||
* 创建用户信息
|
||||
*/
|
||||
private UserVO user;
|
||||
|
||||
/**
|
||||
* 权限列表
|
||||
*/
|
||||
private List<String> permissionList = new ArrayList<>();
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 封装类转对象
|
||||
*
|
||||
* @param spaceVO
|
||||
* @return
|
||||
*/
|
||||
public static Space voToObj(SpaceVO spaceVO) {
|
||||
if (spaceVO == null) {
|
||||
return null;
|
||||
}
|
||||
Space space = new Space();
|
||||
BeanUtils.copyProperties(spaceVO, space);
|
||||
return space;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象转封装类
|
||||
*
|
||||
* @param space
|
||||
* @return
|
||||
*/
|
||||
public static SpaceVO objToVo(Space space) {
|
||||
if (space == null) {
|
||||
return null;
|
||||
}
|
||||
SpaceVO spaceVO = new SpaceVO();
|
||||
BeanUtils.copyProperties(space, spaceVO);
|
||||
return spaceVO;
|
||||
}
|
||||
}
|
@ -118,4 +118,6 @@ public interface PictureService extends IService<Picture> {
|
||||
* @param oldPicture
|
||||
*/
|
||||
void clearPictureFile(Picture oldPicture);
|
||||
|
||||
void checkPictureAuth(User loginUser, Picture picture);
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
package edu.whut.smilepicturebackend.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import edu.whut.smilepicturebackend.model.dto.space.SpaceAddRequest;
|
||||
import edu.whut.smilepicturebackend.model.dto.space.SpaceQueryRequest;
|
||||
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.vo.SpaceVO;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* @author 张三
|
||||
* @description 针对表【space(空间)】的数据库操作Service
|
||||
* @createDate 2025-06-16 16:49:09
|
||||
*/
|
||||
public interface SpaceService extends IService<Space> {
|
||||
/**
|
||||
* 创建空间
|
||||
*
|
||||
* @param spaceAddRequest
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
long addSpace(SpaceAddRequest spaceAddRequest, User loginUser);
|
||||
|
||||
/**
|
||||
* 校验空间
|
||||
*
|
||||
* @param space
|
||||
* @param add 是否为创建时检验
|
||||
*/
|
||||
void validSpace(Space space, boolean add);
|
||||
|
||||
/**
|
||||
* 获取空间包装类(单条)
|
||||
*
|
||||
* @param space
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
SpaceVO getSpaceVO(Space space, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获取空间包装类(分页)
|
||||
*
|
||||
* @param spacePage
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
Page<SpaceVO> getSpaceVOPage(Page<Space> spacePage, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 获取查询对象
|
||||
*
|
||||
* @param spaceQueryRequest
|
||||
* @return
|
||||
*/
|
||||
LambdaQueryWrapper<Space> getQueryWrapper(SpaceQueryRequest spaceQueryRequest);
|
||||
|
||||
/**
|
||||
* 根据空间级别填充空间对象
|
||||
*
|
||||
* @param space
|
||||
*/
|
||||
void fillSpaceBySpaceLevel(Space space);
|
||||
|
||||
/**
|
||||
* 校验空间权限
|
||||
*
|
||||
* @param loginUser
|
||||
* @param space
|
||||
*/
|
||||
void checkSpaceAuth(User loginUser, Space space);
|
||||
}
|
@ -5,7 +5,6 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSON;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
@ -24,12 +23,14 @@ import edu.whut.smilepicturebackend.manager.upload.UrlPictureUpload;
|
||||
import edu.whut.smilepicturebackend.mapper.PictureMapper;
|
||||
import edu.whut.smilepicturebackend.model.dto.picture.*;
|
||||
import edu.whut.smilepicturebackend.model.entity.Picture;
|
||||
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.enums.PictureReviewStatusEnum;
|
||||
import edu.whut.smilepicturebackend.model.file.UploadPictureResult;
|
||||
import edu.whut.smilepicturebackend.model.vo.PictureVO;
|
||||
import edu.whut.smilepicturebackend.model.vo.UserVO;
|
||||
import edu.whut.smilepicturebackend.service.PictureService;
|
||||
import edu.whut.smilepicturebackend.service.SpaceService;
|
||||
import edu.whut.smilepicturebackend.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@ -40,7 +41,6 @@ import org.jsoup.select.Elements;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
|
||||
@ -68,6 +68,7 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
private final UrlPictureUpload urlPictureUpload;
|
||||
private final MyCacheManager cacheManager;
|
||||
private final CosManager cosManager;
|
||||
private final SpaceService spaceService;
|
||||
@Override
|
||||
public void validPicture(Picture picture) {
|
||||
ThrowUtils.throwIf(picture == null, ErrorCode.PARAMS_ERROR);
|
||||
@ -90,7 +91,17 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
public PictureVO uploadPicture(Object inputSource, PictureUploadRequest pictureUploadRequest, User loginUser) {
|
||||
// 校验参数
|
||||
ThrowUtils.throwIf(loginUser == null, ErrorCode.NO_AUTH_ERROR);
|
||||
|
||||
// 校验空间是否存在
|
||||
Long spaceId = pictureUploadRequest.getSpaceId();
|
||||
if (spaceId != null) {
|
||||
Space space = spaceService.getById(spaceId);
|
||||
ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
|
||||
// 改为使用统一的权限校验
|
||||
// 校验是否有空间的权限,仅空间管理员才能上传
|
||||
if (!loginUser.getId().equals(space.getUserId())) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "没有空间权限");
|
||||
}
|
||||
}
|
||||
// 判断是创建还是替换
|
||||
Long pictureId = pictureUploadRequest == null ? null : pictureUploadRequest.getId();
|
||||
Picture oldPicture = null;
|
||||
@ -103,11 +114,29 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
if (!oldPicture.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
// 校验空间是否一致
|
||||
// 没传 spaceId,则复用原有图片的 spaceId(这样也兼容了公共图库)
|
||||
if (spaceId == null) {
|
||||
if (oldPicture.getSpaceId() != null) {
|
||||
spaceId = oldPicture.getSpaceId();
|
||||
}
|
||||
} else {
|
||||
// 传了 spaceId,必须和原图片的空间 id 一致
|
||||
if (ObjUtil.notEqual(spaceId, oldPicture.getSpaceId())) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间 id 不一致");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 上传图片,得到图片信息
|
||||
// 按照用户 id 划分目录 => 按照空间划分目录
|
||||
String uploadPathPrefix;
|
||||
//公共图库下,每个用户有自己的userid管理的文件夹。
|
||||
uploadPathPrefix = String.format("public/%s", loginUser.getId());
|
||||
if (spaceId == null) {
|
||||
// 公共图库+用户id
|
||||
uploadPathPrefix = String.format("public/%s", loginUser.getId());
|
||||
} else {
|
||||
// 私人空间+空间id
|
||||
uploadPathPrefix = String.format("space/%s", spaceId);
|
||||
}
|
||||
// 根据 inputSource 的类型区分上传方式!!
|
||||
PictureUploadTemplate pictureUploadTemplate = filePictureUpload;
|
||||
if (inputSource instanceof String) {
|
||||
@ -127,6 +156,7 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
)
|
||||
);
|
||||
picture.setUserId(loginUser.getId());
|
||||
picture.setSpaceId(spaceId);
|
||||
// 补充审核参数
|
||||
this.fillReviewParams(picture, loginUser);
|
||||
// 操作数据库
|
||||
@ -204,6 +234,8 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
&& !userService.isAdmin(loginUser)) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
// 校验权限
|
||||
checkPictureAuth(loginUser, oldPicture);
|
||||
// 操作数据库
|
||||
boolean result = this.removeById(pictureId);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||
@ -211,6 +243,30 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
this.clearPictureFile(oldPicture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editPicture(PictureEditRequest pictureEditRequest, User loginUser) {
|
||||
// 在此处将实体类和 DTO 进行转换
|
||||
Picture picture = new Picture();
|
||||
BeanUtils.copyProperties(pictureEditRequest, picture);
|
||||
// 注意将 list 转为 string
|
||||
picture.setTags(JSONUtil.toJsonStr(pictureEditRequest.getTags()));
|
||||
// 设置编辑时间
|
||||
picture.setEditTime(new Date());
|
||||
// 数据校验
|
||||
this.validPicture(picture);
|
||||
// 判断是否存在
|
||||
long id = pictureEditRequest.getId();
|
||||
Picture oldPicture = this.getById(id);
|
||||
ThrowUtils.throwIf(oldPicture == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
// 校验权限
|
||||
checkPictureAuth(loginUser, oldPicture);
|
||||
// 补充审核参数,每次编辑图片都要重新过审
|
||||
this.fillReviewParams(picture, loginUser);
|
||||
// 操作数据库
|
||||
boolean result = this.updateById(picture);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PictureVO getPictureVO(Picture picture, HttpServletRequest request) {
|
||||
// 对象转封装类
|
||||
@ -261,32 +317,6 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
return pictureVOPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void editPicture(PictureEditRequest pictureEditRequest, User loginUser) {
|
||||
// 在此处将实体类和 DTO 进行转换
|
||||
Picture picture = new Picture();
|
||||
BeanUtils.copyProperties(pictureEditRequest, picture);
|
||||
// 注意将 list 转为 string
|
||||
picture.setTags(JSONUtil.toJsonStr(pictureEditRequest.getTags()));
|
||||
// 设置编辑时间
|
||||
picture.setEditTime(new Date());
|
||||
// 数据校验
|
||||
this.validPicture(picture);
|
||||
// 补充审核参数,每次编辑图片都要重新过审
|
||||
this.fillReviewParams(picture, loginUser);
|
||||
// 判断是否存在
|
||||
long id = pictureEditRequest.getId();
|
||||
Picture oldPicture = this.getById(id);
|
||||
ThrowUtils.throwIf(oldPicture == null, ErrorCode.NOT_FOUND_ERROR);
|
||||
// 校验权限,仅本人及管理员可编辑
|
||||
if(!oldPicture.getUserId().equals(loginUser.getId())&&!userService.isAdmin(loginUser))
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
|
||||
|
||||
// 操作数据库
|
||||
boolean result = this.updateById(picture);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doPictureReview(PictureReviewRequest pictureReviewRequest, User loginUser) {
|
||||
// 1. 校验参数
|
||||
@ -458,9 +488,23 @@ public class PictureServiceImpl extends ServiceImpl<PictureMapper, Picture>
|
||||
// 删除缩略图
|
||||
String thumbnailUrl = oldPicture.getThumbnailUrl();
|
||||
cosManager.deleteIfNotBlank(thumbnailUrl);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkPictureAuth(User loginUser, Picture picture) {
|
||||
Long spaceId = picture.getSpaceId();
|
||||
Long loginUserId = loginUser.getId();
|
||||
if (spaceId == null) {
|
||||
// 公共图库,仅本人或管理员可操作
|
||||
if (!picture.getUserId().equals(loginUserId) && !userService.isAdmin(loginUser)) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
} else {
|
||||
// 私有空间,仅空间管理员可操作
|
||||
if (!picture.getUserId().equals(loginUserId)) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,233 @@
|
||||
package edu.whut.smilepicturebackend.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import edu.whut.smilepicturebackend.exception.BusinessException;
|
||||
import edu.whut.smilepicturebackend.exception.ErrorCode;
|
||||
import edu.whut.smilepicturebackend.exception.ThrowUtils;
|
||||
import edu.whut.smilepicturebackend.mapper.SpaceMapper;
|
||||
|
||||
import edu.whut.smilepicturebackend.model.dto.space.SpaceAddRequest;
|
||||
import edu.whut.smilepicturebackend.model.dto.space.SpaceQueryRequest;
|
||||
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||
import edu.whut.smilepicturebackend.model.entity.User;
|
||||
import edu.whut.smilepicturebackend.model.enums.SpaceLevelEnum;
|
||||
import edu.whut.smilepicturebackend.model.vo.SpaceVO;
|
||||
import edu.whut.smilepicturebackend.model.vo.UserVO;
|
||||
import edu.whut.smilepicturebackend.service.SpaceService;
|
||||
import edu.whut.smilepicturebackend.service.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author 张三
|
||||
* @description 针对表【space(空间)】的数据库操作Service实现
|
||||
* @createDate 2025-06-16 16:49:09
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SpaceServiceImpl extends ServiceImpl<SpaceMapper, Space>
|
||||
implements SpaceService {
|
||||
private final UserService userService;
|
||||
// 静态锁表,JVM 级别共享
|
||||
private static final ConcurrentHashMap<Long, Object> USER_LOCKS = new ConcurrentHashMap<>();
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
|
||||
// 为了方便部署,注释掉分表
|
||||
// @Resource
|
||||
// @Lazy
|
||||
// private DynamicShardingManager dynamicShardingManager;
|
||||
|
||||
/**
|
||||
* 创建空间 加锁和事务
|
||||
*
|
||||
* @param spaceAddRequest
|
||||
* @param loginUser
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public long addSpace(SpaceAddRequest spaceAddRequest, User loginUser) {
|
||||
// 1. 填充参数默认值
|
||||
// 转换实体类和 DTO
|
||||
Space space = new Space();
|
||||
BeanUtils.copyProperties(spaceAddRequest, space);
|
||||
if (StrUtil.isBlank(space.getSpaceName())) {
|
||||
space.setSpaceName("默认空间");
|
||||
}
|
||||
if (space.getSpaceLevel() == null) {
|
||||
space.setSpaceLevel(SpaceLevelEnum.COMMON.getValue());
|
||||
}
|
||||
// 填充容量和大小
|
||||
this.fillSpaceBySpaceLevel(space);
|
||||
// 2. 校验参数
|
||||
this.validSpace(space, true);
|
||||
// 3. 校验权限,非管理员只能创建普通级别的空间
|
||||
Long userId = loginUser.getId();
|
||||
space.setUserId(userId);
|
||||
if (SpaceLevelEnum.COMMON.getValue() != space.getSpaceLevel() && !userService.isAdmin(loginUser)) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限创建指定级别的空间");
|
||||
}
|
||||
// 4. 控制同一用户只能创建一个私有空间、以及一个团队空间
|
||||
//// 1. 获取或创建该 userId 对应的锁对象,避免使用String.intern()来定义锁,能避免常量池内容越来越多。
|
||||
Object lock = USER_LOCKS.computeIfAbsent(userId, id -> new Object());
|
||||
synchronized (lock) {
|
||||
try {
|
||||
// 2. 在事务内检查并创建空间
|
||||
Long newSpaceId = transactionTemplate.execute(status -> {
|
||||
boolean exists = this.lambdaQuery()
|
||||
.eq(Space::getUserId, userId)
|
||||
.exists();
|
||||
ThrowUtils.throwIf(exists, ErrorCode.OPERATION_ERROR, "每个用户每类空间只能创建一个");
|
||||
|
||||
boolean result = this.save(space);
|
||||
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "保存空间到数据库失败");
|
||||
|
||||
return space.getId();
|
||||
});
|
||||
return Optional.ofNullable(newSpaceId).orElse(-1L);
|
||||
} finally {
|
||||
// 3. 可选:移除锁对象,防止 Map 膨胀(仅当你确定没有并发需求时才移除)
|
||||
USER_LOCKS.remove(userId, lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validSpace(Space space, boolean add) {
|
||||
ThrowUtils.throwIf(space == null, ErrorCode.PARAMS_ERROR);
|
||||
// 从对象中取值
|
||||
String spaceName = space.getSpaceName();
|
||||
Integer spaceLevel = space.getSpaceLevel();
|
||||
SpaceLevelEnum spaceLevelEnum = SpaceLevelEnum.getEnumByValue(spaceLevel);
|
||||
|
||||
// 创建时校验
|
||||
if (add) {
|
||||
if (StrUtil.isBlank(spaceName)) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间名称不能为空");
|
||||
}
|
||||
if (spaceLevel == null) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间级别不能为空");
|
||||
}
|
||||
}
|
||||
// 修改数据时,空间名称进行校验
|
||||
if (StrUtil.isNotBlank(spaceName) && spaceName.length() > 30) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间名称过长");
|
||||
}
|
||||
// 修改数据时,空间级别进行校验
|
||||
if (spaceLevel != null && spaceLevelEnum == null) {
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "空间级别不存在");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpaceVO getSpaceVO(Space space, HttpServletRequest request) {
|
||||
// 对象转封装类
|
||||
SpaceVO spaceVO = SpaceVO.objToVo(space);
|
||||
// 关联查询用户信息
|
||||
Long userId = space.getUserId();
|
||||
if (userId != null && userId > 0) {
|
||||
User user = userService.getById(userId);
|
||||
UserVO userVO = userService.getUserVO(user);
|
||||
spaceVO.setUser(userVO);
|
||||
}
|
||||
return spaceVO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<SpaceVO> getSpaceVOPage(Page<Space> spacePage, HttpServletRequest request) {
|
||||
List<Space> spaceList = spacePage.getRecords();
|
||||
Page<SpaceVO> spaceVOPage = new Page<>(spacePage.getCurrent(), spacePage.getSize(), spacePage.getTotal());
|
||||
if (CollUtil.isEmpty(spaceList)) {
|
||||
return spaceVOPage;
|
||||
}
|
||||
// 对象列表 => 封装对象列表
|
||||
List<SpaceVO> spaceVOList = spaceList.stream()
|
||||
.map(SpaceVO::objToVo)
|
||||
.collect(Collectors.toList());
|
||||
// 1. 关联查询用户信息
|
||||
// 1,2,3,4
|
||||
Set<Long> userIdSet = spaceList.stream().map(Space::getUserId).collect(Collectors.toSet());
|
||||
// 1 => user1, 2 => user2
|
||||
Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
|
||||
.collect(Collectors.groupingBy(User::getId));
|
||||
// 2. 填充信息
|
||||
spaceVOList.forEach(spaceVO -> {
|
||||
Long userId = spaceVO.getUserId();
|
||||
User user = null;
|
||||
if (userIdUserListMap.containsKey(userId)) {
|
||||
user = userIdUserListMap.get(userId).get(0);
|
||||
}
|
||||
spaceVO.setUser(userService.getUserVO(user));
|
||||
});
|
||||
spaceVOPage.setRecords(spaceVOList);
|
||||
return spaceVOPage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapper<Space> getQueryWrapper(SpaceQueryRequest req) {
|
||||
if (req == null) {
|
||||
// 请求参数为空时,抛出异常或根据业务自行处理
|
||||
throw new BusinessException(ErrorCode.PARAMS_ERROR, "请求参数为空");
|
||||
}
|
||||
// 创建 LambdaQueryWrapper
|
||||
LambdaQueryWrapper<Space> qw = Wrappers.lambdaQuery(Space.class);
|
||||
|
||||
// 基本等值与模糊匹配
|
||||
qw.eq(ObjUtil.isNotNull(req.getId()), Space::getId, req.getId())
|
||||
.eq(ObjUtil.isNotNull(req.getUserId()), Space::getUserId, req.getUserId())
|
||||
.like(StrUtil.isNotBlank(req.getSpaceName()), Space::getSpaceName, req.getSpaceName())
|
||||
.eq(ObjUtil.isNotNull(req.getSpaceLevel()), Space::getSpaceLevel, req.getSpaceLevel());
|
||||
|
||||
// 动态排序:将驼峰字段转成下划线,再拼到 SQL 的 ORDER BY 中
|
||||
if (StrUtil.isNotBlank(req.getSortField())) {
|
||||
String column = StrUtil.toUnderlineCase(req.getSortField());
|
||||
boolean asc = "ascend".equalsIgnoreCase(req.getSortOrder());
|
||||
qw.last("ORDER BY " + column + (asc ? " ASC" : " DESC"));
|
||||
}
|
||||
return qw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillSpaceBySpaceLevel(Space space) {
|
||||
SpaceLevelEnum spaceLevelEnum = SpaceLevelEnum.getEnumByValue(space.getSpaceLevel());
|
||||
if (spaceLevelEnum != null) {
|
||||
long maxSize = spaceLevelEnum.getMaxSize();
|
||||
if (space.getMaxSize() == null) {
|
||||
space.setMaxSize(maxSize);
|
||||
}
|
||||
long maxCount = spaceLevelEnum.getMaxCount();
|
||||
if (space.getMaxCount() == null) {
|
||||
space.setMaxCount(maxCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkSpaceAuth(User loginUser, Space space) {
|
||||
// 仅本人或管理员可编辑
|
||||
if (!space.getUserId().equals(loginUser.getId()) && !userService.isAdmin(loginUser)) {
|
||||
throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -19,18 +19,24 @@
|
||||
<result property="picScale" column="pic_scale" jdbcType="DOUBLE"/>
|
||||
<result property="picFormat" column="pic_format" jdbcType="VARCHAR"/>
|
||||
<result property="userId" column="user_id" jdbcType="BIGINT"/>
|
||||
<result property="spaceId" column="space_id" jdbcType="BIGINT"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="editTime" column="edit_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
|
||||
<result property="reviewStatus" column="reviewStatus" jdbcType="INTEGER"/>
|
||||
<result property="reviewMessage" column="reviewMessage" jdbcType="VARCHAR"/>
|
||||
<result property="reviewerId" column="reviewerId" jdbcType="BIGINT"/>
|
||||
<result property="reviewTime" column="reviewTime" jdbcType="TIMESTAMP"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,url,thumbnail_url,name,
|
||||
id,url,thumbnailUrl,name,
|
||||
introduction,category,tags,
|
||||
pic_size,pic_width,pic_height,
|
||||
pic_scale,pic_format,user_id,
|
||||
create_time,edit_time,update_time,
|
||||
is_delete
|
||||
picSize,picWidth,picHeight,
|
||||
picScale,picFormat,userId,spaceId,
|
||||
createTime,editTime,updateTime,
|
||||
isDelete,reviewStatus,reviewMessage,
|
||||
reviewerId,reviewTime
|
||||
</sql>
|
||||
</mapper>
|
||||
|
28
src/main/resources/mapper/SpaceMapper.xml
Normal file
28
src/main/resources/mapper/SpaceMapper.xml
Normal file
@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="edu.whut.smilepicturebackend.mapper.SpaceMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="edu.whut.smilepicturebackend.model.entity.Space">
|
||||
<id property="id" column="id" jdbcType="BIGINT"/>
|
||||
<result property="spaceName" column="space_name" jdbcType="VARCHAR"/>
|
||||
<result property="spaceLevel" column="space_level" jdbcType="INTEGER"/>
|
||||
<result property="maxSize" column="max_size" jdbcType="BIGINT"/>
|
||||
<result property="maxCount" column="max_count" jdbcType="BIGINT"/>
|
||||
<result property="totalSize" column="total_size" jdbcType="BIGINT"/>
|
||||
<result property="totalCount" column="total_count" jdbcType="BIGINT"/>
|
||||
<result property="userId" column="user_id" jdbcType="BIGINT"/>
|
||||
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="editTime" column="edit_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
|
||||
<result property="isDelete" column="is_delete" jdbcType="TINYINT"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,space_name,space_level,
|
||||
max_size,max_count,total_size,
|
||||
total_count,user_id,create_time,
|
||||
edit_time,update_time,is_delete
|
||||
</sql>
|
||||
</mapper>
|
Loading…
x
Reference in New Issue
Block a user