4.8 图库空间使用分析:私人和公共
This commit is contained in:
parent
e40c4a975b
commit
00c871f41e
@ -0,0 +1,134 @@
|
|||||||
|
package edu.whut.smilepicturebackend.controller;
|
||||||
|
import edu.whut.smilepicturebackend.common.BaseResponse;
|
||||||
|
import edu.whut.smilepicturebackend.common.ResultUtils;
|
||||||
|
import edu.whut.smilepicturebackend.exception.ErrorCode;
|
||||||
|
import edu.whut.smilepicturebackend.exception.ThrowUtils;
|
||||||
|
import edu.whut.smilepicturebackend.model.dto.space.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||||
|
import edu.whut.smilepicturebackend.model.entity.User;
|
||||||
|
import edu.whut.smilepicturebackend.model.vo.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.model.vo.space.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.service.SpaceAnalyzeService;
|
||||||
|
import edu.whut.smilepicturebackend.service.UserService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 程序员鱼皮 <a href="https://www.codefather.cn">编程导航原创项目</a>
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RequestMapping("/space/analyze")
|
||||||
|
public class SpaceAnalyzeController {
|
||||||
|
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
private final SpaceAnalyzeService spaceAnalyzeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间的使用状态
|
||||||
|
*
|
||||||
|
* @param spaceUsageAnalyzeRequest
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/usage")
|
||||||
|
public BaseResponse<SpaceUsageAnalyzeResponse> getSpaceUsageAnalyze(
|
||||||
|
@RequestBody SpaceUsageAnalyzeRequest spaceUsageAnalyzeRequest,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
ThrowUtils.throwIf(spaceUsageAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
SpaceUsageAnalyzeResponse spaceUsageAnalyze = spaceAnalyzeService.getSpaceUsageAnalyze(spaceUsageAnalyzeRequest, loginUser);
|
||||||
|
return ResultUtils.success(spaceUsageAnalyze);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间图片分类分析
|
||||||
|
*
|
||||||
|
* @param spaceCategoryAnalyzeRequest
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/category")
|
||||||
|
public BaseResponse<List<SpaceCategoryAnalyzeResponse>> getSpaceCategoryAnalyze(
|
||||||
|
@RequestBody SpaceCategoryAnalyzeRequest spaceCategoryAnalyzeRequest,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
ThrowUtils.throwIf(spaceCategoryAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
List<SpaceCategoryAnalyzeResponse> spaceCategoryAnalyze = spaceAnalyzeService.getSpaceCategoryAnalyze(spaceCategoryAnalyzeRequest, loginUser);
|
||||||
|
return ResultUtils.success(spaceCategoryAnalyze);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间图片标签分析
|
||||||
|
*
|
||||||
|
* @param spaceTagAnalyzeRequest
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/tag")
|
||||||
|
public BaseResponse<List<SpaceTagAnalyzeResponse>> getSpaceTagAnalyze(
|
||||||
|
@RequestBody SpaceTagAnalyzeRequest spaceTagAnalyzeRequest,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
ThrowUtils.throwIf(spaceTagAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
List<SpaceTagAnalyzeResponse> spaceTagAnalyze = spaceAnalyzeService.getSpaceTagAnalyze(spaceTagAnalyzeRequest, loginUser);
|
||||||
|
return ResultUtils.success(spaceTagAnalyze);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间图片大小分析
|
||||||
|
*
|
||||||
|
* @param spaceSizeAnalyzeRequest
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/size")
|
||||||
|
public BaseResponse<List<SpaceSizeAnalyzeResponse>> getSpaceSizeAnalyze(@RequestBody SpaceSizeAnalyzeRequest spaceSizeAnalyzeRequest,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
ThrowUtils.throwIf(spaceSizeAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
List<SpaceSizeAnalyzeResponse> resultList = spaceAnalyzeService.getSpaceSizeAnalyze(spaceSizeAnalyzeRequest, loginUser);
|
||||||
|
return ResultUtils.success(resultList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间用户行为分析
|
||||||
|
*
|
||||||
|
* @param spaceUserAnalyzeRequest
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/user")
|
||||||
|
public BaseResponse<List<SpaceUserAnalyzeResponse>> getSpaceUserAnalyze(@RequestBody SpaceUserAnalyzeRequest spaceUserAnalyzeRequest,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
ThrowUtils.throwIf(spaceUserAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
List<SpaceUserAnalyzeResponse> resultList = spaceAnalyzeService.getSpaceUserAnalyze(spaceUserAnalyzeRequest, loginUser);
|
||||||
|
return ResultUtils.success(resultList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间使用排行分析
|
||||||
|
*
|
||||||
|
* @param spaceRankAnalyzeRequest
|
||||||
|
* @param request
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/rank")
|
||||||
|
public BaseResponse<List<Space>> getSpaceRankAnalyze(@RequestBody SpaceRankAnalyzeRequest spaceRankAnalyzeRequest,
|
||||||
|
HttpServletRequest request) {
|
||||||
|
ThrowUtils.throwIf(spaceRankAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
User loginUser = userService.getLoginUser(request);
|
||||||
|
List<Space> resultList = spaceAnalyzeService.getSpaceRankAnalyze(spaceRankAnalyzeRequest, loginUser);
|
||||||
|
return ResultUtils.success(resultList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用空间分析请求
|
||||||
|
* queryAll ->查全空间,仅管理员 ; querypublic:查公共图库,仅管理员; spaceId,仅queryAll和querypublic都false时启用,查私人空间。
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SpaceAnalyzeRequest implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间 ID
|
||||||
|
*/
|
||||||
|
private Long spaceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否查询公共图库
|
||||||
|
*/
|
||||||
|
private boolean queryPublic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全空间分析
|
||||||
|
*/
|
||||||
|
private boolean queryAll;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间图片分类分析请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class SpaceCategoryAnalyzeRequest extends SpaceAnalyzeRequest {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间使用排行分析请求(仅管理员)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SpaceRankAnalyzeRequest implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排名前 N 的空间
|
||||||
|
*/
|
||||||
|
private Integer topN = 10;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间图片大小分析请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class SpaceSizeAnalyzeRequest extends SpaceAnalyzeRequest {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间图片标签分析请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class SpaceTagAnalyzeRequest extends SpaceAnalyzeRequest {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间资源使用分析请求封装类
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class SpaceUsageAnalyzeRequest extends SpaceAnalyzeRequest {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.dto.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间用户上传行为分析请求
|
||||||
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
public class SpaceUserAnalyzeRequest extends SpaceAnalyzeRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户 ID
|
||||||
|
*/
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间维度:day / week / month
|
||||||
|
*/
|
||||||
|
private String timeDimension;
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.vo.space.analyze;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间图片分类分析响应
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpaceCategoryAnalyzeResponse implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片分类
|
||||||
|
*/
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片数量
|
||||||
|
*/
|
||||||
|
private Long count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分类图片总大小
|
||||||
|
*/
|
||||||
|
private Long totalSize;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.vo.space.analyze;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间图片大小分析响应
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpaceSizeAnalyzeResponse implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片大小范围
|
||||||
|
*/
|
||||||
|
private String sizeRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片数量
|
||||||
|
*/
|
||||||
|
private Long count;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.vo.space.analyze;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间图片标签分析响应
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpaceTagAnalyzeResponse implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标签名称
|
||||||
|
*/
|
||||||
|
private String tag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用次数
|
||||||
|
*/
|
||||||
|
private Long count;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.vo.space.analyze;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间资源使用分析响应类
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SpaceUsageAnalyzeResponse implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已使用大小
|
||||||
|
*/
|
||||||
|
private Long usedSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总大小
|
||||||
|
*/
|
||||||
|
private Long maxSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间使用比例
|
||||||
|
*/
|
||||||
|
private Double sizeUsageRatio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前图片数量
|
||||||
|
*/
|
||||||
|
private Long usedCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最大图片数量
|
||||||
|
*/
|
||||||
|
private Long maxCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片数量占比
|
||||||
|
*/
|
||||||
|
private Double countUsageRatio;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package edu.whut.smilepicturebackend.model.vo.space.analyze;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间用户上传行为分析响应
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class SpaceUserAnalyzeResponse implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间区间
|
||||||
|
*/
|
||||||
|
private String period;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传数量
|
||||||
|
*/
|
||||||
|
private Long count;
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package edu.whut.smilepicturebackend.service;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import edu.whut.smilepicturebackend.model.dto.space.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.model.entity.Space;
|
||||||
|
import edu.whut.smilepicturebackend.model.entity.User;
|
||||||
|
import edu.whut.smilepicturebackend.model.vo.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.model.vo.space.analyze.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 李鱼皮
|
||||||
|
* @createDate 2024-12-18 19:53:34
|
||||||
|
*/
|
||||||
|
public interface SpaceAnalyzeService extends IService<Space> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间使用情况分析
|
||||||
|
*
|
||||||
|
* @param spaceUsageAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SpaceUsageAnalyzeResponse getSpaceUsageAnalyze(SpaceUsageAnalyzeRequest spaceUsageAnalyzeRequest, User loginUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间图片分类分析
|
||||||
|
*
|
||||||
|
* @param spaceCategoryAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SpaceCategoryAnalyzeResponse> getSpaceCategoryAnalyze(SpaceCategoryAnalyzeRequest spaceCategoryAnalyzeRequest, User loginUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间图片标签分析
|
||||||
|
*
|
||||||
|
* @param spaceTagAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SpaceTagAnalyzeResponse> getSpaceTagAnalyze(SpaceTagAnalyzeRequest spaceTagAnalyzeRequest, User loginUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间图片大小分析
|
||||||
|
*
|
||||||
|
* @param spaceSizeAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SpaceSizeAnalyzeResponse> getSpaceSizeAnalyze(SpaceSizeAnalyzeRequest spaceSizeAnalyzeRequest, User loginUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取空间用户上传行为分析
|
||||||
|
*
|
||||||
|
* @param spaceUserAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<SpaceUserAnalyzeResponse> getSpaceUserAnalyze(SpaceUserAnalyzeRequest spaceUserAnalyzeRequest, User loginUser);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空间使用排行分析(仅管理员)
|
||||||
|
*
|
||||||
|
* @param spaceRankAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<Space> getSpaceRankAnalyze(SpaceRankAnalyzeRequest spaceRankAnalyzeRequest, User loginUser);
|
||||||
|
}
|
@ -0,0 +1,310 @@
|
|||||||
|
package edu.whut.smilepicturebackend.service.impl;
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
|
import cn.hutool.core.util.ObjUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
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.analyze.*;
|
||||||
|
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.vo.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.model.vo.space.analyze.*;
|
||||||
|
import edu.whut.smilepicturebackend.service.PictureService;
|
||||||
|
import edu.whut.smilepicturebackend.service.SpaceAnalyzeService;
|
||||||
|
import edu.whut.smilepicturebackend.service.SpaceService;
|
||||||
|
import edu.whut.smilepicturebackend.service.UserService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author 李鱼皮
|
||||||
|
* @createDate 2024-12-18 19:53:34
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SpaceAnalyzeServiceImpl extends ServiceImpl<SpaceMapper, Space>
|
||||||
|
implements SpaceAnalyzeService {
|
||||||
|
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
|
private final SpaceService spaceService;
|
||||||
|
|
||||||
|
private final PictureService pictureService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SpaceUsageAnalyzeResponse getSpaceUsageAnalyze(SpaceUsageAnalyzeRequest spaceUsageAnalyzeRequest, User loginUser) {
|
||||||
|
// 校验参数
|
||||||
|
// 全空间或公共图库,需要从 Picture 表查询
|
||||||
|
if (spaceUsageAnalyzeRequest.isQueryAll() || spaceUsageAnalyzeRequest.isQueryPublic()) {
|
||||||
|
// 权限校验,仅管理员可以访问
|
||||||
|
checkSpaceAnalyzeAuth(spaceUsageAnalyzeRequest, loginUser);
|
||||||
|
// 统计图库的使用空间
|
||||||
|
QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.select("pic_size");
|
||||||
|
// 补充查询范围
|
||||||
|
fillAnalyzeQueryWrapper(spaceUsageAnalyzeRequest, queryWrapper);
|
||||||
|
List<Object> pictureObjList = pictureService.getBaseMapper().selectObjs(queryWrapper); //不用pictureService.list(),它会查完整的一条记录,而我们仅需一列
|
||||||
|
long usedSize = 0L;
|
||||||
|
for (Object obj : pictureObjList) {
|
||||||
|
// 记得把 Object 强转成 Long,再拆箱加到累加器里
|
||||||
|
usedSize += (Long) obj;
|
||||||
|
}
|
||||||
|
long usedCount = pictureObjList.size();
|
||||||
|
// 封装返回结果
|
||||||
|
SpaceUsageAnalyzeResponse spaceUsageAnalyzeResponse = new SpaceUsageAnalyzeResponse();
|
||||||
|
spaceUsageAnalyzeResponse.setUsedSize(usedSize);
|
||||||
|
spaceUsageAnalyzeResponse.setUsedCount(usedCount);
|
||||||
|
// 公共图库(或者全部空间)无数量和容量限制、也没有比例
|
||||||
|
spaceUsageAnalyzeResponse.setMaxSize(null);
|
||||||
|
spaceUsageAnalyzeResponse.setSizeUsageRatio(null);
|
||||||
|
spaceUsageAnalyzeResponse.setMaxCount(null);
|
||||||
|
spaceUsageAnalyzeResponse.setCountUsageRatio(null);
|
||||||
|
return spaceUsageAnalyzeResponse;
|
||||||
|
} else {
|
||||||
|
// 特定空间可以直接从 Space 表查询!
|
||||||
|
Long spaceId = spaceUsageAnalyzeRequest.getSpaceId();
|
||||||
|
ThrowUtils.throwIf(spaceId == null || spaceId <= 0, ErrorCode.PARAMS_ERROR);
|
||||||
|
// 获取空间信息
|
||||||
|
Space space = spaceService.getById(spaceId);
|
||||||
|
ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
|
||||||
|
// 权限校验,仅管理员可以访问
|
||||||
|
checkSpaceAnalyzeAuth(spaceUsageAnalyzeRequest, loginUser);
|
||||||
|
// 封装返回结果
|
||||||
|
SpaceUsageAnalyzeResponse spaceUsageAnalyzeResponse = new SpaceUsageAnalyzeResponse();
|
||||||
|
spaceUsageAnalyzeResponse.setUsedSize(space.getTotalSize());
|
||||||
|
spaceUsageAnalyzeResponse.setUsedCount(space.getTotalCount());
|
||||||
|
spaceUsageAnalyzeResponse.setMaxSize(space.getMaxSize());
|
||||||
|
spaceUsageAnalyzeResponse.setMaxCount(space.getMaxCount());
|
||||||
|
// 计算比例
|
||||||
|
double sizeUsageRatio = NumberUtil.round(space.getTotalSize() * 100.0 / space.getMaxSize(), 2).doubleValue();
|
||||||
|
double countUsageRatio = NumberUtil.round(space.getTotalCount() * 100.0 / space.getMaxCount(), 2).doubleValue();
|
||||||
|
spaceUsageAnalyzeResponse.setSizeUsageRatio(sizeUsageRatio);
|
||||||
|
spaceUsageAnalyzeResponse.setCountUsageRatio(countUsageRatio);
|
||||||
|
return spaceUsageAnalyzeResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SpaceCategoryAnalyzeResponse> getSpaceCategoryAnalyze(SpaceCategoryAnalyzeRequest spaceCategoryAnalyzeRequest, User loginUser) {
|
||||||
|
ThrowUtils.throwIf(spaceCategoryAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
// 检查权限
|
||||||
|
checkSpaceAnalyzeAuth(spaceCategoryAnalyzeRequest, loginUser);
|
||||||
|
|
||||||
|
// 构造查询条件
|
||||||
|
QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
|
||||||
|
fillAnalyzeQueryWrapper(spaceCategoryAnalyzeRequest, queryWrapper);
|
||||||
|
|
||||||
|
// 使用 MyBatis Plus 分组查询
|
||||||
|
queryWrapper.select("category", "count(*) as count", "sum(pic_size) as total_size")
|
||||||
|
.groupBy("category");
|
||||||
|
|
||||||
|
// 查询并转换结果
|
||||||
|
return pictureService.getBaseMapper().selectMaps(queryWrapper)
|
||||||
|
.stream()
|
||||||
|
.map(result -> {
|
||||||
|
String category = (String) result.get("category");
|
||||||
|
Long count = ((Number) result.get("count")).longValue();
|
||||||
|
Long totalSize = ((Number) result.get("total_size")).longValue();
|
||||||
|
return new SpaceCategoryAnalyzeResponse(category, count, totalSize);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SpaceTagAnalyzeResponse> getSpaceTagAnalyze(SpaceTagAnalyzeRequest spaceTagAnalyzeRequest, User loginUser) {
|
||||||
|
ThrowUtils.throwIf(spaceTagAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
// 检查权限
|
||||||
|
checkSpaceAnalyzeAuth(spaceTagAnalyzeRequest, loginUser);
|
||||||
|
|
||||||
|
// 构造查询条件
|
||||||
|
QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
|
||||||
|
fillAnalyzeQueryWrapper(spaceTagAnalyzeRequest, queryWrapper);
|
||||||
|
// 查询所有符合条件的标签
|
||||||
|
queryWrapper.select("tags");
|
||||||
|
List<String> tagsJsonList = pictureService.getBaseMapper().selectObjs(queryWrapper)
|
||||||
|
.stream()
|
||||||
|
.filter(ObjUtil::isNotNull)
|
||||||
|
.map(Object::toString)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 解析标签并统计
|
||||||
|
Map<String, Long> tagCountMap = tagsJsonList.stream()
|
||||||
|
// ["Java", "Python"], ["Java", "PHP"] => "Java", "Python", "Java", "PHP"
|
||||||
|
.flatMap(tagsJson -> JSONUtil.toList(tagsJson, String.class).stream())
|
||||||
|
.collect(Collectors.groupingBy(tag -> tag, Collectors.counting()));
|
||||||
|
|
||||||
|
// 转换为响应对象,按照使用次数进行排序
|
||||||
|
return tagCountMap.entrySet().stream()
|
||||||
|
.sorted((e1, e2) -> Long.compare(e2.getValue(), e1.getValue())) // 降序排序
|
||||||
|
.map(entry -> new SpaceTagAnalyzeResponse(entry.getKey(), entry.getValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SpaceSizeAnalyzeResponse> getSpaceSizeAnalyze(SpaceSizeAnalyzeRequest spaceSizeAnalyzeRequest, User loginUser) {
|
||||||
|
ThrowUtils.throwIf(spaceSizeAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
// 检查权限
|
||||||
|
checkSpaceAnalyzeAuth(spaceSizeAnalyzeRequest, loginUser);
|
||||||
|
|
||||||
|
// 构造查询条件
|
||||||
|
QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
|
||||||
|
fillAnalyzeQueryWrapper(spaceSizeAnalyzeRequest, queryWrapper);
|
||||||
|
|
||||||
|
// 查询所有符合条件的图片大小
|
||||||
|
queryWrapper.select("pic_size");
|
||||||
|
// 100、120、1000
|
||||||
|
List<Long> picSizeList = pictureService.getBaseMapper().selectObjs(queryWrapper)
|
||||||
|
.stream()
|
||||||
|
.filter(ObjUtil::isNotNull)
|
||||||
|
.map(size -> (Long) size)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 定义分段范围,注意使用有序的 Map
|
||||||
|
Map<String, Long> sizeRanges = new LinkedHashMap<>();
|
||||||
|
sizeRanges.put("<100KB", picSizeList.stream().filter(size -> size < 100 * 1024).count());
|
||||||
|
sizeRanges.put("100KB-500KB", picSizeList.stream().filter(size -> size >= 100 * 1024 && size < 500 * 1024).count());
|
||||||
|
sizeRanges.put("500KB-1MB", picSizeList.stream().filter(size -> size >= 500 * 1024 && size < 1 * 1024 * 1024).count());
|
||||||
|
sizeRanges.put(">1MB", picSizeList.stream().filter(size -> size >= 1 * 1024 * 1024).count());
|
||||||
|
|
||||||
|
// 转换为响应对象
|
||||||
|
return sizeRanges.entrySet().stream()
|
||||||
|
.map(entry -> new SpaceSizeAnalyzeResponse(entry.getKey(), entry.getValue()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据前端传来的 时间维度(按天 / 周 / 月)来动态拼出不同的 SQL 聚合字段,然后再按照这个“时间段”字段去分组和排序,最终拿到每个周期(period)里上传的图片数量
|
||||||
|
* @param spaceUserAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<SpaceUserAnalyzeResponse> getSpaceUserAnalyze(SpaceUserAnalyzeRequest spaceUserAnalyzeRequest, User loginUser) {
|
||||||
|
ThrowUtils.throwIf(spaceUserAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
// 检查权限
|
||||||
|
checkSpaceAnalyzeAuth(spaceUserAnalyzeRequest, loginUser);
|
||||||
|
|
||||||
|
// 构造查询条件
|
||||||
|
QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
|
||||||
|
fillAnalyzeQueryWrapper(spaceUserAnalyzeRequest, queryWrapper);
|
||||||
|
// 补充用户 id 查询
|
||||||
|
Long userId = spaceUserAnalyzeRequest.getUserId();
|
||||||
|
queryWrapper.eq(ObjUtil.isNotNull(userId), "user_id", userId);
|
||||||
|
// 补充分析维度:每日、每周、每月
|
||||||
|
/**
|
||||||
|
* eg:
|
||||||
|
* SELECT
|
||||||
|
* DATE_FORMAT(create_time, '%Y-%m') AS period,
|
||||||
|
* COUNT(*) AS count
|
||||||
|
* FROM picture
|
||||||
|
* … (其他 WHERE 条件)
|
||||||
|
* GROUP BY period
|
||||||
|
* ORDER BY period ASC;
|
||||||
|
*/
|
||||||
|
String timeDimension = spaceUserAnalyzeRequest.getTimeDimension();
|
||||||
|
switch (timeDimension) {
|
||||||
|
case "day":
|
||||||
|
queryWrapper.select("DATE_FORMAT(create_time, '%Y-%m-%d') as period", "count(*) as count");
|
||||||
|
break;
|
||||||
|
case "week":
|
||||||
|
queryWrapper.select("YEARWEEK(create_time) as period", "count(*) as count");
|
||||||
|
break;
|
||||||
|
case "month":
|
||||||
|
queryWrapper.select("DATE_FORMAT(create_time, '%Y-%m') as period", "count(*) as count");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "不支持的时间维度");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分组排序
|
||||||
|
queryWrapper.groupBy("period").orderByAsc("period");
|
||||||
|
|
||||||
|
// 查询并封装结果
|
||||||
|
List<Map<String, Object>> queryResult = pictureService.getBaseMapper().selectMaps(queryWrapper);
|
||||||
|
return queryResult
|
||||||
|
.stream()
|
||||||
|
.map(result -> {
|
||||||
|
String period = result.get("period").toString();
|
||||||
|
Long count = ((Number) result.get("count")).longValue();
|
||||||
|
return new SpaceUserAnalyzeResponse(period, count);
|
||||||
|
})
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Space> getSpaceRankAnalyze(SpaceRankAnalyzeRequest spaceRankAnalyzeRequest, User loginUser) {
|
||||||
|
ThrowUtils.throwIf(spaceRankAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
|
||||||
|
// 检查权限,仅管理员可以查看
|
||||||
|
ThrowUtils.throwIf(!userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR);
|
||||||
|
|
||||||
|
// 构造查询条件
|
||||||
|
QueryWrapper<Space> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.select("id", "space_name", "user_id", "total_size")
|
||||||
|
.orderByDesc("total_size")
|
||||||
|
.last("limit " + spaceRankAnalyzeRequest.getTopN()); // 取前 N 名
|
||||||
|
|
||||||
|
// 查询并封装结果
|
||||||
|
return spaceService.list(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共方法:校验空间分析权限
|
||||||
|
*
|
||||||
|
* @param spaceAnalyzeRequest
|
||||||
|
* @param loginUser
|
||||||
|
*/
|
||||||
|
private void checkSpaceAnalyzeAuth(SpaceAnalyzeRequest spaceAnalyzeRequest, User loginUser) {
|
||||||
|
boolean queryPublic = spaceAnalyzeRequest.isQueryPublic();
|
||||||
|
boolean queryAll = spaceAnalyzeRequest.isQueryAll();
|
||||||
|
// 全空间分析或者公共图库权限校验:仅管理员可访问
|
||||||
|
if (queryAll || queryPublic) {
|
||||||
|
ThrowUtils.throwIf(!userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR);
|
||||||
|
} else {
|
||||||
|
// 分析特定空间,仅本人或管理员可以访问
|
||||||
|
Long spaceId = spaceAnalyzeRequest.getSpaceId();
|
||||||
|
ThrowUtils.throwIf(spaceId == null, ErrorCode.PARAMS_ERROR);
|
||||||
|
Space space = spaceService.getById(spaceId);
|
||||||
|
ThrowUtils.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
|
||||||
|
spaceService.checkSpaceAuth(loginUser, space);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共方法:根据请求对象封装查询条件
|
||||||
|
*
|
||||||
|
* @param spaceAnalyzeRequest
|
||||||
|
* @param queryWrapper
|
||||||
|
*/
|
||||||
|
private void fillAnalyzeQueryWrapper(SpaceAnalyzeRequest spaceAnalyzeRequest, QueryWrapper<Picture> queryWrapper) {
|
||||||
|
// 全空间分析
|
||||||
|
boolean queryAll = spaceAnalyzeRequest.isQueryAll();
|
||||||
|
if (queryAll) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 公共图库
|
||||||
|
boolean queryPublic = spaceAnalyzeRequest.isQueryPublic();
|
||||||
|
if (queryPublic) {
|
||||||
|
queryWrapper.isNull("space_id");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 分析特定空间
|
||||||
|
Long spaceId = spaceAnalyzeRequest.getSpaceId();
|
||||||
|
if (spaceId != null) {
|
||||||
|
queryWrapper.eq("space_id", spaceId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw new BusinessException(ErrorCode.PARAMS_ERROR, "未指定查询范围");
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user