Merge remote-tracking branch 'origin/main' into wzj-main

# Conflicts:
#	ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/SysTenantAccountBo.java
#	ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTenantAccountVo.java
This commit is contained in:
fxh 2025-08-12 14:57:38 +08:00
commit ad580e3f99
23 changed files with 342 additions and 58 deletions

View File

@ -103,7 +103,7 @@ spring.data:
# 地址 # 地址
host: localhost host: localhost
# 端口默认为6379 # 端口默认为6379
port: 6379 port: 26379
# 数据库索引 # 数据库索引
database: 0 database: 0
# redis 密码必须配置 # redis 密码必须配置

View File

@ -13,11 +13,11 @@ import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam; import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.mybatis.core.page.PageQuery; // import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; // import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.web.core.BaseController; import org.dromara.common.web.core.BaseController;
import org.dromara.common.core.constant.HttpStatus; // import org.dromara.common.core.constant.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -25,7 +25,11 @@ import org.springframework.web.bind.annotation.*;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.Collections; import com.wzj.soopin.content.utils.RedisOperator;
import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.enums.MessageEnum;
// import com.wzj.soopin.content.domain.po.Comment;
@Slf4j @Slf4j
@Api(tags = "管理端-评论管理接口") @Api(tags = "管理端-评论管理接口")
@ -36,6 +40,12 @@ public class CommentController extends BaseController {
@Autowired @Autowired
private CommentService commentService; private CommentService commentService;
@Autowired
private RedisOperator redis;
@Autowired
private MsgService msgService;
@ApiOperation("获取评论列表") @ApiOperation("获取评论列表")
@PostMapping("/list") @PostMapping("/list")
public R<Page<CommentVO>> list( public R<Page<CommentVO>> list(
@ -62,6 +72,51 @@ public class CommentController extends BaseController {
} }
} }
@ApiOperation("发布评论")
@PostMapping("/publish")
public R<Void> publishComment(@RequestBody CommentBO bo) {
try {
// 鉴权评论人从登录上下文获取覆盖入参
Long loginUserId = LoginHelper.getUserId();
if (loginUserId == null) {
return R.fail("未登录或登录已过期");
}
bo.setCommentUserId(String.valueOf(loginUserId));
// 父评论为空时按根评论处理约定使用"0"作为无父评论标记
if (bo.getFatherCommentId() == null || bo.getFatherCommentId().isEmpty()) {
bo.setFatherCommentId("0");
}
// 1) 创建评论
commentService.createComment(bo);
// 2) 短视频评论总数 +1Redis 优先
redis.increment(BaseInfoProperties.REDIS_VLOG_COMMENT_COUNTS + ":" + bo.getVlogId(), 1);
// 3) 发送站内消息根评论 -> 通知视频作者回复评论 -> 通知被回复用户
if ("0".equals(bo.getFatherCommentId())) {
// 评论视频通知视频作者
if (bo.getVlogerId() != null && !bo.getVlogerId().isEmpty()
&& !String.valueOf(loginUserId).equals(bo.getVlogerId())) {
msgService.createMsg(String.valueOf(loginUserId), bo.getVlogerId(), MessageEnum.COMMENT_VLOG.type, null);
}
} else {
// 回复评论通知父评论作者
Comment father = commentService.getCommentDetail(bo.getFatherCommentId());
if (father != null && father.getCommentUserId() != null
&& !String.valueOf(loginUserId).equals(father.getCommentUserId())) {
msgService.createMsg(String.valueOf(loginUserId), father.getCommentUserId(), MessageEnum.REPLY_YOU.type, null);
}
}
return R.ok();
} catch (Exception e) {
log.error("发布评论失败", e);
return R.fail("发布评论失败: " + e.getMessage());
}
}
@ApiOperation("删除评论") @ApiOperation("删除评论")
@PostMapping("/delete") @PostMapping("/delete")
public R<Void> deleteComment( public R<Void> deleteComment(

View File

@ -131,18 +131,14 @@ public class VlogUploadController extends BaseInfoProperties {
mediaMap.put("description", basicInfo.getDescription()); mediaMap.put("description", basicInfo.getDescription());
mediaMap.put("createTime", basicInfo.getCreateTime()); mediaMap.put("createTime", basicInfo.getCreateTime());
mediaMap.put("updateTime", basicInfo.getUpdateTime()); mediaMap.put("updateTime", basicInfo.getUpdateTime());
mediaMap.put("expireTime", basicInfo.getExpireTime());
mediaMap.put("classId", basicInfo.getClassId());
mediaMap.put("className", basicInfo.getClassName());
mediaMap.put("classPath", basicInfo.getClassPath());
mediaMap.put("coverUrl", basicInfo.getCoverUrl()); mediaMap.put("coverUrl", basicInfo.getCoverUrl());
mediaMap.put("type", basicInfo.getType()); mediaMap.put("type", basicInfo.getType());
mediaMap.put("mediaUrl", basicInfo.getMediaUrl()); mediaMap.put("mediaUrl", basicInfo.getMediaUrl());
mediaMap.put("status", basicInfo.getStatus()); mediaMap.put("status", basicInfo.getStatus());
mediaMap.put("storageRegion", basicInfo.getStorageRegion());
mediaMap.put("category", basicInfo.getCategory()); mediaMap.put("category", basicInfo.getCategory());
mediaMap.put("storageClass", basicInfo.getStorageClass()); mediaMap.put("title",vlogBO.getTitle());
mediaMap.put("tagSet", basicInfo.getTagSet()); mediaMap.put("firstFrameImg",vlogBO.getFirstFrameImg());
mediaMap.put("vlogerId",vlogBO.getVlogerId());
// 获取视频统计信息 // 获取视频统计信息
Map<String, Object> statistics = vlogService.getVlogStatistics(mediaInfo.getFileId()); Map<String, Object> statistics = vlogService.getVlogStatistics(mediaInfo.getFileId());

View File

@ -10,6 +10,13 @@ public class MyListBO {
@Schema(description = "是否公开1公开0私密") @Schema(description = "是否公开1公开0私密")
private Integer yesOrNo; private Integer yesOrNo;
@Schema(description = "页码", defaultValue = "1")
private Long pageNum = 1L;
@Schema(description = "每页大小", defaultValue = "10")
private Long pageSize = 10L;
// getter/setter // getter/setter
public String getUserId() { return userId; } public String getUserId() { return userId; }
public void setUserId(String userId) { this.userId = userId; } public void setUserId(String userId) { this.userId = userId; }
@ -18,4 +25,10 @@ public class MyListBO {
public Integer getYesOrNo() { return yesOrNo; } public Integer getYesOrNo() { return yesOrNo; }
public void setYesOrNo(Integer yesOrNo) { this.yesOrNo = yesOrNo; } public void setYesOrNo(Integer yesOrNo) { this.yesOrNo = yesOrNo; }
public Long getPageNum() { return pageNum; }
public void setPageNum(Long pageNum) { this.pageNum = pageNum; }
public Long getPageSize() { return pageSize; }
public void setPageSize(Long pageSize) { this.pageSize = pageSize; }
} }

View File

@ -33,7 +33,7 @@ public class MessageMO {
@TableField("msgType") @TableField("msgType")
private Integer msgType; // 消息类型 枚举 private Integer msgType; // 消息类型 枚举
@TableField("msgContent") @TableField("msgContent")
private Map msgContent; // 消息内容 private Map<String, Object> msgContent; // 消息内容
@TableField("createTime") @TableField("createTime")
private Date createTime; // 消息创建时间 private Date createTime; // 消息创建时间

View File

@ -25,7 +25,6 @@ public class CommentVO {
private Integer likeCounts; private Integer likeCounts;
private String replyedUserNickname; private String replyedUserNickname;
private LocalDateTime createTime; private LocalDateTime createTime;
private Integer isLike = 0;
private Integer childCount; // 子评论数 private Integer childCount; // 子评论数
private Integer status; private Integer status;
private String vlogerMobile; // 视频作者手机号 private String vlogerMobile; // 视频作者手机号

View File

@ -18,6 +18,6 @@ public interface MyLikedVlogMapper extends BaseMapperPlus<MyLikedVlog,MyLikedVlo
@Select("SELECT COUNT(*) FROM t_my_liked_vlog WHERE vlog_id = #{vlogId}") @Select("SELECT COUNT(*) FROM t_my_liked_vlog WHERE vlog_id = #{vlogId}")
int countLikesByVlogId(@Param("vlogId") String vlogId); int countLikesByVlogId(@Param("vlogId") String vlogId);
@Select("SELECT u.nickname, u.face, l.created_time FROM t_my_liked_vlog l LEFT JOIN t_users u ON l.user_id = u.id WHERE l.vlog_id = #{vlogId} ORDER BY l.created_time DESC") @Select("SELECT u.nickname, u.face, l.create_time FROM t_my_liked_vlog l LEFT JOIN t_users u ON l.user_id = u.id WHERE l.vlog_id = #{vlogId} ORDER BY l.create_time DESC")
List<Map<String, Object>> selectLikedUsersByVlogId(@Param("vlogId") String vlogId); List<Map<String, Object>> selectLikedUsersByVlogId(@Param("vlogId") String vlogId);
} }

View File

@ -1,18 +1,23 @@
package com.wzj.soopin.content.mapper.repository; package com.wzj.soopin.content.mapper.repository;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.wzj.soopin.content.domain.mo.MessageMO; import com.wzj.soopin.content.domain.mo.MessageMO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.List; import java.util.List;
@InterceptorIgnore(tenantLine = "true")
@Mapper
@Repository @Repository
public interface MessageRepository { public interface MessageRepository {
// 通过实现Repository自定义条件查询 // 通过实现Repository自定义条件查询
List<MessageMO> findAllByToUserIdEqualsOrderByCreateTimeDesc(String toUserId, List<MessageMO> findAllByToUserIdEqualsOrderByCreateTimeDesc(@Param("toUserId") String toUserId,
Pageable pageable); @Param("pageable") Pageable pageable);
void save(MessageMO messageMO); void save(MessageMO messageMO);
// void deleteAllByFromUserIdAndToUserIdAndMsgType(); // void deleteAllByFromUserIdAndToUserIdAndMsgType();
} }

View File

@ -14,7 +14,7 @@ public interface MsgService {
public void createMsg(String fromUserId, public void createMsg(String fromUserId,
String toUserId, String toUserId,
Integer type, Integer type,
Map msgContent); Map<String, Object> msgContent);
/** /**
* 查询消息列表 * 查询消息列表

View File

@ -3,13 +3,11 @@ package com.wzj.soopin.content.service.impl;
import com.wzj.soopin.content.domain.base.BaseInfoProperties; import com.wzj.soopin.content.domain.base.BaseInfoProperties;
import com.wzj.soopin.content.domain.mo.MessageMO; import com.wzj.soopin.content.domain.mo.MessageMO;
import com.wzj.soopin.content.domain.po.Users;
import com.wzj.soopin.content.enums.MessageEnum; import com.wzj.soopin.content.enums.MessageEnum;
import com.wzj.soopin.content.mapper.repository.MessageRepository; import com.wzj.soopin.content.mapper.repository.MessageRepository;
import com.wzj.soopin.content.service.MsgService; import com.wzj.soopin.content.service.MsgService;
import com.wzj.soopin.member.domain.po.Member; import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.mapper.MemberMapper; import com.wzj.soopin.member.mapper.MemberMapper;
import com.wzj.soopin.member.service.IMemberService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -36,15 +34,18 @@ public class MsgServiceImpl extends BaseInfoProperties implements MsgService {
public void createMsg(String fromUserId, public void createMsg(String fromUserId,
String toUserId, String toUserId,
Integer type, Integer type,
Map msgContent) { Map<String, Object> msgContent) {
Member fromUser = memberMapper.selectById(fromUserId); Member fromUser = memberMapper.selectById(fromUserId);
MessageMO messageMO = new MessageMO(); MessageMO messageMO = new MessageMO();
messageMO.setFromUserId(fromUserId); messageMO.setFromUserId(fromUserId);
messageMO.setFromNickname(fromUser.getNickname()); // 兼容会员资料缺失的情况避免空指针
messageMO.setFromFace(fromUser.getAvatar()); String fromNickname = fromUser != null && fromUser.getNickname() != null ? fromUser.getNickname() : "";
String fromFace = fromUser != null && fromUser.getAvatar() != null ? fromUser.getAvatar() : "";
messageMO.setFromNickname(fromNickname);
messageMO.setFromFace(fromFace);
messageMO.setToUserId(toUserId); messageMO.setToUserId(toUserId);
@ -74,9 +75,9 @@ public class MsgServiceImpl extends BaseInfoProperties implements MsgService {
for (MessageMO msg : list) { for (MessageMO msg : list) {
// 如果类型是关注消息则需要查询我之前有没有关注过他用于在前端标记互粉互关 // 如果类型是关注消息则需要查询我之前有没有关注过他用于在前端标记互粉互关
if (msg.getMsgType() != null && msg.getMsgType() == MessageEnum.FOLLOW_YOU.type) { if (msg.getMsgType() != null && msg.getMsgType() == MessageEnum.FOLLOW_YOU.type) {
Map map = msg.getMsgContent(); Map<String, Object> map = (Map<String, Object>) msg.getMsgContent();
if (map == null) { if (map == null) {
map = new HashMap(); map = new HashMap<>();
} }
String relationship = redis.get(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + msg.getToUserId() + ":" + msg.getFromUserId()); String relationship = redis.get(REDIS_FANS_AND_VLOGGER_RELATIONSHIP + ":" + msg.getToUserId() + ":" + msg.getFromUserId());

View File

@ -208,7 +208,7 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
List<IndexVlogVO> voList = vlogList.stream().map(v -> { List<IndexVlogVO> voList = vlogList.stream().map(v -> {
IndexVlogVO vo = vlogConvert.toVO(v); IndexVlogVO vo = vlogConvert.toVO(v);
if (StringUtils.isNotBlank(userId)) { if (StringUtils.isNotBlank(userId)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(Long.valueOf(userId), Long.valueOf(v.getVlogerId()))); vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(userId, v.getVlogerId()));
vo.setDoILikeThisVlog(doILikeVlog(userId, v.getId())); vo.setDoILikeThisVlog(doILikeVlog(userId, v.getId()));
} }
vo.setLikeCounts(getVlogBeLikedCounts(v.getId())); vo.setLikeCounts(getVlogBeLikedCounts(v.getId()));
@ -307,8 +307,29 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
queryWrapper.eq(Vlog::getIsPrivate, bo.getYesOrNo()); queryWrapper.eq(Vlog::getIsPrivate, bo.getYesOrNo());
Page<Vlog> vlogPage = vlogMapper.selectPage(pageParam, queryWrapper); Page<Vlog> vlogPage = vlogMapper.selectPage(pageParam, queryWrapper);
List<Vlog> vlogList = vlogPage.getRecords(); List<Vlog> vlogList = vlogPage.getRecords();
// TODO: 组装PagedGridResult返回
return null; List<IndexVlogVO> voList = vlogList.stream().map(vlog -> {
IndexVlogVO vo = vlogConvert.toVO(vlog);
String uid = bo.getUserId();
if (StringUtils.isBlank(uid)) {
LoginUser user = LoginHelper.getLoginUser();
uid = user != null ? String.valueOf(user.getUserId()) : null;
}
if (StringUtils.isNotBlank(uid)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(uid, vlog.getVlogerId()));
vo.setDoILikeThisVlog(doILikeVlog(uid, vlog.getId()));
}
vo.setLikeCounts(getVlogBeLikedCounts(vlog.getId()));
vo.setCommentsCounts(getVlogComment(vlog.getId()));
return vo;
}).collect(Collectors.toList());
PagedGridResult gridResult = new PagedGridResult();
gridResult.setRows(voList);
gridResult.setPage(current);
gridResult.setRecords(vlogPage.getTotal());
gridResult.setTotal(vlogPage.getPages());
return gridResult;
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
@ -393,8 +414,38 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
queryWrapper.eq(MyLikedVlog::getUserId, bo.getUserId()); queryWrapper.eq(MyLikedVlog::getUserId, bo.getUserId());
Page<MyLikedVlog> likedPage = myLikedVlogMapper.selectPage(pageParam, queryWrapper); Page<MyLikedVlog> likedPage = myLikedVlogMapper.selectPage(pageParam, queryWrapper);
List<MyLikedVlog> likedList = likedPage.getRecords(); List<MyLikedVlog> likedList = likedPage.getRecords();
// TODO: 组装PagedGridResult返回 // 组装返回的 VO 列表
return null; String uid = bo.getUserId();
if (StringUtils.isBlank(uid)) {
LoginUser user = LoginHelper.getLoginUser();
uid = user != null ? String.valueOf(user.getUserId()) : null;
}
final String finalUid = uid;
List<IndexVlogVO> voList = likedList.stream()
.map(liked -> {
Vlog vlog = vlogMapper.selectById(liked.getVlogId());
if (vlog == null) {
return null;
}
IndexVlogVO vo = vlogConvert.toVO(vlog);
if (StringUtils.isNotBlank(finalUid)) {
vo.setDoIFollowVloger(fansService.queryDoIFollowVloger(finalUid, vlog.getVlogerId()));
vo.setDoILikeThisVlog(true);
}
vo.setLikeCounts(getVlogBeLikedCounts(vlog.getId()));
vo.setCommentsCounts(getVlogComment(vlog.getId()));
return vo;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
PagedGridResult gridResult = new PagedGridResult();
gridResult.setRows(voList);
gridResult.setPage(current);
gridResult.setRecords(likedPage.getTotal());
gridResult.setTotal(likedPage.getPages());
return gridResult;
} }
@Override @Override
@ -445,8 +496,17 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
int likeCounts = myLikedVlogMapper.countLikesByVlogId(vlog.getId()); int likeCounts = myLikedVlogMapper.countLikesByVlogId(vlog.getId());
result.put("likeCounts", likeCounts); result.put("likeCounts", likeCounts);
// 评论数 // 评论数优先 Redis无则 MySQL
Integer commentCount = commentMapper.countByVlogId(vlog.getId()); String commentCountStr = redis.get(REDIS_VLOG_COMMENT_COUNTS + ":" + vlog.getId());
Integer commentCount = 0;
if (StringUtils.isNotBlank(commentCountStr)) {
commentCount = Integer.valueOf(commentCountStr);
} else {
commentCount = commentMapper.countByVlogId(vlog.getId());
if (commentCount != null) {
redis.set(REDIS_VLOG_COMMENT_COUNTS + ":" + vlog.getId(), String.valueOf(commentCount));
}
}
result.put("commentCounts", commentCount); result.put("commentCounts", commentCount);
// 获取粉丝数量优先 Redis无则 MySQL // 获取粉丝数量优先 Redis无则 MySQL
@ -486,7 +546,7 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
// } else { // } else {
// result.put("vodDetail", vodDetail); // result.put("vodDetail", vodDetail);
// } // }
IndexVlogVO vo = vlogConvert.toVO(vlog);
// 添加评论信息 // 添加评论信息
List<Map<String, Object>> comments = commentMapper.selectCommentsByVlogId(vlog.getId()); List<Map<String, Object>> comments = commentMapper.selectCommentsByVlogId(vlog.getId());
result.put("comments", comments); result.put("comments", comments);
@ -498,6 +558,7 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
List<Map<String, Object>> likedUsers = myLikedVlogMapper.selectLikedUsersByVlogId(vlog.getId()); List<Map<String, Object>> likedUsers = myLikedVlogMapper.selectLikedUsersByVlogId(vlog.getId());
result.put("likedUsers", likedUsers); result.put("likedUsers", likedUsers);
result.put("vlog",vo);
// 添加粉丝列表 // 添加粉丝列表
// Page<FansVO> fansPage = fansService.queryMyFans(vlog.getVlogerId(), 0, 10); // Page<FansVO> fansPage = fansService.queryMyFans(vlog.getVlogerId(), 0, 10);
@ -618,16 +679,16 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
// 查询所有公开的视频列表 // 查询所有公开的视频列表
List<Map<String, Object>> allVlogs = vlogMapper.selectAllPublicVlogs(); List<Map<String, Object>> allVlogs = vlogMapper.selectAllPublicVlogs();
if (allVlogs != null && !allVlogs.isEmpty()) { if (allVlogs != null && !allVlogs.isEmpty()) {
// 从Redis获取每个视频的点赞数量 // 从Redis获取每个视频的点赞数量
List<Map<String, Object>> vlogsWithLikeCounts = new ArrayList<>(); List<Map<String, Object>> vlogsWithLikeCounts = new ArrayList<>();
for (Map<String, Object> vlog : allVlogs) { for (Map<String, Object> vlog : allVlogs) {
String vlogId = vlog.get("id").toString(); String vlogId = vlog.get("id").toString();
String redisLikeKey = REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId; String redisLikeKey = REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId;
String likeCountStr = redis.get(redisLikeKey); String likeCountStr = redis.get(redisLikeKey);
// 获取Redis中的点赞数如果没有则使用数据库中的默认值 // 获取Redis中的点赞数如果没有则使用数据库中的默认值
int likeCount = 0; int likeCount = 0;
if (likeCountStr != null && !likeCountStr.isEmpty()) { if (likeCountStr != null && !likeCountStr.isEmpty()) {
@ -638,22 +699,22 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
likeCount = 0; likeCount = 0;
} }
} }
// 添加Redis中的点赞数到视频信息中 // 添加Redis中的点赞数到视频信息中
vlog.put("redis_like_count", likeCount); vlog.put("redis_like_count", likeCount);
vlogsWithLikeCounts.add(vlog); vlogsWithLikeCounts.add(vlog);
} }
// 先打乱顺序 // 先打乱顺序
Collections.shuffle(vlogsWithLikeCounts); Collections.shuffle(vlogsWithLikeCounts);
// 按Redis中的点赞数排序获取前limit个 // 按Redis中的点赞数排序获取前limit个
vlogsWithLikeCounts.sort((v1, v2) -> { vlogsWithLikeCounts.sort((v1, v2) -> {
int count1 = (Integer) v1.get("redis_like_count"); int count1 = (Integer) v1.get("redis_like_count");
int count2 = (Integer) v2.get("redis_like_count"); int count2 = (Integer) v2.get("redis_like_count");
return Integer.compare(count2, count1); // 降序排列 return Integer.compare(count2, count1); // 降序排列
}); });
// 取前limit个 // 取前limit个
List<Map<String, Object>> topLikedVlogs = vlogsWithLikeCounts.stream() List<Map<String, Object>> topLikedVlogs = vlogsWithLikeCounts.stream()
.limit(limit) .limit(limit)

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wzj.soopin.content.mapper.repository.MessageRepository">
<!-- 将数据库列映射到 MessageMO 属性 -->
<resultMap id="MessageResultMap" type="com.wzj.soopin.content.domain.mo.MessageMO">
<id column="id" property="id"/>
<result column="from_user_id" property="fromUserId"/>
<result column="from_nickname" property="fromNickname"/>
<result column="from_face" property="fromFace"/>
<result column="to_user_id" property="toUserId"/>
<result column="msg_type" property="msgType"/>
<result column="msg_content" property="msgContent"
typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
<result column="create_time" property="createTime"/>
</resultMap>
<!-- 保存消息,如果未传 id 则使用 uuid 生成 -->
<insert id="save" parameterType="com.wzj.soopin.content.domain.mo.MessageMO">
INSERT INTO t_message
(
id,
from_user_id,
from_nickname,
from_face,
to_user_id,
msg_type,
msg_content,
create_time
)
VALUES
(
IFNULL(#{id}, REPLACE(UUID(),'-','')),
#{fromUserId},
#{fromNickname},
#{fromFace},
#{toUserId},
#{msgType},
#{msgContent, jdbcType=LONGVARCHAR, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
#{createTime}
)
</insert>
<!-- 按接收人查询,按创建时间倒序,分页 -->
<select id="findAllByToUserIdEqualsOrderByCreateTimeDesc" resultMap="MessageResultMap">
SELECT
id,
from_user_id,
from_nickname,
from_face,
to_user_id,
msg_type,
msg_content,
create_time
FROM t_message
WHERE to_user_id = #{toUserId}
ORDER BY create_time DESC
LIMIT #{pageable.offset}, #{pageable.pageSize}
</select>
</mapper>

View File

@ -27,7 +27,8 @@ public class MemberAccountChangeRecordBO extends BaseBO<MemberAccountChangeRecor
@Schema(description ="MEMBER_ID") @Schema(description ="MEMBER_ID")
private Long memberId; private Long memberId;
@Schema(description = "账户id")
private Long accountId;
@Schema(description ="余额") @Schema(description ="余额")
private BigDecimal moneyBalance; private BigDecimal moneyBalance;

View File

@ -27,7 +27,8 @@ public class MemberAccountChangeRecord extends BaseAudit {
@Schema(description ="会员id") @Schema(description ="会员id")
private Long memberId; private Long memberId;
@Schema(description = "账户id")
private Long accountId;
@Schema(description ="余额") @Schema(description ="余额")
private BigDecimal moneyBalance; private BigDecimal moneyBalance;

View File

@ -143,8 +143,22 @@ public class FansServiceImpl extends ServiceImpl<FansMapper, Fans> implements IF
@Override @Override
public boolean queryDoIFollowVloger(String myId, String vloggerId) { public boolean queryDoIFollowVloger(String myId, String vloggerId) {
Fans vlogger = queryFansRelationship(Long.valueOf(myId), Long.valueOf(vloggerId)); try {
return vlogger != null; // Try to convert string IDs to Long if they are numeric
if (myId != null && vloggerId != null &&
myId.matches("\\d+") && vloggerId.matches("\\d+")) {
Fans vlogger = queryFansRelationship(Long.valueOf(myId), Long.valueOf(vloggerId));
return vlogger != null;
} else {
// If IDs contain non-numeric characters, return false for now
// This prevents the NumberFormatException
log.warn("Cannot convert string IDs to Long: myId={}, vloggerId={}", myId, vloggerId);
return false;
}
} catch (NumberFormatException e) {
log.warn("Failed to convert string IDs to Long: myId={}, vloggerId={}", myId, vloggerId, e);
return false;
}
} }
@Override @Override

View File

@ -35,10 +35,9 @@ public class SysTenantAccountController {
@Operation(summary = "查询租户账户列表") @Operation(summary = "查询租户账户列表")
@PostMapping("/list") @PostMapping("/list")
public R<IPage<SysTenantAccountVo>> fansList(@RequestBody SysTenantAccountBo bo, @RequestBody Page<SysTenantAccount> page) { public R<IPage<SysTenantAccountVo>> fansList(@RequestBody SysTenantAccountBo bo, Page<SysTenantAccount> page) {
LambdaQueryWrapper<SysTenantAccount> fansQuery = new LambdaQueryWrapper<>(); IPage<SysTenantAccountVo> result = service.selectTenantAccountPage(page, bo);
Page<SysTenantAccount> fans = service.page(page, fansQuery); return R.ok(result);
return R.ok(convert.toVO(fans));
} }
@Operation(summary = "导出租户账户列表") @Operation(summary = "导出租户账户列表")

View File

@ -17,18 +17,18 @@ public class SysTenantAccountBo extends BaseAudit {
private Long id; private Long id;
@Schema(description = "租户ID") @Schema(description = "租户ID")
private Long tenantId; private Long tenantId;
@Schema(description = "现金余额") @Schema(description = "积分余额")
private BigDecimal moneyBalance; private BigDecimal integralBalance;
@Schema(description = "钱包余额") @Schema(description = "钱包余额")
private BigDecimal wallet; private BigDecimal wallet;
@Schema(description = "累计收益") @Schema(description = "营收")
private BigDecimal revenue; private BigDecimal revenue;
@Schema(description = "创建人")
private Long createBy;
@Schema(description = "更新人")
private Long updateBy; private Long updateBy;
@Schema(description = "账户类型 1商家 2代理 3平台") @Schema(description = "账户类型 1商家 2代理 3平台")
private Integer type; private Integer type;
private String storeName;
public LambdaQueryWrapper<SysTenantAccount> toWrapper() { public LambdaQueryWrapper<SysTenantAccount> toWrapper() {
LambdaQueryWrapper<SysTenantAccount> wrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<SysTenantAccount> wrapper = new LambdaQueryWrapper<>();

View File

@ -12,12 +12,16 @@ public class SysTenantAccountVo {
private Long id; private Long id;
@Schema(description = "租户ID") @Schema(description = "租户ID")
private Long tenantId; private Long tenantId;
@Schema(description = "积分余额")
private BigDecimal integralBalance;
// @Schema(description = "累计积分余额")
// private BigDecimal totalIntegralBalance;
@Schema(description = "更新时间") @Schema(description = "更新时间")
private Date updateTime; private Date updateTime;
@Schema(description = "创建时间") @Schema(description = "创建时间")
private Date createTime; private Date createTime;
@Schema(description = "现金余额") // @Schema(description = "现金余额")
private BigDecimal moneyBalance; // private BigDecimal moneyBalance;
@Schema(description = "钱包余额") @Schema(description = "钱包余额")
private BigDecimal wallet; private BigDecimal wallet;
@Schema(description = "累计收益") @Schema(description = "累计收益")
@ -28,4 +32,8 @@ public class SysTenantAccountVo {
private Long updateBy; private Long updateBy;
@Schema(description = "账户类型 1商家 2代理 3平台") @Schema(description = "账户类型 1商家 2代理 3平台")
private Integer type; private Integer type;
@Schema(description = "店铺名称")
private String storeName;
@Schema(description = "店铺名称")
private String companyName;
} }

View File

@ -1,13 +1,22 @@
package org.dromara.system.mapper; package org.dromara.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
import org.dromara.system.domain.CommissionSection; import org.dromara.system.domain.CommissionSection;
import org.dromara.system.domain.SysTenantAccount; import org.dromara.system.domain.SysTenantAccount;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.dromara.system.domain.bo.SysTenantAccountBo;
import org.dromara.system.domain.vo.CommissionSectionVo; import org.dromara.system.domain.vo.CommissionSectionVo;
import org.dromara.system.domain.vo.SysTenantAccountVo; import org.dromara.system.domain.vo.SysTenantAccountVo;
@Mapper @Mapper
public interface SysTenantAccountMapper extends BaseMapperPlus<SysTenantAccount, SysTenantAccountVo> { public interface SysTenantAccountMapper extends BaseMapperPlus<SysTenantAccount, SysTenantAccountVo> {
/**
* 分页查询租户账户列表关联租户表获取店铺名称
*/
IPage<SysTenantAccountVo> selectTenantAccountPage(Page<SysTenantAccount> page, @Param("bo") SysTenantAccountBo bo);
} }

View File

@ -6,11 +6,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
import org.dromara.system.domain.CommissionSection; import org.dromara.system.domain.CommissionSection;
import org.dromara.system.domain.SysTenantAccount; import org.dromara.system.domain.SysTenantAccount;
import org.dromara.system.domain.bo.SysTenantAccountBo; import org.dromara.system.domain.bo.SysTenantAccountBo;
import org.dromara.system.domain.vo.SysTenantAccountVo;
import java.util.List; import java.util.List;
public interface ISysTenantAccountService extends IService<SysTenantAccount> { public interface ISysTenantAccountService extends IService<SysTenantAccount> {
IPage<SysTenantAccount> pageWithTenant(Page<SysTenantAccount> page, SysTenantAccountBo bo); IPage<SysTenantAccount> pageWithTenant(Page<SysTenantAccount> page, SysTenantAccountBo bo);
IPage<SysTenantAccountVo> selectTenantAccountPage(Page<SysTenantAccount> page, SysTenantAccountBo bo);
List<SysTenantAccount> list(SysTenantAccountBo bo); List<SysTenantAccount> list(SysTenantAccountBo bo);
SysTenantAccount getById(Long id); SysTenantAccount getById(Long id);
boolean save(SysTenantAccount po); boolean save(SysTenantAccount po);

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.dromara.system.domain.SysTenantAccount; import org.dromara.system.domain.SysTenantAccount;
import org.dromara.system.domain.bo.SysTenantAccountBo; import org.dromara.system.domain.bo.SysTenantAccountBo;
import org.dromara.system.domain.vo.SysTenantAccountVo;
import org.dromara.system.mapper.SysTenantAccountMapper; import org.dromara.system.mapper.SysTenantAccountMapper;
import org.dromara.system.service.ISysTenantAccountService; import org.dromara.system.service.ISysTenantAccountService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -24,6 +25,11 @@ public class SysTenantAccountServiceImpl extends ServiceImpl<SysTenantAccountMa
return mapper.selectPage(page, wrapper); return mapper.selectPage(page, wrapper);
} }
@Override
public IPage<SysTenantAccountVo> selectTenantAccountPage(Page<SysTenantAccount> page, SysTenantAccountBo bo) {
return mapper.selectTenantAccountPage(page, bo);
}
@Override @Override
public List<SysTenantAccount> list(SysTenantAccountBo bo) { public List<SysTenantAccount> list(SysTenantAccountBo bo) {
LambdaQueryWrapper<SysTenantAccount> wrapper = buildWrapper(bo); LambdaQueryWrapper<SysTenantAccount> wrapper = buildWrapper(bo);

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dromara.system.mapper.SysTenantAccountMapper">
<resultMap type="org.dromara.system.domain.vo.SysTenantAccountVo" id="SysTenantAccountResult">
<result property="id" column="id"/>
<result property="tenantId" column="tenant_id"/>
<result property="integralBalance" column="integral_balance"/>
<result property="totalIntegralBalance" column="total_integral_balance"/>
<result property="moneyBalance" column="money_balance"/>
<result property="wallet" column="wallet"/>
<result property="revenue" column="revenue"/>
<result property="createBy" column="create_by"/>
<result property="updateBy" column="update_by"/>
<result property="type" column="type"/>
<result property="createTime" column="create_time"/>
<result property="updateTime" column="update_time"/>
<result property="storeName" column="store_name"/>
</resultMap>
<select id="selectTenantAccountPage" resultMap="SysTenantAccountResult">
SELECT
ta.id,
ta.tenant_id,
ta.integral_balance,
ta.wallet,
ta.revenue,
ta.create_by,
ta.update_by,
ta.type,
ta.create_time,
t.store_name,
t.company_name
FROM sys_tenant_account ta
LEFT JOIN sys_tenant t ON ta.tenant_id = t.tenant_id
<where>
<if test="bo.storeName != null and bo.storeName != ''">
AND t.store_name LIKE CONCAT('%', #{bo.storeName}, '%')
</if>
<if test="bo.type != null">
AND ta.type = #{bo.type}
</if>
</where>
</select>
</mapper>

View File

@ -29,7 +29,7 @@ public class DivideController {
@Tag(name = "查询列表") @Tag(name = "查询列表")
@PostMapping("/list") @PostMapping("/list")
public R<IPage<DivideVO>> list(@RequestBody DivideBO bo, @RequestBody Page page) { public R<IPage<DivideVO>> slist(@RequestBody DivideBO bo, @RequestBody Page page) {
Page<Divide> pages = service.page(page, bo.toWrapper()); Page<Divide> pages = service.page(page, bo.toWrapper());
return R.ok(convert.toVO(pages)); return R.ok(convert.toVO(pages));
} }