视频评论

This commit is contained in:
曹佳豪 2025-06-14 14:17:34 +08:00
parent 983617947a
commit 3c3f3d03ea
27 changed files with 394 additions and 1296 deletions

View File

@ -1,11 +1,11 @@
package com.wzj.soopin.content.controller;
import com.wzj.soopin.content.result.GraceJSONResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.dromara.common.core.domain.R;
import java.io.File;
import java.io.FileOutputStream;
@ -19,7 +19,7 @@ public class FileController {
@PostMapping("upload")
public GraceJSONResult upload(MultipartFile file) throws Exception {
public R<String> upload(MultipartFile file) {
// 获取 vlogdata 目录路径
// String storagePath = new File(System.getProperty("user.dir"), "vlogdata").getAbsolutePath();
String storagePath = "/data/vlogdata"; // 生产
@ -43,6 +43,9 @@ public class FileController {
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (Exception e) {
log.error("文件上传失败: ", e);
return R.fail("文件上传失败: " + e.getMessage());
}
log.info("本地文件存储成功: " + destFile.getAbsolutePath());
@ -61,6 +64,6 @@ public class FileController {
// + "/"
// + fileName;
return GraceJSONResult.ok(imgUrl);
return R.ok(imgUrl);
}
}

View File

@ -2,7 +2,7 @@ package com.wzj.soopin.content.controller;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.mo.MessageMO;
import com.wzj.soopin.content.result.GraceJSONResult;
import org.dromara.common.core.domain.R;
import com.wzj.soopin.content.service.MsgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -22,7 +22,7 @@ public class MsgController extends BaseInfoProperties {
private MsgService msgService;
@GetMapping("list")
public GraceJSONResult list(@RequestParam String userId,
public R<List<MessageMO>> list(@RequestParam String userId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@ -36,6 +36,6 @@ public class MsgController extends BaseInfoProperties {
List<MessageMO> list = msgService.queryList(userId, page, pageSize);
return GraceJSONResult.ok(list);
return R.ok(list);
}
}

View File

@ -2,9 +2,9 @@ package com.wzj.soopin.content.controller;
import com.wzj.soopin.content.domain.base.RabbitMQConfig;
import com.wzj.soopin.content.domain.exceptions.GraceException;
import com.wzj.soopin.content.domain.mo.MessageMO;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
import com.wzj.soopin.content.enums.MessageEnum;
import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.utils.JsonUtils;
@ -58,7 +58,7 @@ public class RabbitMQConsumer {
MessageEnum.LIKE_COMMENT.type,
messageMO.getMsgContent());
} else {
GraceException.display(ResponseStatusEnum.SYSTEM_OPERATION_ERROR);
// GraceException.display(ResponseStatusEnum.SYSTEM_OPERATION_ERROR);
}
}

View File

@ -5,7 +5,7 @@ package com.wzj.soopin.content.controller;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.enums.YesOrNo;
import com.wzj.soopin.content.result.GraceJSONResult;
import org.dromara.common.core.domain.R;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.service.VlogUploadService;
import com.wzj.soopin.content.utils.PagedGridResult;
@ -36,7 +36,7 @@ public class VlogController extends BaseInfoProperties {
private VlogUploadService vlogUploadService;
@PostMapping("vodCallBack")
public GraceJSONResult vodCallBack(@RequestBody Map<String, Object> callbackData) {
public R<Void> vodCallBack(@RequestBody Map<String, Object> callbackData) {
try {
// 解析回调事件类型
String eventType = (String) callbackData.get("EventType");
@ -137,15 +137,15 @@ public class VlogController extends BaseInfoProperties {
}
}
// 处理完成返回成功防止腾讯云重复发送回调
return GraceJSONResult.ok();
return R.ok();
} catch (Exception e) {
log.error("处理腾讯云 VOD 回调异常: ", e);
return GraceJSONResult.error();
return R.fail("处理腾讯云 VOD 回调异常: " + e.getMessage());
}
}
@PostMapping("publish")
public GraceJSONResult publish(@RequestBody VlogBO vlogBO) throws Exception {
public R<Void> publish(@RequestBody VlogBO vlogBO) throws Exception {
String url = vlogBO.getUrl();
log.info("未审核视频地址:"+url);
String fileName = url.substring(url.lastIndexOf("/") + 1);
@ -161,11 +161,11 @@ public class VlogController extends BaseInfoProperties {
// FIXME 校验VlogBO
vlogService.createVlog(vlogBO);
return GraceJSONResult.ok();
return R.ok();
}
@GetMapping("indexList")
public GraceJSONResult indexList(@RequestParam(defaultValue = "") String userId,
public R<PagedGridResult> indexList(@RequestParam(defaultValue = "") String userId,
@RequestParam(defaultValue = "") String search,
@RequestParam(defaultValue = "") String cityCode,
@RequestParam(defaultValue = "") String status,
@ -180,44 +180,44 @@ public class VlogController extends BaseInfoProperties {
}
PagedGridResult gridResult = vlogService.getIndexVlogList(userId, search, cityCode,status, page, pageSize);
return GraceJSONResult.ok(gridResult);
return R.ok(gridResult);
}
@GetMapping("detail")
public GraceJSONResult detail(@RequestParam(defaultValue = "") String userId,
public R<Object> detail(@RequestParam(defaultValue = "") String userId,
@RequestParam String vlogId) {
return GraceJSONResult.ok(vlogService.getVlogDetailById(userId, vlogId));
return R.ok(vlogService.getVlogDetailById(userId, vlogId));
}
@PostMapping("changeVlogStatus")
public GraceJSONResult changeVlogStatus(@RequestParam String userId,
public R<Void> changeVlogStatus(@RequestParam String userId,
@RequestParam String vlogId,
@RequestParam Integer status) {
vlogService.changeVlogStatus(userId, vlogId,status);
return GraceJSONResult.ok();
return R.ok();
}
@PostMapping("changeToPrivate")
public GraceJSONResult changeToPrivate(@RequestParam String userId,
public R<Void> changeToPrivate(@RequestParam String userId,
@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(userId,
vlogId,
YesOrNo.YES.type);
return GraceJSONResult.ok();
return R.ok();
}
@PostMapping("changeToPublic")
public GraceJSONResult changeToPublic(@RequestParam String userId,
public R<Void> changeToPublic(@RequestParam String userId,
@RequestParam String vlogId) {
vlogService.changeToPrivateOrPublic(userId,
vlogId,
YesOrNo.NO.type);
return GraceJSONResult.ok();
return R.ok();
}
@GetMapping("myPublicList")
public GraceJSONResult myPublicList(@RequestParam String userId,
public R<PagedGridResult> myPublicList(@RequestParam String userId,
@RequestParam(defaultValue = "") String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@ -234,11 +234,11 @@ public class VlogController extends BaseInfoProperties {
page,
pageSize,
YesOrNo.NO.type);
return GraceJSONResult.ok(gridResult);
return R.ok(gridResult);
}
@GetMapping("myPrivateList")
public GraceJSONResult myPrivateList(@RequestParam String userId,
public R<PagedGridResult> myPrivateList(@RequestParam String userId,
@RequestParam(defaultValue = "") String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@ -255,11 +255,11 @@ public class VlogController extends BaseInfoProperties {
page,
pageSize,
YesOrNo.YES.type);
return GraceJSONResult.ok(gridResult);
return R.ok(gridResult);
}
@GetMapping("myLikedList")
public GraceJSONResult myLikedList(@RequestParam String userId,
public R<PagedGridResult> myLikedList(@RequestParam String userId,
@RequestParam(defaultValue = "") String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@ -275,14 +275,14 @@ public class VlogController extends BaseInfoProperties {
myId,
page,
pageSize);
return GraceJSONResult.ok(gridResult);
return R.ok(gridResult);
}
private Integer nacosConuts=0;
@PostMapping("like")
public GraceJSONResult like(@RequestParam String userId,
public R<Void> like(@RequestParam String userId,
@RequestParam String vlogerId,
@RequestParam String vlogId) {
@ -309,12 +309,12 @@ public class VlogController extends BaseInfoProperties {
}
}
return GraceJSONResult.ok();
return R.ok();
}
@PostMapping("unlike")
public GraceJSONResult unlike(@RequestParam String userId,
public R<Void> unlike(@RequestParam String userId,
@RequestParam String vlogerId,
@RequestParam String vlogId) {
@ -325,16 +325,16 @@ public class VlogController extends BaseInfoProperties {
redis.decrement(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId, 1);
redis.del(REDIS_USER_LIKE_VLOG + ":" + userId + ":" + vlogId);
return GraceJSONResult.ok();
return R.ok();
}
@PostMapping("totalLikedCounts")
public GraceJSONResult totalLikedCounts(@RequestParam String vlogId) {
return GraceJSONResult.ok(vlogService.getVlogBeLikedCounts(vlogId));
public R<Integer> totalLikedCounts(@RequestParam String vlogId) {
return R.ok(vlogService.getVlogBeLikedCounts(vlogId));
}
@GetMapping("followList")
public GraceJSONResult followList(@RequestParam String myId,
public R<PagedGridResult> followList(@RequestParam String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@ -348,11 +348,11 @@ public class VlogController extends BaseInfoProperties {
PagedGridResult gridResult = vlogService.getMyFollowVlogList(myId,
page,
pageSize);
return GraceJSONResult.ok(gridResult);
return R.ok(gridResult);
}
@GetMapping("friendList")
public GraceJSONResult friendList(@RequestParam String myId,
public R<PagedGridResult> friendList(@RequestParam String myId,
@RequestParam Integer page,
@RequestParam Integer pageSize) {
@ -366,7 +366,7 @@ public class VlogController extends BaseInfoProperties {
PagedGridResult gridResult = vlogService.getMyFriendVlogList(myId,
page,
pageSize);
return GraceJSONResult.ok(gridResult);
return R.ok(gridResult);
}

View File

@ -5,7 +5,7 @@ import com.wzj.soopin.content.domain.bo.CommentBO;
import com.wzj.soopin.content.domain.po.Comment;
import com.wzj.soopin.content.domain.vo.CommentVO;
import com.wzj.soopin.content.domain.vo.ChildCommentVO;
import com.wzj.soopin.content.result.GraceJSONResult;
import com.wzj.soopin.content.service.CommentService;
// import com.wzj.soopin.content.utils.PagedGridResult;
import io.swagger.annotations.Api;
@ -17,7 +17,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.core.constant.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -25,6 +25,7 @@ import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
@Slf4j
@Api(tags = "管理端-评论管理接口")
@ -57,31 +58,36 @@ public class CommentController extends BaseController {
return commentService.queryVlogComments(vlogId, userId, pageQuery);
} catch (Exception e) {
log.error("查询视频评论列表失败", e);
return null;
TableDataInfo<CommentVO> errorResponse = new TableDataInfo<>();
errorResponse.setCode(HttpStatus.ERROR);
errorResponse.setMsg("查询视频评论列表失败: " + e.getMessage());
errorResponse.setRows(Collections.emptyList());
errorResponse.setTotal(0L);
return errorResponse;
}
}
@ApiOperation("删除评论")
@PostMapping("/delete")
public GraceJSONResult deleteComment(
public R<Void> deleteComment(
@ApiParam(value = "评论ID") @RequestParam String commentId) {
try {
String username = LoginHelper.getUsername();
commentService.deleteComment(commentId, username);
return GraceJSONResult.ok();
return R.ok();
} catch (Exception e) {
log.error("删除评论失败", e);
return GraceJSONResult.errorMsg("删除评论失败: " + e.getMessage());
return R.fail("删除评论失败: " + e.getMessage());
}
}
@ApiOperation("获取评论详情")
@GetMapping("/detail")
public GraceJSONResult getCommentDetail(@ApiParam(value = "评论ID") @RequestParam String commentId) {
public R<Map<String, Object>> getCommentDetail(@ApiParam(value = "评论ID") @RequestParam String commentId) {
try {
Comment comment = commentService.getCommentDetail(commentId);
if (comment == null) {
return GraceJSONResult.errorMsg("评论不存在");
return R.fail("评论不存在");
}
// 获取子评论
@ -91,10 +97,10 @@ public class CommentController extends BaseController {
result.put("comment", comment);
result.put("childComments", childComments);
return GraceJSONResult.ok(result);
return R.ok(result);
} catch (Exception e) {
log.error("获取评论详情失败", e);
return GraceJSONResult.errorMsg("获取评论详情失败: " + e.getMessage());
return R.fail("获取评论详情失败: " + e.getMessage());
}
}
@ -111,14 +117,14 @@ public class CommentController extends BaseController {
@ApiOperation("下架评论")
@PostMapping("/offline")
public GraceJSONResult offlineComment(@ApiParam(value = "评论ID") @RequestParam String commentId) {
public R<Void> offlineComment(@ApiParam(value = "评论ID") @RequestParam String commentId) {
try {
String username = LoginHelper.getUsername();
commentService.offlineComment(commentId, username);
return GraceJSONResult.ok();
return R.ok();
} catch (Exception e) {
log.error("下架评论失败", e);
return GraceJSONResult.errorMsg("下架评论失败: " + e.getMessage());
return R.fail("下架评论失败: " + e.getMessage());
}
}
}

View File

@ -4,7 +4,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tencentcloudapi.vod.v20180717.models.*;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.result.GraceJSONResult;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.service.VlogService;
import com.wzj.soopin.content.service.VlogUploadService;
import com.wzj.soopin.content.utils.RedisOperator;
@ -15,6 +16,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.apache.commons.lang3.StringUtils;
@ -47,92 +49,32 @@ public class VlogUploadController extends BaseInfoProperties {
private IFansService fansService;
@ApiOperation("获取腾讯云点播视频列表")
@GetMapping("/list")
public GraceJSONResult getVodList(
@ApiParam(value = "当前页码", defaultValue = "1") @RequestParam(value = "current", required = false, defaultValue = "1") Integer current,
@ApiParam(value = "每页记录数", defaultValue = "10") @RequestParam(value = "size", required = false, defaultValue = "10") Integer size,
@ApiParam(value = "手机号(模糊查询)") @RequestParam(required = false) String mobile,
@ApiParam(value = "用户昵称(模糊查询)") @RequestParam(required = false) String nickname,
@ApiParam(value = "视频标题(模糊查询)") @RequestParam(required = false) String title,
@ApiParam(value = "文件状态") @RequestParam(required = false) String[] status,
@ApiParam(value = "文件类型") @RequestParam(required = false) String[] categories,
@ApiParam(value = "媒体文件来源") @RequestParam(required = false) String[] sourceTypes,
@ApiParam(value = "媒体文件封装格式") @RequestParam(required = false) String[] mediaTypes,
@ApiParam(value = "文件名") @RequestParam(required = false) String[] names,
@ApiParam(value = "文件名前缀") @RequestParam(required = false) String[] namePrefixes,
@ApiParam(value = "文件描述") @RequestParam(required = false) String[] descriptions,
@ApiParam(value = "标签") @RequestParam(required = false) String[] tags,
@ApiParam(value = "分类ID") @RequestParam(required = false) Long[] classIds,
@ApiParam(value = "存储地区") @RequestParam(required = false) String[] storageRegions,
@ApiParam(value = "创建时间范围-开始时间") @RequestParam(required = false) String startTime,
@ApiParam(value = "创建时间范围-结束时间") @RequestParam(required = false) String endTime,
@ApiParam(value = "排序字段", defaultValue = "CreateTime", allowableValues = "CreateTime,LikeCounts,CommentsCounts,Name,Status")
@RequestParam(required = false, defaultValue = "CreateTime") String sortField,
@ApiParam(value = "排序方式", defaultValue = "Asc", allowableValues = "Asc,Desc")
@RequestParam(required = false, defaultValue = "Asc") String sortOrder,
@ApiParam(value = "需要返回的信息类型") @RequestParam(required = false) String[] filters) {
@PostMapping("/list")
public R<IPage<Map<String, Object>>> getVodList(@RequestBody VlogBO vlogBO) {
try {
// 验证分页参数
if (current < 1) {
current = 1;
if (vlogBO.getCurrent() < 1) {
vlogBO.setCurrent(1L);
}
if (size < 1 || size > 50) {
size = 10;
if (vlogBO.getSize() < 1 || vlogBO.getSize() > 50) {
vlogBO.setSize(10L);
}
// 如果有模糊查询条件或有时间区间条件,则只查询数据库
if (StringUtils.isNotBlank(mobile)
|| StringUtils.isNotBlank(nickname)
|| StringUtils.isNotBlank(title)
|| StringUtils.isNotBlank(startTime)
|| StringUtils.isNotBlank(endTime)
|| (status != null && status.length > 0)) {
// 如果有模糊查询条件时间区间条件或者有排序条件则只查询数据库
if (StringUtils.isNotBlank(vlogBO.getMobile())
|| StringUtils.isNotBlank(vlogBO.getNickname())
|| StringUtils.isNotBlank(vlogBO.getTitleQuery())
|| StringUtils.isNotBlank(vlogBO.getStartTime())
|| StringUtils.isNotBlank(vlogBO.getEndTime())
|| vlogBO.getStatus() != null
|| StringUtils.isNotBlank(vlogBO.getColumn())) {
// 创建分页对象
Page<Map<String, Object>> page = new Page<>(current, size);
// 构建查询参数
Map<String, Object> params = new HashMap<>();
if (StringUtils.isNotBlank(mobile)) {
params.put("mobile", mobile);
}
if (StringUtils.isNotBlank(nickname)) {
params.put("nickname", nickname);
}
if (StringUtils.isNotBlank(title)) {
params.put("title", title);
}
if (status != null && status.length > 0) {
params.put("status", status[0]); // 取第一个状态值
}
// 时间格式转换
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
if (StringUtils.isNotBlank(startTime)) {
try {
Instant instant = Instant.parse(startTime.replace("\"", ""));
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
String formatted = zdt.format(formatter);
params.put("startTime", formatted);
} catch (Exception e) {
log.error("开始时间格式错误: {}", startTime);
return GraceJSONResult.errorMsg("开始时间格式错误请使用yyyy-MM-dd HH:mm:ss格式");
}
}
if (StringUtils.isNotBlank(endTime)) {
try {
Instant instant = Instant.parse(endTime.replace("\"", ""));
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());
String formatted = zdt.format(formatter);
params.put("endTime", formatted);
} catch (Exception e) {
log.error("结束时间格式错误: {}", endTime);
return GraceJSONResult.errorMsg("结束时间格式错误请使用yyyy-MM-dd HH:mm:ss格式");
}
}
Page<Map<String, Object>> page = new Page<>(vlogBO.getCurrent(), vlogBO.getSize());
// 调用服务层方法进行查询
IPage<Map<String, Object>> result = vlogService.getVlogListByMobile(page, params);
return GraceJSONResult.ok(result);
IPage<Map<String, Object>> result = vlogService.getVlogListByMobile(page, vlogBO);
return R.ok(result);
}
// 否则查询腾讯云点播
@ -141,72 +83,31 @@ public class VlogUploadController extends BaseInfoProperties {
String secretKey = tencentCloudUtil.getSecretKey();
if (secretId == null || secretId.isEmpty() || secretKey == null || secretKey.isEmpty()) {
log.error("腾讯云密钥未配置");
return GraceJSONResult.errorMsg("腾讯云密钥未配置");
return R.fail("腾讯云密钥未配置");
}
// 计算实际的offset
long offset = (long) ((current - 1) * size);
long offset = (long) ((vlogBO.getCurrent() - 1) * vlogBO.getSize());
if (offset < 0) {
offset = 0;
}
// 打印分页参数
log.info("分页参数 - 当前页码: {}, 每页记录数: {}, 偏移量: {}", current, size, offset);
log.info("排序参数 - 排序字段: {}, 排序方式: {}", sortField, sortOrder);
// 验证排序参数
List<String> validSortFields = Arrays.asList("CreateTime", "LikeCounts", "CommentsCounts", "Name", "Status");
List<String> validSortOrders = Arrays.asList("Asc", "Desc");
if (!validSortFields.contains(sortField)) {
return GraceJSONResult.errorMsg("无效的排序字段,支持的字段有:" + String.join(",", validSortFields));
}
if (!validSortOrders.contains(sortOrder)) {
return GraceJSONResult.errorMsg("无效的排序方式,只能是 Asc(升序) 或 Desc(降序)");
}
log.info("分页参数 - 当前页码: {}, 每页记录数: {}, 偏移量: {}", vlogBO.getCurrent(), vlogBO.getSize(), offset);
// 创建请求对象
SearchMediaRequest req = new SearchMediaRequest();
// 设置分页参数
req.setOffset(offset);
req.setLimit((long) size);
req.setLimit(vlogBO.getSize());
// 设置排序
SortBy sort = new SortBy();
sort.setField(sortField);
sort.setOrder(sortOrder);
sort.setField("CreateTime");
sort.setOrder("Desc");
req.setSort(sort);
// 设置过滤条件
if (categories != null && categories.length > 0) {
req.setCategories(categories);
}
if (sourceTypes != null && sourceTypes.length > 0) {
req.setSourceTypes(sourceTypes);
}
if (names != null && names.length > 0) {
req.setNames(names);
}
if (namePrefixes != null && namePrefixes.length > 0) {
req.setNamePrefixes(namePrefixes);
}
if (descriptions != null && descriptions.length > 0) {
req.setDescriptions(descriptions);
}
if (tags != null && tags.length > 0) {
req.setTags(tags);
}
if (classIds != null && classIds.length > 0) {
req.setClassIds(classIds);
}
if (storageRegions != null && storageRegions.length > 0) {
req.setStorageRegions(storageRegions);
}
if (filters != null && filters.length > 0) {
req.setFilters(filters);
}
// 调用腾讯云API获取视频列表
log.info("开始调用腾讯云 SearchMedia API");
SearchMediaResponse resp = vlogUploadService.searchMedia(req);
@ -215,9 +116,9 @@ public class VlogUploadController extends BaseInfoProperties {
// 处理响应结果
Map<String, Object> result = new HashMap<>();
result.put("total", resp.getTotalCount());
result.put("current", current);
result.put("size", size);
result.put("pages", (resp.getTotalCount() + size - 1) / size); // 总页数
result.put("current", vlogBO.getCurrent());
result.put("size", vlogBO.getSize());
result.put("pages", (resp.getTotalCount() + vlogBO.getSize() - 1) / vlogBO.getSize()); // 总页数
List<Map<String, Object>> mediaList = new ArrayList<>();
if (resp.getMediaInfoSet() != null) {
@ -257,12 +158,19 @@ public class VlogUploadController extends BaseInfoProperties {
mediaList.add(mediaMap);
}
}
result.put("records", mediaList); // 改为 records 以匹配前端预期
result.put("records", mediaList);
return GraceJSONResult.ok(result);
// 构建Page对象
Page<Map<String, Object>> page = new Page<>();
page.setCurrent(vlogBO.getCurrent());
page.setSize(vlogBO.getSize());
page.setTotal(resp.getTotalCount());
page.setRecords(mediaList);
return R.ok(page);
} catch (Exception e) {
log.error("获取视频列表失败", e);
return GraceJSONResult.errorMsg("获取视频列表失败: " + e.getMessage());
return R.fail("获取视频列表失败: " + e.getMessage());
}
}
@ -270,15 +178,15 @@ public class VlogUploadController extends BaseInfoProperties {
* 视频审核接口
*/
@PostMapping("/audit")
public GraceJSONResult auditVlog(@RequestParam String vlogId,
public R<Void> auditVlog(@RequestParam String vlogId,
@RequestParam Integer status,
@RequestParam(required = false) String reason) {
try {
vlogUploadService.auditVlog(vlogId, status, reason);
return GraceJSONResult.ok();
return R.ok();
} catch (Exception e) {
log.error("视频审核失败", e);
return GraceJSONResult.errorMsg("视频审核失败: " + e.getMessage());
return R.fail("视频审核失败: " + e.getMessage());
}
}
@ -286,13 +194,13 @@ public class VlogUploadController extends BaseInfoProperties {
* 视频删除接口
*/
@PostMapping("/delete")
public GraceJSONResult deleteVlog(@RequestParam String vlogId) {
public R<Void> deleteVlog(@RequestParam String vlogId) {
try {
vlogUploadService.deleteVlog(vlogId);
return GraceJSONResult.ok();
return R.ok();
} catch (Exception e) {
log.error("视频删除失败", e);
return GraceJSONResult.errorMsg("视频删除失败: " + e.getMessage());
return R.fail("视频删除失败: " + e.getMessage());
}
}
@ -300,7 +208,7 @@ public class VlogUploadController extends BaseInfoProperties {
* 视频详情接口
*/
@GetMapping("/detail")
public GraceJSONResult vlogDetail(@RequestParam String fileId) {
public R<Map<String, Object>> vlogDetail(@RequestParam String fileId) {
try {
// 获取视频基本信息
Map<String, Object> result = vlogService.getVlogDetailInfo(fileId);
@ -312,20 +220,20 @@ public class VlogUploadController extends BaseInfoProperties {
result.put("uploaderPhone", uploaderInfo.get("phone"));
}
return GraceJSONResult.ok(result);
return R.ok(result);
} catch (Exception e) {
log.error("获取视频详情失败", e);
return GraceJSONResult.errorMsg("获取视频详情失败: " + e.getMessage());
return R.fail("获取视频详情失败: " + e.getMessage());
}
}
@ApiOperation(value = "禁播/解禁视频", notes = "禁播/解禁视频接口")
@PostMapping("/forbid")
public GraceJSONResult forbidMediaDistribution(@RequestBody Map<String, Object> params) {
public R<Void> forbidMediaDistribution(@RequestBody Map<String, Object> params) {
try {
// 参数验证
if (params == null) {
return GraceJSONResult.errorMsg("参数不能为空");
return R.fail("参数不能为空");
}
Object fileIdsObj = params.get("fileIds");
@ -339,51 +247,51 @@ public class VlogUploadController extends BaseInfoProperties {
// 如果已经是列表直接使用
fileIds = (List<String>) fileIdsObj;
} else {
return GraceJSONResult.errorMsg("媒体文件ID格式不正确");
return R.fail("媒体文件ID格式不正确");
}
if (fileIds.isEmpty()) {
return GraceJSONResult.errorMsg("媒体文件ID列表不能为空");
return R.fail("媒体文件ID列表不能为空");
}
if (fileIds.size() > 20) {
return GraceJSONResult.errorMsg("每次最多可提交20个媒体文件");
return R.fail("每次最多可提交20个媒体文件");
}
if (!"forbid".equals(operation) && !"recover".equals(operation)) {
return GraceJSONResult.errorMsg("操作类型无效只能是forbid(禁播)或recover(解禁)");
return R.fail("操作类型无效只能是forbid(禁播)或recover(解禁)");
}
// 调用服务层方法
vlogUploadService.forbidMediaDistribution(fileIds, operation);
// 返回成功结果
return GraceJSONResult.ok("操作成功");
return R.ok("操作成功");
} catch (IllegalArgumentException e) {
log.error("参数错误: {}", e.getMessage());
return GraceJSONResult.errorMsg(e.getMessage());
return R.fail(e.getMessage());
} catch (Exception e) {
log.error("操作失败: {}", e.getMessage(), e);
return GraceJSONResult.errorMsg("操作失败: " + e.getMessage());
return R.fail("操作失败: " + e.getMessage());
}
}
@ApiOperation(value = "根据vlogerId查询用户信息", notes = "查询视频上传者的姓名和电话")
@GetMapping("/user-info")
public GraceJSONResult getUserInfoByVlogerId(@RequestParam String vlogerId) {
public R<Map<String, String>> getUserInfoByVlogerId(@RequestParam String vlogerId) {
try {
if (StringUtils.isBlank(vlogerId)) {
return GraceJSONResult.errorMsg("vlogerId不能为空");
return R.fail("vlogerId不能为空");
}
// 获取视频上传者信息
Map<String, String> uploaderInfo = vlogService.getVlogUploaderInfo(vlogerId);
if (uploaderInfo == null || uploaderInfo.isEmpty()) {
return GraceJSONResult.errorMsg("未找到对应的用户信息");
return R.fail("未找到对应的用户信息");
}
return GraceJSONResult.ok(uploaderInfo);
return R.ok(uploaderInfo);
} catch (Exception e) {
log.error("获取用户信息失败", e);
return GraceJSONResult.errorMsg("获取用户信息失败: " + e.getMessage());
return R.fail("获取用户信息失败: " + e.getMessage());
}
}
}

View File

@ -1,15 +1,22 @@
package com.wzj.soopin.content.domain.bo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.wzj.soopin.content.domain.po.Vlog;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.apache.commons.lang3.StringUtils;
import org.dromara.common.core.domain.BaseBO;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class VlogBO {
@ApiModel(description = "视频查询对象")
public class VlogBO extends BaseBO {
private String id;
private String vlogerId;
private String url;
@ -20,8 +27,94 @@ public class VlogBO {
private Integer likeCounts;
private Integer commentsCounts;
private String fileId;
private Integer status;
private String reason;
private Integer cityCode;
private String firstFrameImg;
@ApiModelProperty("当前页数")
private Long current;
@ApiModelProperty("分页大小")
private Long size;
@ApiModelProperty("排序字段,例如 commentCounts, likeCounts, reason")
private String Column;
@ApiModelProperty("排序方向true 为升序false 为降序")
private Boolean asc;
@ApiModelProperty("手机号(模糊查询)")
private String mobile;
@ApiModelProperty("用户昵称(模糊查询)")
private String nickname;
@ApiModelProperty("视频标题(模糊查询)")
private String titleQuery;
@ApiModelProperty("视频状态(精确查询)")
private Integer status;
@ApiModelProperty("创建时间范围-开始时间")
private String startTime;
@ApiModelProperty("创建时间范围-结束时间")
private String endTime;
@Override
public LambdaQueryWrapper<Vlog> toWrapper() {
LambdaQueryWrapper<Vlog> wrapper = new LambdaQueryWrapper<>();
// 手机号和昵称的查询条件将不在toWrapper中处理而是在Service层处理
// if (StringUtils.isNotBlank(mobile)) {
// wrapper.like(Vlog::getMobile, mobile);
// }
// if (StringUtils.isNotBlank(nickname)) {
// wrapper.like(Vlog::getNickname, nickname);
// }
if (StringUtils.isNotBlank(titleQuery)) {
wrapper.like(Vlog::getTitle, titleQuery);
}
// 添加精确查询条件
if (status != null) {
wrapper.eq(Vlog::getStatus, status);
}
// 添加时间范围查询
if (StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime)) {
wrapper.ge(Vlog::getCreateTime, startTime);
wrapper.lt(Vlog::getCreateTime, endTime);
}
// 添加排序条件
if (StringUtils.isNotBlank(Column)) {
String column = org.dromara.common.core.utils.StringUtils.toUnderScoreCase(Column);
boolean Asc = Boolean.TRUE.equals(asc);
if ("reason".equals(column)) {
// 自定义状态排序待审核, 复审, 通过, 不通过
if (Asc) {
wrapper.apply("ORDER BY FIELD(reason, 0, 1, 2, 3)");
} else {
wrapper.apply("ORDER BY FIELD(reason, 3, 2, 1, 0)"); // 反向排序
}
} else if ("create_time".equals(column)) { // 假设create_time是Vlog的直接字段
if (Asc) {
wrapper.orderByAsc(Vlog::getCreateTime);
} else {
wrapper.orderByDesc(Vlog::getCreateTime);
}
}
// like_counts comments_counts 不在Vlog实体中无法在此直接排序
// 需要在Service层获取数据后进行内存排序或修改Mapper进行联表查询
} else {
// 默认按创建时间倒序排序
wrapper.orderByDesc(Vlog::getCreateTime);
}
return wrapper;
}
}

View File

@ -1,15 +0,0 @@
package com.wzj.soopin.content.domain.exceptions;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
/**
* 优雅的处理异常统一封装
*/
public class GraceException {
public static void display(ResponseStatusEnum responseStatusEnum) {
throw new MyCustomException(responseStatusEnum);
}
}

View File

@ -1,59 +0,0 @@
package com.wzj.soopin.content.domain.exceptions;
import com.wzj.soopin.content.domain.result.GraceJSONResult;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 统一异常拦截处理
* 可以针对异常的类型进行捕获然后返回json信息到前端
*/
@ControllerAdvice
public class GraceExceptionHandler {
@ExceptionHandler(MyCustomException.class)
@ResponseBody
public GraceJSONResult returnMyException(MyCustomException e) {
//e.printStackTrace();
return GraceJSONResult.exception(e.getResponseStatusEnum());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public GraceJSONResult returnMethodArgumentNotValid(MethodArgumentNotValidException e) {
BindingResult result = e.getBindingResult();
Map<String, String> map = getErrors(result);
return GraceJSONResult.errorMap(map);
}
@ExceptionHandler(MaxUploadSizeExceededException.class)
@ResponseBody
public GraceJSONResult returnMaxUploadSize(MaxUploadSizeExceededException e) {
// e.printStackTrace();
return GraceJSONResult.errorCustom(ResponseStatusEnum.FILE_MAX_SIZE_2MB_ERROR);
}
public Map<String, String> getErrors(BindingResult result) {
Map<String, String> map = new HashMap<>();
List<FieldError> errorList = result.getFieldErrors();
for (FieldError ff : errorList) {
// 错误所对应的属性字段名
String field = ff.getField();
// 错误的信息
String msg = ff.getDefaultMessage();
map.put(field, msg);
}
return map;
}
}

View File

@ -1,29 +0,0 @@
package com.wzj.soopin.content.domain.exceptions;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
/**
* 自定义异常
* 目的统一处理异常信息
* 便于解耦拦截器service与controller 异常错误的解耦
* 不会被service返回的类型而限制
*/
public class MyCustomException extends RuntimeException {
private ResponseStatusEnum responseStatusEnum;
public MyCustomException(ResponseStatusEnum responseStatusEnum) {
super("异常状态码为:" + responseStatusEnum.status()
+ ";具体异常信息为:" + responseStatusEnum.msg());
this.responseStatusEnum = responseStatusEnum;
}
public ResponseStatusEnum getResponseStatusEnum() {
return responseStatusEnum;
}
public void setResponseStatusEnum(ResponseStatusEnum responseStatusEnum) {
this.responseStatusEnum = responseStatusEnum;
}
}

View File

@ -1,153 +0,0 @@
package com.wzj.soopin.content.domain.result;
import java.util.Map;
/**
* 自定义响应数据类型枚举升级版本
*
* @Title: IMOOCJSONResult.java
* @Package com.imooc.utils
* @Description: 自定义响应数据结构
* 本类可提供给 H5/ios/安卓/公众号/小程序 使用
* 前端接受此类数据json object)可自行根据业务去实现相关功能
*
* @Copyright: Copyright (c) 2020
* @Company: www.imooc.com
* @author 慕课网 - 风间影月
* @version V2.0
*/
public class GraceJSONResult {
// 响应业务状态码
private Integer status;
// 响应消息
private String msg;
// 是否成功
private Boolean success;
// 响应数据可以是Object也可以是List或Map等
private Object data;
/**
* 成功返回带有数据的直接往OK方法丢data数据即可
* @param data
* @return
*/
public static GraceJSONResult ok(Object data) {
return new GraceJSONResult(data);
}
/**
* 成功返回不带有数据的直接调用ok方法data无须传入其实就是null
* @return
*/
public static GraceJSONResult ok() {
return new GraceJSONResult(ResponseStatusEnum.SUCCESS);
}
public GraceJSONResult(Object data) {
this.status = ResponseStatusEnum.SUCCESS.status();
this.msg = ResponseStatusEnum.SUCCESS.msg();
this.success = ResponseStatusEnum.SUCCESS.success();
this.data = data;
}
/**
* 错误返回直接调用error方法即可当然也可以在ResponseStatusEnum中自定义错误后再返回也都可以
* @return
*/
public static GraceJSONResult error() {
return new GraceJSONResult(ResponseStatusEnum.FAILED);
}
/**
* 错误返回map中包含了多条错误信息可以用于表单验证把错误统一的全部返回出去
* @param map
* @return
*/
public static GraceJSONResult errorMap(Map map) {
return new GraceJSONResult(ResponseStatusEnum.FAILED, map);
}
/**
* 错误返回直接返回错误的消息
* @param msg
* @return
*/
public static GraceJSONResult errorMsg(String msg) {
return new GraceJSONResult(ResponseStatusEnum.FAILED, msg);
}
/**
* 错误返回token异常一些通用的可以在这里统一定义
* @return
*/
public static GraceJSONResult errorTicket() {
return new GraceJSONResult(ResponseStatusEnum.TICKET_INVALID);
}
/**
* 自定义错误范围需要传入一个自定义的枚举可以到[ResponseStatusEnum.java[中自定义后再传入
* @param responseStatus
* @return
*/
public static GraceJSONResult errorCustom(ResponseStatusEnum responseStatus) {
return new GraceJSONResult(responseStatus);
}
public static GraceJSONResult exception(ResponseStatusEnum responseStatus) {
return new GraceJSONResult(responseStatus);
}
public GraceJSONResult(ResponseStatusEnum responseStatus) {
this.status = responseStatus.status();
this.msg = responseStatus.msg();
this.success = responseStatus.success();
}
public GraceJSONResult(ResponseStatusEnum responseStatus, Object data) {
this.status = responseStatus.status();
this.msg = responseStatus.msg();
this.success = responseStatus.success();
this.data = data;
}
public GraceJSONResult(ResponseStatusEnum responseStatus, String msg) {
this.status = responseStatus.status();
this.msg = msg;
this.success = responseStatus.success();
}
public GraceJSONResult() {
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
}

View File

@ -1,135 +0,0 @@
package com.wzj.soopin.content.domain.result;
/**
*
* @Title: IMOOCJSONResult.java
* @Package com.imooc.utils
* @Description: 自定义响应数据结构
* 本类可提供给 H5/ios/安卓/公众号/小程序 使用
* 前端接受此类数据json object)可自行根据业务去实现相关功能
*
* 200表示成功
* 500表示错误错误信息在msg字段中
* 501bean验证错误不管多少个错误都以map形式返回
* 502拦截器拦截到用户token出错
* 555异常抛出信息
* 556: 用户qq校验异常
* 557: 校验用户是否在CAS登录用户门票的校验
* @Copyright: Copyright (c) 2020
* @Company: www.imooc.com
* @author 慕课网 - 风间影月
* @version V1.0
*/
public class IMOOCJSONResult {
// 响应业务状态
private Integer status;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
private String ok; // 不使用
public static IMOOCJSONResult build(Integer status, String msg, Object data) {
return new IMOOCJSONResult(status, msg, data);
}
public static IMOOCJSONResult build(Integer status, String msg, Object data, String ok) {
return new IMOOCJSONResult(status, msg, data, ok);
}
public static IMOOCJSONResult ok(Object data) {
return new IMOOCJSONResult(data);
}
public static IMOOCJSONResult ok() {
return new IMOOCJSONResult(null);
}
public static IMOOCJSONResult errorMsg(String msg) {
return new IMOOCJSONResult(500, msg, null);
}
public static IMOOCJSONResult errorUserTicket(String msg) {
return new IMOOCJSONResult(557, msg, null);
}
public static IMOOCJSONResult errorMap(Object data) {
return new IMOOCJSONResult(501, "error", data);
}
public static IMOOCJSONResult errorTokenMsg(String msg) {
return new IMOOCJSONResult(502, msg, null);
}
public static IMOOCJSONResult errorException(String msg) {
return new IMOOCJSONResult(555, msg, null);
}
public static IMOOCJSONResult errorUserQQ(String msg) {
return new IMOOCJSONResult(556, msg, null);
}
public IMOOCJSONResult() {
}
public IMOOCJSONResult(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public IMOOCJSONResult(Integer status, String msg, Object data, String ok) {
this.status = status;
this.msg = msg;
this.data = data;
this.ok = ok;
}
public IMOOCJSONResult(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
}
public Boolean isOK() {
return this.status == 200;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getOk() {
return ok;
}
public void setOk(String ok) {
this.ok = ok;
}
}

View File

@ -1,108 +0,0 @@
package com.wzj.soopin.content.domain.result;
/**
* 响应结果枚举用于提供给GraceJSONResult返回给前端的
* 本枚举类中包含了很多的不同的状态码供使用可以自定义
* 便于更优雅的对状态码进行管理一目了然
*/
public enum ResponseStatusEnum {
SUCCESS(200, true, "操作成功!"),
FAILED(500, false, "操作失败!"),
ON_BLOCK(201,false,"用户已被拉黑"),
// 50x
UN_LOGIN(501,false,"请登录后再继续操作!"),
TICKET_INVALID(502,false,"会话失效,请重新登录!"),
NO_AUTH(503,false,"您的权限不足,无法继续操作!"),
MOBILE_ERROR(504,false,"短信发送失败,请稍后重试!"),
SMS_NEED_WAIT_ERROR(505,false,"短信发送太快啦~请稍后再试!"),
SMS_CODE_ERROR(506,false,"验证码过期或不匹配,请稍后再试!"),
USER_FROZEN(507,false,"用户已被冻结,请联系管理员!"),
USER_UPDATE_ERROR(508,false,"用户信息更新失败,请联系管理员!"),
USER_INACTIVE_ERROR(509,false,"请前往[账号设置]修改信息激活后再进行后续操作!"),
USER_INFO_UPDATED_ERROR(5091,false,"用户信息修改失败!"),
USER_INFO_UPDATED_NICKNAME_EXIST_ERROR(5092,false,"昵称已经存在!"),
FANS_INFO_UPDATED_ISFAN_EXIST_ERROR(5092,false,"已关注"),
FANS_INFO_UPDATED_ISFLOW_EXIST_ERROR(5092,false,"未关注"),
USER_INFO_UPDATED_IMOOCNUM_EXIST_ERROR(5092,false,"视频号已经存在!"),
USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR(5092,false,"视频号无法修改!"),
FILE_UPLOAD_NULL_ERROR(510,false,"文件不能为空,请选择一个文件再上传!"),
FILE_UPLOAD_FAILD(511,false,"文件上传失败!"),
FILE_FORMATTER_FAILD(512,false,"文件图片格式不支持!"),
FILE_MAX_SIZE_500KB_ERROR(5131,false,"仅支持500kb大小以下的图片上传"),
FILE_MAX_SIZE_2MB_ERROR(5132,false,"仅支持2MB大小以下的图片上传"),
FILE_NOT_EXIST_ERROR(514,false,"你所查看的文件不存在!"),
USER_STATUS_ERROR(515,false,"用户状态参数出错!"),
USER_NOT_EXIST_ERROR(516,false,"用户不存在!"),
USER_PASSWORD_ERROR(517,false,"密码错误!"),
// 自定义系统级别异常 54x
SYSTEM_INDEX_OUT_OF_BOUNDS(541, false, "系统错误,数组越界!"),
SYSTEM_ARITHMETIC_BY_ZERO(542, false, "系统错误,无法除零!"),
SYSTEM_NULL_POINTER(543, false, "系统错误,空指针!"),
SYSTEM_NUMBER_FORMAT(544, false, "系统错误,数字转换异常!"),
SYSTEM_PARSE(545, false, "系统错误,解析异常!"),
SYSTEM_IO(546, false, "系统错误IO输入输出异常"),
SYSTEM_FILE_NOT_FOUND(547, false, "系统错误,文件未找到!"),
SYSTEM_CLASS_CAST(548, false, "系统错误,类型强制转换错误!"),
SYSTEM_PARSER_ERROR(549, false, "系统错误,解析出错!"),
SYSTEM_DATE_PARSER_ERROR(550, false, "系统错误,日期解析出错!"),
// admin 管理系统 56x
ADMIN_USERNAME_NULL_ERROR(561, false, "管理员登录名不能为空!"),
ADMIN_USERNAME_EXIST_ERROR(562, false, "管理员登录名已存在!"),
ADMIN_NAME_NULL_ERROR(563, false, "管理员负责人不能为空!"),
ADMIN_PASSWORD_ERROR(564, false, "密码不能为空后者两次输入不一致!"),
ADMIN_CREATE_ERROR(565, false, "添加管理员失败!"),
ADMIN_PASSWORD_NULL_ERROR(566, false, "密码不能为空!"),
ADMIN_NOT_EXIT_ERROR(567, false, "管理员不存在或密码错误!"),
ADMIN_FACE_NULL_ERROR(568, false, "人脸信息不能为空!"),
ADMIN_FACE_LOGIN_ERROR(569, false, "人脸识别失败,请重试!"),
CATEGORY_EXIST_ERROR(570, false, "文章分类已存在,请换一个分类名!"),
// 媒体中心 相关错误 58x
ARTICLE_COVER_NOT_EXIST_ERROR(580, false, "文章封面不存在,请选择一个!"),
ARTICLE_CATEGORY_NOT_EXIST_ERROR(581, false, "请选择正确的文章领域!"),
ARTICLE_CREATE_ERROR(582, false, "创建文章失败,请重试或联系管理员!"),
ARTICLE_QUERY_PARAMS_ERROR(583, false, "文章列表查询参数错误!"),
ARTICLE_DELETE_ERROR(584, false, "文章删除失败!"),
ARTICLE_WITHDRAW_ERROR(585, false, "文章撤回失败!"),
ARTICLE_REVIEW_ERROR(585, false, "文章审核出错!"),
ARTICLE_ALREADY_READ_ERROR(586, false, "文章重复阅读!"),
// 人脸识别错误代码
FACE_VERIFY_TYPE_ERROR(600, false, "人脸比对验证类型不正确!"),
FACE_VERIFY_LOGIN_ERROR(601, false, "人脸登录失败!"),
// 系统错误未预期的错误 555
SYSTEM_ERROR(555, false, "系统繁忙,请稍后再试!"),
SYSTEM_OPERATION_ERROR(556, false, "操作失败,请重试或联系管理员"),
SYSTEM_RESPONSE_NO_INFO(557, false, ""),
SYSTEM_ERROR_GLOBAL(558, false, "全局降级:系统繁忙,请稍后再试!"),
SYSTEM_ERROR_FEIGN(559, false, "客户端Feign降级系统繁忙请稍后再试"),
SYSTEM_ERROR_ZUUL(560, false, "请求系统过于繁忙,请稍后再试!");
// 响应业务状态
private Integer status;
// 调用是否成功
private Boolean success;
// 响应消息可以为成功或者失败的消息
private String msg;
ResponseStatusEnum(Integer status, Boolean success, String msg) {
this.status = status;
this.success = success;
this.msg = msg;
}
public Integer status() {
return status;
}
public Boolean success() {
return success;
}
public String msg() {
return msg;
}
}

View File

@ -1,7 +1,7 @@
package com.wzj.soopin.content.enums;
import com.wzj.soopin.content.domain.exceptions.GraceException;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
import org.dromara.common.core.exception.ServiceException;
/**
* @Desc: 修改用户信息类型 枚举
@ -29,7 +29,7 @@ public enum UserInfoModifyType {
type != UserInfoModifyType.BIRTHDAY.type &&
type != UserInfoModifyType.LOCATION.type &&
type != UserInfoModifyType.DESC.type) {
GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_ERROR);
throw new ServiceException("用户信息修改失败!");
}
}
@ -39,7 +39,6 @@ public enum UserInfoModifyType {
return modifyType;
}
}
GraceException.display(ResponseStatusEnum.USER_INFO_UPDATED_ERROR);
return null;
throw new ServiceException("用户信息修改失败!");
}
}

View File

@ -1,48 +0,0 @@
package com.wzj.soopin.content.intercepter;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.exceptions.GraceException;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
import com.wzj.soopin.content.utils.IPUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
public class PassportInterceptor extends BaseInfoProperties implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 获得用户的ip
String userIp = IPUtil.getRequestIp(request);
// 得到是否存在的判断
boolean keyIsExist = redis.keyIsExist(MOBILE_SMSCODE + ":" + userIp);
if (keyIsExist) {
GraceException.display(ResponseStatusEnum.SMS_NEED_WAIT_ERROR);
log.info("短信发送频率太大!");
return false;
}
/**
* true: 请求放行
* false: 请求拦截
*/
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}

View File

@ -1,59 +0,0 @@
package com.wzj.soopin.content.intercepter;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.exceptions.GraceException;
import com.wzj.soopin.content.domain.result.ResponseStatusEnum;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Slf4j
public class UserTokenInterceptor extends BaseInfoProperties implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 从header中获得用户id和token
String userId = request.getHeader("headerUserId");
String userToken = request.getHeader("headerUserToken");
// 判断header中用户id和token不能为空
if (StringUtils.isNotBlank(userId) && StringUtils.isNotBlank(userToken)) {
String redisToken = redis.get(REDIS_USER_TOKEN + ":" + userId);
if (StringUtils.isBlank(redisToken)) {
GraceException.display(ResponseStatusEnum.UN_LOGIN);
return false;
} else {
// 比较token是否一致如果不一致表示用户在别的手机端登录
if (!redisToken.equalsIgnoreCase(userToken)) {
GraceException.display(ResponseStatusEnum.TICKET_INVALID);
return false;
}
}
} else {
GraceException.display(ResponseStatusEnum.UN_LOGIN);
return false;
}
/**
* true: 请求放行
* false: 请求拦截
*/
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}

View File

@ -2,6 +2,7 @@ package com.wzj.soopin.content.mapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.content.domain.bo.CommentBO;
import com.wzj.soopin.content.domain.po.Comment;
import com.wzj.soopin.content.domain.vo.CommentVO;
import org.apache.ibatis.annotations.Param;
@ -26,4 +27,12 @@ public interface CommentMapperCustom extends BaseMapperPlus<Comment, CommentVO>
*/
IPage<CommentVO> selectByMobileAndVlogId(Page<?> page, @Param("mobile") String mobile, @Param("vlogId") String vlogId);
/**
* 分页查询评论并按点赞数量进行聚合排序
* @param page 分页对象
* @param bo 评论业务对象包含排序信息
* @return 分页的评论VO列表
*/
IPage<CommentVO> selectCommentsWithAggregatedLikes(Page<CommentVO> page, @Param("bo") CommentBO bo);
}

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.po.Vlog;
import com.wzj.soopin.content.domain.vo.CommentVO;
import com.wzj.soopin.content.domain.vo.IndexVlogVO;
@ -85,4 +86,12 @@ public interface VlogMapper extends BaseMapper<Vlog> {
IPage<Map<String, Object>> selectVlogList(Page<Map<String, Object>> page, @Param("params") Map<String, Object> params);
IPage<CommentVO> selectByMobileAndVlogId(Page<?> page, @Param("mobile") String mobile, @Param("vlogId") String vlogId);
/**
* 分页查询视频列表包含点赞数和评论数并支持按这些聚合字段进行全局排序
* @param page 分页对象
* @param vlogBO 查询和排序参数
* @return 分页结果包含视频信息及统计数据
*/
IPage<Map<String, Object>> selectVlogListWithAggregatedData(Page<Map<String, Object>> page, @Param("vlogBO") VlogBO vlogBO);
}

View File

@ -1,152 +0,0 @@
package com.wzj.soopin.content.result;
import java.util.Map;
/**
* 自定义响应数据类型枚举升级版本
*
* @Title: IMOOCJSONResult.java
* @Package com.imooc.utils
* @Description: 自定义响应数据结构
* 本类可提供给 H5/ios/安卓/公众号/小程序 使用
* 前端接受此类数据json object)可自行根据业务去实现相关功能
*
* @Copyright: Copyright (c) 2020
* @Company: www.imooc.com
* @author 慕课网 - 风间影月
* @version V2.0 */
public class GraceJSONResult {
// 响应业务状态码
private Integer status;
// 响应消息
private String msg;
// 是否成功
private Boolean success;
// 响应数据可以是Object也可以是List或Map等
private Object data;
/**
* 成功返回带有数据的直接往OK方法丢data数据即可
* @param data
* @return
*/
public static GraceJSONResult ok(Object data) {
return new GraceJSONResult(data);
}
/**
* 成功返回不带有数据的直接调用ok方法data无须传入其实就是null
* @return
*/
public static GraceJSONResult ok() {
return new GraceJSONResult(ResponseStatusEnum.SUCCESS);
}
public GraceJSONResult(Object data) {
this.status = ResponseStatusEnum.SUCCESS.status();
this.msg = ResponseStatusEnum.SUCCESS.msg();
this.success = ResponseStatusEnum.SUCCESS.success();
this.data = data;
}
/**
* 错误返回直接调用error方法即可当然也可以在ResponseStatusEnum中自定义错误后再返回也都可以
* @return
*/
public static GraceJSONResult error() {
return new GraceJSONResult(ResponseStatusEnum.FAILED);
}
/**
* 错误返回map中包含了多条错误信息可以用于表单验证把错误统一的全部返回出去
* @param map
* @return
*/
public static GraceJSONResult errorMap(Map map) {
return new GraceJSONResult(ResponseStatusEnum.FAILED, map);
}
/**
* 错误返回直接返回错误的消息
* @param msg
* @return
*/
public static GraceJSONResult errorMsg(String msg) {
return new GraceJSONResult(ResponseStatusEnum.FAILED, msg);
}
/**
* 错误返回token异常一些通用的可以在这里统一定义
* @return
*/
public static GraceJSONResult errorTicket() {
return new GraceJSONResult(ResponseStatusEnum.TICKET_INVALID);
}
/**
* 自定义错误范围需要传入一个自定义的枚举可以到[ResponseStatusEnum.java[中自定义后再传入
* @param responseStatus
* @return
*/
public static GraceJSONResult errorCustom(ResponseStatusEnum responseStatus) {
return new GraceJSONResult(responseStatus);
}
public static GraceJSONResult exception(ResponseStatusEnum responseStatus) {
return new GraceJSONResult(responseStatus);
}
public GraceJSONResult(ResponseStatusEnum responseStatus) {
this.status = responseStatus.status();
this.msg = responseStatus.msg();
this.success = responseStatus.success();
}
public GraceJSONResult(ResponseStatusEnum responseStatus, Object data) {
this.status = responseStatus.status();
this.msg = responseStatus.msg();
this.success = responseStatus.success();
this.data = data;
}
public GraceJSONResult(ResponseStatusEnum responseStatus, String msg) {
this.status = responseStatus.status();
this.msg = msg;
this.success = responseStatus.success();
}
public GraceJSONResult() {
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
}

View File

@ -1,135 +0,0 @@
package com.wzj.soopin.content.result;
/**
*
* @Title: IMOOCJSONResult.java
* @Package com.imooc.utils
* @Description: 自定义响应数据结构
* 本类可提供给 H5/ios/安卓/公众号/小程序 使用
* 前端接受此类数据json object)可自行根据业务去实现相关功能
*
* 200表示成功
* 500表示错误错误信息在msg字段中
* 501bean验证错误不管多少个错误都以map形式返回
* 502拦截器拦截到用户token出错
* 555异常抛出信息
* 556: 用户qq校验异常
* 557: 校验用户是否在CAS登录用户门票的校验
* @Copyright: Copyright (c) 2020
* @Company: www.imooc.com
* @author 慕课网 - 风间影月
* @version V1.0
*/
public class IMOOCJSONResult {
// 响应业务状态
private Integer status;
// 响应消息
private String msg;
// 响应中的数据
private Object data;
private String ok; // 不使用
public static IMOOCJSONResult build(Integer status, String msg, Object data) {
return new IMOOCJSONResult(status, msg, data);
}
public static IMOOCJSONResult build(Integer status, String msg, Object data, String ok) {
return new IMOOCJSONResult(status, msg, data, ok);
}
public static IMOOCJSONResult ok(Object data) {
return new IMOOCJSONResult(data);
}
public static IMOOCJSONResult ok() {
return new IMOOCJSONResult(null);
}
public static IMOOCJSONResult errorMsg(String msg) {
return new IMOOCJSONResult(500, msg, null);
}
public static IMOOCJSONResult errorUserTicket(String msg) {
return new IMOOCJSONResult(557, msg, null);
}
public static IMOOCJSONResult errorMap(Object data) {
return new IMOOCJSONResult(501, "error", data);
}
public static IMOOCJSONResult errorTokenMsg(String msg) {
return new IMOOCJSONResult(502, msg, null);
}
public static IMOOCJSONResult errorException(String msg) {
return new IMOOCJSONResult(555, msg, null);
}
public static IMOOCJSONResult errorUserQQ(String msg) {
return new IMOOCJSONResult(556, msg, null);
}
public IMOOCJSONResult() {
}
public IMOOCJSONResult(Integer status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
public IMOOCJSONResult(Integer status, String msg, Object data, String ok) {
this.status = status;
this.msg = msg;
this.data = data;
this.ok = ok;
}
public IMOOCJSONResult(Object data) {
this.status = 200;
this.msg = "OK";
this.data = data;
}
public Boolean isOK() {
return this.status == 200;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getOk() {
return ok;
}
public void setOk(String ok) {
this.ok = ok;
}
}

View File

@ -1,108 +0,0 @@
package com.wzj.soopin.content.result;
/**
* 响应结果枚举用于提供给GraceJSONResult返回给前端的
* 本枚举类中包含了很多的不同的状态码供使用可以自定义
* 便于更优雅的对状态码进行管理一目了然
*/
public enum ResponseStatusEnum {
SUCCESS(200, true, "操作成功!"),
FAILED(500, false, "操作失败!"),
ON_BLOCK(201,false,"用户已被拉黑"),
// 50x
UN_LOGIN(501,false,"请登录后再继续操作!"),
TICKET_INVALID(502,false,"会话失效,请重新登录!"),
NO_AUTH(503,false,"您的权限不足,无法继续操作!"),
MOBILE_ERROR(504,false,"短信发送失败,请稍后重试!"),
SMS_NEED_WAIT_ERROR(505,false,"短信发送太快啦~请稍后再试!"),
SMS_CODE_ERROR(506,false,"验证码过期或不匹配,请稍后再试!"),
USER_FROZEN(507,false,"用户已被冻结,请联系管理员!"),
USER_UPDATE_ERROR(508,false,"用户信息更新失败,请联系管理员!"),
USER_INACTIVE_ERROR(509,false,"请前往[账号设置]修改信息激活后再进行后续操作!"),
USER_INFO_UPDATED_ERROR(5091,false,"用户信息修改失败!"),
USER_INFO_UPDATED_NICKNAME_EXIST_ERROR(5092,false,"昵称已经存在!"),
FANS_INFO_UPDATED_ISFAN_EXIST_ERROR(5092,false,"已关注"),
FANS_INFO_UPDATED_ISFLOW_EXIST_ERROR(5092,false,"未关注"),
USER_INFO_UPDATED_IMOOCNUM_EXIST_ERROR(5092,false,"视频号已经存在!"),
USER_INFO_CANT_UPDATED_IMOOCNUM_ERROR(5092,false,"视频号无法修改!"),
FILE_UPLOAD_NULL_ERROR(510,false,"文件不能为空,请选择一个文件再上传!"),
FILE_UPLOAD_FAILD(511,false,"文件上传失败!"),
FILE_FORMATTER_FAILD(512,false,"文件图片格式不支持!"),
FILE_MAX_SIZE_500KB_ERROR(5131,false,"仅支持500kb大小以下的图片上传"),
FILE_MAX_SIZE_2MB_ERROR(5132,false,"仅支持2MB大小以下的图片上传"),
FILE_NOT_EXIST_ERROR(514,false,"你所查看的文件不存在!"),
USER_STATUS_ERROR(515,false,"用户状态参数出错!"),
USER_NOT_EXIST_ERROR(516,false,"用户不存在!"),
USER_PASSWORD_ERROR(517,false,"密码错误!"),
// 自定义系统级别异常 54x
SYSTEM_INDEX_OUT_OF_BOUNDS(541, false, "系统错误,数组越界!"),
SYSTEM_ARITHMETIC_BY_ZERO(542, false, "系统错误,无法除零!"),
SYSTEM_NULL_POINTER(543, false, "系统错误,空指针!"),
SYSTEM_NUMBER_FORMAT(544, false, "系统错误,数字转换异常!"),
SYSTEM_PARSE(545, false, "系统错误,解析异常!"),
SYSTEM_IO(546, false, "系统错误IO输入输出异常"),
SYSTEM_FILE_NOT_FOUND(547, false, "系统错误,文件未找到!"),
SYSTEM_CLASS_CAST(548, false, "系统错误,类型强制转换错误!"),
SYSTEM_PARSER_ERROR(549, false, "系统错误,解析出错!"),
SYSTEM_DATE_PARSER_ERROR(550, false, "系统错误,日期解析出错!"),
// admin 管理系统 56x
ADMIN_USERNAME_NULL_ERROR(561, false, "管理员登录名不能为空!"),
ADMIN_USERNAME_EXIST_ERROR(562, false, "管理员登录名已存在!"),
ADMIN_NAME_NULL_ERROR(563, false, "管理员负责人不能为空!"),
ADMIN_PASSWORD_ERROR(564, false, "密码不能为空后者两次输入不一致!"),
ADMIN_CREATE_ERROR(565, false, "添加管理员失败!"),
ADMIN_PASSWORD_NULL_ERROR(566, false, "密码不能为空!"),
ADMIN_NOT_EXIT_ERROR(567, false, "管理员不存在或密码错误!"),
ADMIN_FACE_NULL_ERROR(568, false, "人脸信息不能为空!"),
ADMIN_FACE_LOGIN_ERROR(569, false, "人脸识别失败,请重试!"),
CATEGORY_EXIST_ERROR(570, false, "文章分类已存在,请换一个分类名!"),
// 媒体中心 相关错误 58x
ARTICLE_COVER_NOT_EXIST_ERROR(580, false, "文章封面不存在,请选择一个!"),
ARTICLE_CATEGORY_NOT_EXIST_ERROR(581, false, "请选择正确的文章领域!"),
ARTICLE_CREATE_ERROR(582, false, "创建文章失败,请重试或联系管理员!"),
ARTICLE_QUERY_PARAMS_ERROR(583, false, "文章列表查询参数错误!"),
ARTICLE_DELETE_ERROR(584, false, "文章删除失败!"),
ARTICLE_WITHDRAW_ERROR(585, false, "文章撤回失败!"),
ARTICLE_REVIEW_ERROR(585, false, "文章审核出错!"),
ARTICLE_ALREADY_READ_ERROR(586, false, "文章重复阅读!"),
// 人脸识别错误代码
FACE_VERIFY_TYPE_ERROR(600, false, "人脸比对验证类型不正确!"),
FACE_VERIFY_LOGIN_ERROR(601, false, "人脸登录失败!"),
// 系统错误未预期的错误 555
SYSTEM_ERROR(555, false, "系统繁忙,请稍后再试!"),
SYSTEM_OPERATION_ERROR(556, false, "操作失败,请重试或联系管理员"),
SYSTEM_RESPONSE_NO_INFO(557, false, ""),
SYSTEM_ERROR_GLOBAL(558, false, "全局降级:系统繁忙,请稍后再试!"),
SYSTEM_ERROR_FEIGN(559, false, "客户端Feign降级系统繁忙请稍后再试"),
SYSTEM_ERROR_ZUUL(560, false, "请求系统过于繁忙,请稍后再试!");
// 响应业务状态
private Integer status;
// 调用是否成功
private Boolean success;
// 响应消息可以为成功或者失败的消息
private String msg;
ResponseStatusEnum(Integer status, Boolean success, String msg) {
this.status = status;
this.success = success;
this.msg = msg;
}
public Integer status() {
return status;
}
public Boolean success() {
return success;
}
public String msg() {
return msg;
}
}

View File

@ -146,8 +146,8 @@ public interface VlogService {
/**
* 分页查询视频列表
* @param page 分页对象
* @param params 查询参数
* @param vlogBO 查询条件
* @return 分页结果
*/
IPage<Map<String, Object>> getVlogListByMobile(Page<Map<String, Object>> page, Map<String, Object> params);
IPage<Map<String, Object>> getVlogListByMobile(Page<Map<String, Object>> page, VlogBO vlogBO);
}

View File

@ -172,6 +172,13 @@ public class CommentServiceImpl extends BaseInfoProperties implements CommentSer
@Override
public Page<CommentVO> pageComment(Page<Comment> page, CommentBO bo) {
// 如果是按点赞数排序则调用新的Mapper方法进行聚合排序
// if (bo != null && "likeCounts".equals(bo.getColumn())) {
// Page<CommentVO> voPage = new Page<>(page.getCurrent(), page.getSize());
// commentMapperCustom.selectCommentsWithAggregatedLikes(voPage, bo);
// return voPage;
// }
LambdaQueryWrapper<Comment> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Comment::getFatherCommentId, "0");

View File

@ -8,6 +8,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.bo.VlogBO;
import com.wzj.soopin.content.domain.po.MyLikedVlog;
import com.wzj.soopin.content.domain.po.Vlog;
@ -25,7 +26,6 @@ import com.wzj.soopin.content.utils.PagedGridResult;
import com.wzj.soopin.content.utils.RedisOperator;
import com.wzj.soopin.content.utils.Sid;
import com.wzj.soopin.content.utils.TencentCloudUtil;
import com.wzj.soopin.member.domain.vo.FansVO;
import com.wzj.soopin.member.service.IFansService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
@ -33,6 +33,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@ -410,7 +414,7 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
result.put("vlogId", null);
result.put("likeCounts", 0);
result.put("commentCounts", 0);
result.put("reason",vlog.getReason());
result.put("reason", null);
result.put("fansCounts", 0);
}
@ -508,7 +512,53 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
}
@Override
public IPage<Map<String, Object>> getVlogListByMobile(Page<Map<String, Object>> page, Map<String, Object> params) {
return vlogMapper.selectVlogList(page, params);
public IPage<Map<String, Object>> getVlogListByMobile(Page<Map<String, Object>> page, VlogBO vlogBO) {
// 统一调用新的Mapper方法进行查询和排序
// 预处理时间字符串确保转换为MySQL DATETIME兼容格式
String beginTimeStr = vlogBO.getStartTime();
if (StringUtils.isNotBlank(beginTimeStr)) {
try {
// 移除双引号解析为 Instant然后转换为 LocalDateTime
String cleanedBeginTimeStr = beginTimeStr.trim().replace("\"", "");
System.out.println("Original beginTimeStr: " + beginTimeStr);
System.out.println("Cleaned beginTimeStr: " + cleanedBeginTimeStr);
Instant instant = Instant.parse(cleanedBeginTimeStr);
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
String formattedDateTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("Formatted startTime: " + formattedDateTime);
vlogBO.setStartTime(formattedDateTime);
} catch (Exception e) {
// 处理解析异常例如日志记录
System.err.println("Error parsing beginTime: " + beginTimeStr + " - " + e.getMessage());
vlogBO.setStartTime(null); // 设置为null以避免SQL错误
}
} else {
System.out.println("beginTimeStr is blank or null.");
vlogBO.setStartTime(null);
}
String endTimeStr = vlogBO.getEndTime();
if (StringUtils.isNotBlank(endTimeStr)) {
try {
// 移除双引号解析为 Instant然后转换为 LocalDateTime
String cleanedEndTimeStr = endTimeStr.trim().replace("\"", "");
System.out.println("Original endTimeStr: " + endTimeStr);
System.out.println("Cleaned endTimeStr: " + cleanedEndTimeStr);
Instant instant = Instant.parse(cleanedEndTimeStr);
LocalDateTime dateTime = LocalDateTime.ofInstant(instant, ZoneOffset.UTC);
String formattedDateTime = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println("Formatted endTime: " + formattedDateTime);
vlogBO.setEndTime(formattedDateTime);
} catch (Exception e) {
// 处理解析异常例如日志记录
System.err.println("Error parsing endTime: " + endTimeStr + " - " + e.getMessage());
vlogBO.setEndTime(null); // 设置为null以避免SQL错误
}
} else {
System.out.println("endTimeStr is blank or null.");
vlogBO.setEndTime(null);
}
return vlogMapper.selectVlogListWithAggregatedData(page, vlogBO);
}
}

View File

@ -1,9 +0,0 @@
package com.wzj.soopin.content.utils;
public class MyInfo {
public static String getMobile() {
return "";
}
}

View File

@ -1,12 +0,0 @@
package com.wzj.soopin.content.utils;
public class Test {
public static void main(String[] args) {
for (int i = 0 ; i < 1000 ; i ++) {
// System.out.println(Sid.nextShort());
}
}
}

View File

@ -77,12 +77,12 @@
u.face as vlogerFace,
u.nickname as vlogerName,
v.title as content,
v.url as url,
v.url as mediaUrl,
v.cover as cover,
v.width as width,
v.height as height,
v.like_counts as likeCounts,
v.comments_counts as commentsCounts,
v.comments_counts as commentCounts,
v.is_private as isPrivate,
v.city_code as cityCode,
v.reason as reason,
@ -132,12 +132,12 @@
u.face as vlogerFace,
u.nickname as vlogerName,
v.title as content,
v.url as url,
v.url as mediaUrl,
v.cover as cover,
v.width as width,
v.height as height,
v.like_counts as likeCounts,
v.comments_counts as commentsCounts,
v.comments_counts as commentCounts,
v.is_private as isPrivate,
v.city_code as cityCode,
v.reason as reason,
@ -172,55 +172,8 @@
SELECT * FROM t_vlog WHERE file_id = #{fileId}
</select>
<select id="selectVlogList" resultType="java.util.Map">
SELECT
v.id,
v.vloger_id,
v.url as mediaUrl,
v.cover,
v.title,
v.width,
v.height,
v.like_counts as likeCounts,
v.comments_counts as commentCounts,
v.is_private,
v.status,
v.file_id,
v.reason,
v.city_code,
v.first_frame_img as coverUrl,
v.create_time,
v.update_time,
m.mobile,
m.nickname
FROM
t_vlog v
LEFT JOIN t_users m ON v.vloger_id = m.id
<where>
<if test="params.mobile != null and params.mobile != ''">
AND m.mobile LIKE CONCAT('%', #{params.mobile}, '%')
</if>
<if test="params.nickname != null and params.nickname != ''">
AND m.nickname LIKE CONCAT('%', #{params.nickname}, '%')
</if>
<if test="params.title != null and params.title != ''">
AND v.title LIKE CONCAT('%', #{params.title}, '%')
</if>
<if test="params.status != null">
AND v.status = #{params.status}
</if>
<if test="params.startTime != null">
AND v.create_time >= #{params.startTime}
</if>
<if test="params.endTime != null">
AND v.create_time &lt;= #{params.endTime}
</if>
</where>
ORDER BY v.create_time DESC
</select>
<select id="selectByMobileAndVlogId" resultType="com.wzj.soopin.content.domain.vo.CommentVO">
SELECT
SELECT
c.id,
c.id as commentId,
c.vloger_id as vlogerId,
@ -246,5 +199,88 @@
ORDER BY c.create_time DESC
</select>
<select id="selectVlogListWithAggregatedData" resultType="java.util.Map">
SELECT
v.id,
v.vloger_id,
v.url as mediaUrl,
v.cover,
v.title,
v.width,
v.height,
COUNT(DISTINCT mlv.id) AS likeCounts,
COUNT(DISTINCT c.id) AS commentCounts,
v.file_id as fileId,
v.status,
v.reason,
v.city_code,
v.first_frame_img as coverUrl,
v.create_time as createTime,
v.update_time,
v.create_by,
v.update_by,
u.nickname,
u.mobile
FROM
t_vlog v
LEFT JOIN
t_users u ON v.vloger_id = u.id
LEFT JOIN
t_my_liked_vlog mlv ON v.id = mlv.vlog_id
LEFT JOIN
t_comment c ON v.id = c.vlog_id AND (c.father_comment_id = '0' OR c.father_comment_id IS NULL)
<where>
<if test="vlogBO.mobile != null and vlogBO.mobile != ''">
AND u.mobile LIKE CONCAT('%', #{vlogBO.mobile}, '%')
</if>
<if test="vlogBO.nickname != null and vlogBO.nickname != ''">
AND u.nickname LIKE CONCAT('%', #{vlogBO.nickname}, '%')
</if>
<if test="vlogBO.titleQuery != null and vlogBO.titleQuery != ''">
AND v.title LIKE CONCAT('%', #{vlogBO.titleQuery}, '%')
</if>
<if test="vlogBO.status != null">
AND v.status = #{vlogBO.status}
</if>
<if test="vlogBO.startTime != null and vlogBO.startTime != '' and vlogBO.endTime != null and vlogBO.endTime != ''">
AND v.create_time BETWEEN #{vlogBO.startTime} AND #{vlogBO.endTime}
</if>
</where>
GROUP BY
v.id,
v.vloger_id,
v.url,
v.cover,
v.title,
v.width,
v.height,
v.file_id,
v.status,
v.reason,
v.city_code,
v.first_frame_img,
v.create_time,
v.update_time,
v.create_by,
v.update_by,
u.nickname,
u.mobile
ORDER BY
<choose>
<when test="vlogBO.column == 'likeCounts'">
likeCounts ${vlogBO.asc ? 'ASC' : 'DESC'}
</when>
<when test="vlogBO.column == 'commentCounts'">
commentCounts ${vlogBO.asc ? 'ASC' : 'DESC'}
</when>
<when test="vlogBO.column == 'status'">
FIELD(v.status, 0, 1, 2, 3) ${vlogBO.asc ? 'ASC' : 'DESC'}
</when>
<otherwise>
v.create_time DESC
</otherwise>
</choose>
</select>
</mapper>