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

This commit is contained in:
fxh 2025-08-13 17:36:27 +08:00
commit 02eb7ceeeb
29 changed files with 530 additions and 125 deletions

View File

@ -125,11 +125,11 @@ tenant:
# 排除表
excludes:
- sys_menu
- t_users
- t_vlog
- t_comment
- t_my_liked_vlog
- t_fans
- cont_users
- cont_vlog
- cont_comment
- cont_my_liked_vlog
- ums_fans
- sys_tenant
- sys_tenant_package
- aws_system_statistics

View File

@ -114,47 +114,53 @@ public class VlogUploadController extends BaseInfoProperties {
log.info("腾讯云 SearchMedia API 调用成功,总记录数: {}", resp.getTotalCount());
// 处理响应结果
Map<String, Object> result = new HashMap<>();
result.put("total", resp.getTotalCount());
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) {
for (MediaInfo mediaInfo : resp.getMediaInfoSet()) {
Map<String, Object> mediaMap = new HashMap<>();
// 基础信息
MediaBasicInfo basicInfo = mediaInfo.getBasicInfo();
mediaMap.put("fileId", mediaInfo.getFileId());
mediaMap.put("name", basicInfo.getName());
mediaMap.put("description", basicInfo.getDescription());
mediaMap.put("createTime", basicInfo.getCreateTime());
mediaMap.put("updateTime", basicInfo.getUpdateTime());
mediaMap.put("coverUrl", basicInfo.getCoverUrl());
mediaMap.put("type", basicInfo.getType());
mediaMap.put("mediaUrl", basicInfo.getMediaUrl());
// 1. 映射字段与表结构一致
String fileId = mediaInfo.getFileId();
mediaMap.put("vloger_id", vlogBO.getVlogerId());
mediaMap.put("url", basicInfo.getMediaUrl());
mediaMap.put("cover", basicInfo.getCoverUrl());
mediaMap.put("title", basicInfo.getName());
mediaMap.put("create_time", basicInfo.getCreateTime());
mediaMap.put("update_time", basicInfo.getUpdateTime());
mediaMap.put("status", basicInfo.getStatus());
mediaMap.put("category", basicInfo.getCategory());
mediaMap.put("title",vlogBO.getTitle());
mediaMap.put("firstFrameImg",vlogBO.getFirstFrameImg());
mediaMap.put("vlogerId",vlogBO.getVlogerId());
mediaMap.put("file_id", fileId);
mediaMap.put("first_frame_img", vlogBO.getFirstFrameImg());
// 获取视频统计信息
Map<String, Object> statistics = vlogService.getVlogStatistics(mediaInfo.getFileId());
mediaMap.putAll(statistics);
// 获取视频上传者信息
Map<String, String> uploaderInfo = vlogService.getVlogUploaderInfo(mediaInfo.getFileId());
if (uploaderInfo != null) {
mediaMap.put("nickname", uploaderInfo.get("name"));
mediaMap.put("mobile", uploaderInfo.get("phone"));
// 2. 点赞数和评论数从Redis获取
String likeCountsStr = redis.get(REDIS_VLOG_BE_LIKED_COUNTS + ":" + fileId);
Integer likeCounts = 0;
if (StringUtils.isNotBlank(likeCountsStr)) {
try {
likeCounts = Integer.valueOf(likeCountsStr);
} catch (NumberFormatException e) {
log.warn("Redis中视频{}的点赞数格式错误: {}", fileId, likeCountsStr);
likeCounts = 0;
}
}
mediaMap.put("like_counts", likeCounts);
String commentCountsStr = redis.get(REDIS_VLOG_COMMENT_COUNTS + ":" + fileId);
Integer commentCounts = 0;
if (StringUtils.isNotBlank(commentCountsStr)) {
try {
commentCounts = Integer.valueOf(commentCountsStr);
} catch (NumberFormatException e) {
log.warn("Redis中视频{}的评论数格式错误: {}", fileId, commentCountsStr);
commentCounts = 0;
}
}
mediaMap.put("comments_counts", commentCounts);
mediaList.add(mediaMap);
}
}
result.put("records", mediaList);
// 构建Page对象
Page<Map<String, Object>> page = new Page<>();

View File

@ -8,7 +8,7 @@ import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_comment")
@TableName("cont_comment")
public class Comment {
@TableId(type = IdType.ASSIGN_ID)

View File

@ -10,7 +10,7 @@ import org.dromara.common.tenant.core.TenantEntity;
import java.util.Date;
@TableName("t_my_liked_vlog")
@TableName("cont_my_liked_vlog")
@Data
@EqualsAndHashCode(callSuper = true)
public class MyLikedVlog extends BaseAudit {

View File

@ -10,7 +10,7 @@ import org.dromara.common.tenant.core.TenantEntity;
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName( "r_user_member")
@TableName( "cont_user_member")
public class UserMember extends BaseAudit {
private String userId;
private String memberId;

View File

@ -11,7 +11,7 @@ import org.dromara.common.tenant.core.TenantEntity;
import java.util.Date;
@TableName("t_users")
@TableName("cont_users")
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)

View File

@ -7,7 +7,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import org.dromara.common.core.domain.model.BaseAudit;
@TableName(value = "t_vlog", autoResultMap = true)
@TableName(value = "cont_vlog", autoResultMap = true)
@Data
@EqualsAndHashCode(callSuper = true)

View File

@ -39,8 +39,8 @@ public interface CommentMapper extends BaseMapper<Comment> {
* 根据视频ID查询评论列表
*/
@Select("SELECT c.*, u.nickname as userNickname, u.face as userFace " +
"FROM t_comment c " +
"LEFT JOIN t_users u ON c.comment_user_id = u.id " +
"FROM cont_comment c " +
"LEFT JOIN cont_users u ON c.comment_user_id = u.id " +
"WHERE c.vlog_id = #{vlogId} " +
"ORDER BY c.create_time DESC")
List<Map<String, Object>> selectCommentsByVlogId(@Param("vlogId") String vlogId);

View File

@ -15,9 +15,9 @@ public interface MyLikedVlogMapper extends BaseMapperPlus<MyLikedVlog,MyLikedVlo
/**
* 统计某视频的点赞数
*/
@Select("SELECT COUNT(*) FROM t_my_liked_vlog WHERE vlog_id = #{vlogId}")
@Select("SELECT COUNT(*) FROM cont_my_liked_vlog WHERE vlog_id = #{vlogId}")
int countLikesByVlogId(@Param("vlogId") String vlogId);
@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")
@Select("SELECT u.nickname, u.face, l.create_time FROM cont_my_liked_vlog l LEFT JOIN cont_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);
}

View File

@ -96,7 +96,7 @@ public interface VlogMapper extends BaseMapper<Vlog> {
*/
IPage<Map<String, Object>> selectVlogListWithAggregatedData(Page<Map<String, Object>> page, @Param("vlogBO") VlogBO vlogBO);
@Select("SELECT COUNT(*) FROM t_vlog where status = 0")
@Select("SELECT COUNT(*) FROM cont_vlog where status = 0")
Object countVlog();
@ -104,7 +104,7 @@ public interface VlogMapper extends BaseMapper<Vlog> {
" DATE_FORMAT(create_time, '%Y-%m') AS month, " +
" COUNT(*) AS vlog_count " +
"FROM " +
" t_vlog " +
" cont_vlog " +
"WHERE " +
" status = 1 " +
"GROUP BY " +
@ -135,7 +135,7 @@ public interface VlogMapper extends BaseMapper<Vlog> {
" v.reason, " +
"city_code,"+
" v.first_frame_img " +
"FROM t_vlog v " +
"FROM cont_vlog v " +
"WHERE v.status = 1 AND v.is_private = 0 " +
"ORDER BY v.create_time DESC")
List<Map<String, Object>> selectAllPublicVlogs();
@ -163,7 +163,7 @@ public interface VlogMapper extends BaseMapper<Vlog> {
" v.reason, " +
" v.city_code, " +
" v.first_frame_img " +
"FROM t_vlog v " +
"FROM cont_vlog v " +
"WHERE v.status = 1 AND v.is_private = 0 " +
"ORDER BY RAND() " +
"LIMIT #{limit}")

View File

@ -492,22 +492,8 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
result.put("height",vlog.getHeight());
result.put("reason",vlog.getReason());
// 点赞数通过点赞表统计
int likeCounts = myLikedVlogMapper.countLikesByVlogId(vlog.getId());
result.put("likeCounts", likeCounts);
// 评论数优先 Redis无则 MySQL
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);
// 注意点赞数和评论数现在在控制器中直接从Redis获取
// 这里不再统计避免重复计算
// 获取粉丝数量优先 Redis无则 MySQL
String fansCountsStr = redis.get(REDIS_MY_FANS_COUNTS + ":" + vlog.getVlogerId());
@ -523,8 +509,6 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
result.put("fansCounts", fansCounts);
} else {
result.put("vlogId", null);
result.put("likeCounts", 0);
result.put("commentCounts", 0);
result.put("reason", null);
result.put("fansCounts", 0);
}
@ -551,8 +535,17 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
List<Map<String, Object>> comments = commentMapper.selectCommentsByVlogId(vlog.getId());
result.put("comments", comments);
// 添加点赞数和点赞用户信息
int likeCounts = myLikedVlogMapper.countLikesByVlogId(vlog.getId());
// 从Redis获取点赞数
String likeCountsStr = redis.get(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlog.getId());
Integer likeCounts = 0;
if (StringUtils.isNotBlank(likeCountsStr)) {
try {
likeCounts = Integer.valueOf(likeCountsStr);
} catch (NumberFormatException e) {
log.warn("Redis中视频{}的点赞数格式错误: {}", vlog.getId(), likeCountsStr);
likeCounts = 0;
}
}
result.put("likeCounts", likeCounts);
result.put("vlogId", vlog.getId());
@ -593,7 +586,17 @@ public class VlogServiceImpl extends BaseInfoProperties implements VlogService {
@Override
public int getLikeCounts(String vlogId) {
return myLikedVlogMapper.countLikesByVlogId(vlogId);
// 从Redis获取点赞数
String likeCountsStr = redis.get(REDIS_VLOG_BE_LIKED_COUNTS + ":" + vlogId);
if (StringUtils.isNotBlank(likeCountsStr)) {
try {
return Integer.valueOf(likeCountsStr);
} catch (NumberFormatException e) {
log.warn("Redis中视频{}的点赞数格式错误: {}", vlogId, likeCountsStr);
return 0;
}
}
return 0;
}
@Override

View File

@ -17,27 +17,27 @@
<!-- 根据视频ID查询评论列表 -->
<select id="selectByVlogId" resultType="com.wzj.soopin.content.domain.po.Comment">
SELECT * FROM t_comment
SELECT * FROM cont_comment
WHERE vlog_id = #{vlogId}
ORDER BY create_time DESC
</select>
<!-- 根据父评论ID查询子评论列表 -->
<select id="selectByFatherCommentId" resultType="com.wzj.soopin.content.domain.po.Comment">
SELECT * FROM t_comment
SELECT * FROM cont_comment
WHERE father_comment_id = #{fatherCommentId}
ORDER BY create_time ASC
</select>
<!-- 根据评论ID查询评论信息 -->
<select id="selectByCommentId" resultType="com.wzj.soopin.content.domain.po.Comment">
SELECT * FROM t_comment
SELECT * FROM cont_comment
WHERE id = #{commentId}
</select>
<!-- 根据视频ID统计评论数量 -->
<select id="countByVlogId" resultType="java.lang.Integer">
SELECT COUNT(*) FROM t_comment
SELECT COUNT(*) FROM cont_comment
WHERE vlog_id = #{vlogId}
</select>
</mapper>

View File

@ -22,8 +22,8 @@
c.content,
c.like_counts as likeCounts,
c.create_time as createTime
FROM t_comment c
LEFT JOIN t_users u ON c.comment_user_id = u.id
FROM cont_comment c
LEFT JOIN cont_users u ON c.comment_user_id = u.id
<where>
<if test="paramMap.vlogId != null and paramMap.vlogId != ''">
AND c.vlog_id = #{paramMap.vlogId}
@ -52,8 +52,8 @@
c.content,
c.like_counts as likeCounts,
c.create_time as createTime
FROM t_comment c
LEFT JOIN t_users u ON c.comment_user_id = u.id
FROM cont_comment c
LEFT JOIN cont_users u ON c.comment_user_id = u.id
<where>
c.father_comment_id = '0'
<if test="vlogId != null and vlogId != ''">

View File

@ -11,9 +11,9 @@
f.is_fan_friend_of_mine as bothFriend,
f.created_time as createdTime
FROM
t_fans f
ums_fans f
LEFT JOIN
t_users u
cont_users u
ON
f.vloger_id = u.id
WHERE
@ -33,9 +33,9 @@
f.is_fan_friend_of_mine as bothFriend,
f.created_time as createdTime
FROM
t_fans f
ums_fans f
LEFT JOIN
t_users u
cont_users u
ON
f.fan_id = u.id
WHERE

View File

@ -20,7 +20,7 @@
<!-- 保存消息,如果未传 id 则使用 uuid 生成 -->
<insert id="save" parameterType="com.wzj.soopin.content.domain.mo.MessageMO">
INSERT INTO t_message
INSERT INTO cont_message
(
id,
from_user_id,
@ -55,7 +55,7 @@
msg_type,
msg_content,
create_time
FROM t_message
FROM cont_message
WHERE to_user_id = #{toUserId}
ORDER BY create_time DESC
LIMIT #{pageable.offset}, #{pageable.pageSize}

View File

@ -38,7 +38,7 @@
t1.description,
t1.bg_img,
t1.can_imooc_num_be_updated
FROM t_users t1 INNER JOIN
FROM cont_users t1 INNER JOIN
r_user_member t2 ON t1.id=t2.user_id
WHERE t2.member_id=#{memberId}
</select>

View File

@ -4,7 +4,7 @@
<mapper namespace="com.wzj.soopin.content.mapper.VlogMapper">
<!-- 通用更新 -->
<update id="dynamicUpdate">
UPDATE t_vlog
UPDATE cont_vlog
<set>
<foreach collection="updateFields" index="key" item="value" separator=",">
${key} = #{value}
@ -14,7 +14,7 @@
</update>
<update id="updateVlogByConditions">
UPDATE t_vlog
UPDATE cont_vlog
<set>
<foreach collection="updates" item="value" index="key" separator=",">
${key} = #{value}
@ -45,7 +45,7 @@
<!-- 单条插入 -->
<insert id="dynamicInsert">
INSERT INTO t_vlog
INSERT INTO cont_vlog
<foreach collection="vlogData.keys" item="key" open="(" separator="," close=")">
${key}
</foreach>
@ -57,7 +57,7 @@
<!-- 批量插入 -->
<insert id="dynamicBatchInsert">
INSERT INTO t_vlog
INSERT INTO cont_vlog
<foreach collection="vlogList[0].keys" item="key" open="(" separator="," close=")">
${key}
</foreach>
@ -91,9 +91,9 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_users u
cont_users u
ON
v.vloger_id = u.id
WHERE
@ -146,9 +146,9 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_users u
cont_users u
ON
v.vloger_id = u.id
WHERE
@ -169,7 +169,7 @@
<!-- 根据fileId查询Vlog信息 -->
<select id="selectByFileId" parameterType="String" resultType="com.wzj.soopin.content.domain.po.Vlog">
/* @SqlParser(filter=true) */
SELECT * FROM t_vlog WHERE file_id = #{fileId}
SELECT * FROM cont_vlog WHERE file_id = #{fileId}
</select>
<select id="selectByMobileAndVlogId" resultType="com.wzj.soopin.content.domain.vo.CommentVO">
@ -185,8 +185,8 @@
c.content,
c.like_counts as likeCounts,
c.create_time as createTime
FROM t_comment c
LEFT JOIN t_users u ON c.comment_user_id = u.id
FROM cont_comment c
LEFT JOIN cont_users u ON c.comment_user_id = u.id
<where>
c.father_comment_id = '0'
<if test="vlogId != null and vlogId != ''">
@ -222,13 +222,13 @@
u.nickname,
u.mobile
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_users u ON v.vloger_id = u.id
cont_users u ON v.vloger_id = u.id
LEFT JOIN
t_my_liked_vlog mlv ON v.id = mlv.vlog_id
cont_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)
cont_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}, '%')

View File

@ -23,9 +23,9 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_users u
cont_users u
ON
v.vloger_id = u.id
WHERE
@ -84,9 +84,9 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_users u
cont_users u
ON
v.vloger_id = u.id
WHERE
@ -116,13 +116,13 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_my_liked_vlog mlv
cont_my_liked_vlog mlv
ON
v.id = mlv.vlog_id
LEFT JOIN
t_users u
cont_users u
ON
mlv.user_id = u.id
WHERE
@ -168,13 +168,13 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_fans f
cont_fans f
ON
v.vloger_id = f.vloger_id
LEFT JOIN
t_users u
cont_users u
ON
f.vloger_id = u.id
WHERE
@ -209,13 +209,13 @@
v.first_frame_img as firstFrameImg,
v.id as vlogId
FROM
t_vlog v
cont_vlog v
LEFT JOIN
t_fans f
ums_fans f
ON
v.vloger_id = f.fan_id
LEFT JOIN
t_users u
cont_users u
ON
f.fan_id = u.id
WHERE

View File

@ -0,0 +1,54 @@
package com.wzj.soopin.member.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.domain.bo.AccountDetailQueryBO;
import com.wzj.soopin.member.domain.vo.AccountDetailVO;
import com.wzj.soopin.member.service.IAccountDetailService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.validation.annotation.Validated;
/**
* 账户明细查询控制器
*/
@Tag(name = "账户明细查询")
@RestController
@RequestMapping("/account/detail")
@RequiredArgsConstructor
public class AccountDetailController {
private final IAccountDetailService accountDetailService;
/**
* 分页查询账户明细
*/
@Operation(summary = "根据account_id分页查询账户明细")
@PostMapping("/page")
public R<IPage<AccountDetailVO>> queryAccountDetailPage(@RequestBody AccountDetailQueryBO queryBO,
@RequestBody Page<?> page) {
if (page != null) {
queryBO.setPageNum(page.getCurrent());
queryBO.setPageSize(page.getSize());
}
IPage<AccountDetailVO> result = accountDetailService.queryAccountDetailPage(queryBO);
return R.ok(result);
}
/**
* 查询当前登录用户的账户明细
*/
@Operation(summary = "查询当前登录用户的账户明细")
@PostMapping("/current")
public R<IPage<AccountDetailVO>> queryCurrentUserAccountDetailPage(@Validated @RequestBody AccountDetailQueryBO queryBO) {
IPage<AccountDetailVO> result = accountDetailService.queryCurrentUserAccountDetailPage(queryBO);
return R.ok(result);
}
}

View File

@ -53,7 +53,6 @@ public class MemberController extends BaseController {
}
@Tag(name ="导出会员信息列表")
@SaCheckPermission("ums:member:export")
@Log(title = "会员信息", businessType = BusinessType.EXPORT)
@PostMapping("export")
public R<String> export(MemberBO query) {
@ -63,7 +62,6 @@ public class MemberController extends BaseController {
}
@Tag(name ="获取会员信息详细信息")
@SaCheckPermission("ums:member:query")
@GetMapping(value = "{id}")
public R<MemberVO> getInfo(@PathVariable("id") Long id) {
return R.ok(convert.toVO(service.getById(id)));

View File

@ -0,0 +1,38 @@
package com.wzj.soopin.member.domain.bo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 账户明细查询对象
*/
@Schema(description = "账户明细查询对象")
@Data
public class AccountDetailQueryBO {
@Schema(description = "会员ID")
private Long memberId;
@Schema(description = "账户ID")
private Long accountId;
@Schema(description = "变动类型")
private Integer changeType;
@Schema(description = "变动来源")
private Integer source;
@Schema(description = "开始时间")
private LocalDateTime startTime;
@Schema(description = "结束时间")
private LocalDateTime endTime;
@Schema(description = "页码", defaultValue = "1")
private Long pageNum = 1L;
@Schema(description = "每页大小", defaultValue = "10")
private Long pageSize = 10L;
}

View File

@ -33,13 +33,9 @@ public class MemberAccount extends BaseAudit {
private String name;
/**
* 账户类型 1 用户 2 商家 3 代理 4 平台
*/
private Integer type;
@Schema(description ="积分余额")
@Schema(description ="积分")
private BigDecimal integral;
@Schema(description ="钱包")

View File

@ -0,0 +1,66 @@
package com.wzj.soopin.member.domain.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
/**
* 账户明细返回对象
*/
@Schema(description = "账户明细返回对象")
@Data
public class AccountDetailVO {
@Schema(description = "记录ID")
private Long id;
@Schema(description = "会员ID")
private Long memberId;
@Schema(description = "账户ID")
private Long accountId;
@Schema(description = "账户类型 1-用户 2-商家 3-代理 4-平台")
private Integer accountType;
@Schema(description = "账户类型描述")
private String accountTypeDesc;
@Schema(description = "用户类型 1-租户 2-会员")
private Integer userType;
@Schema(description = "用户类型描述")
private String userTypeDesc;
@Schema(description = "余额")
private BigDecimal moneyBalance;
@Schema(description = "变动前余额")
private BigDecimal beforeBalance;
@Schema(description = "变动后余额")
private BigDecimal afterBalance;
@Schema(description = "变动金额")
private BigDecimal changeAmount;
@Schema(description = "变动类型")
private Integer changeType;
@Schema(description = "变动类型描述")
private String changeTypeDesc;
@Schema(description = "变动描述")
private String changeDesc;
@Schema(description = "变动来源")
private Integer source;
@Schema(description = "变动来源描述")
private String sourceDesc;
@Schema(description = "创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,32 @@
package com.wzj.soopin.member.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 账户类型枚举
*/
@Getter
@AllArgsConstructor
public enum AccountTypeEnum {
USER(1, "用户"),
MERCHANT(2, "商家"),
AGENT(3, "代理"),
PLATFORM(4, "平台");
private final Integer code;
private final String desc;
public static String getDesc(Integer code) {
if (code == null) {
return "";
}
for (AccountTypeEnum type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return "";
}
}

View File

@ -0,0 +1,42 @@
package com.wzj.soopin.member.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 用户类型枚举
*/
@Getter
@AllArgsConstructor
public enum UserTypeEnum {
TENANT(1, "租户"),
MEMBER(2, "会员");
private final Integer code;
private final String desc;
public static String getDesc(Integer code) {
if (code == null) {
return "";
}
for (UserTypeEnum type : values()) {
if (type.getCode().equals(code)) {
return type.getDesc();
}
}
return "";
}
/**
* 根据账户类型判断用户类型
* 1-用户 -> 会员, 2-商家 -> 租户, 3-代理 -> 租户, 4-平台 -> 租户
*/
public static Integer getUserTypeByAccountType(Integer accountType) {
if (accountType == null) {
return MEMBER.getCode();
}
// 1-用户是会员其他都是租户
return accountType == 1 ? MEMBER.getCode() : TENANT.getCode();
}
}

View File

@ -1,18 +1,23 @@
package com.wzj.soopin.member.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wzj.soopin.member.domain.po.MemberAccount;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.domain.po.MemberAccountChangeRecord;
import com.wzj.soopin.member.domain.vo.AccountDetailVO;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
/**
* 会员账户表Mapper接口
*
* @author zcc
* 会员账户变动记录Mapper接口
*/
public interface MemberAccountChangeRecordMapper extends BaseMapper<MemberAccountChangeRecord> {
public interface MemberAccountChangeRecordMapper extends BaseMapperPlus<MemberAccountChangeRecord, AccountDetailVO> {
/**
* 分页查询账户明细关联账户表获取账户类型
*/
IPage<AccountDetailVO> selectAccountDetailPage(Page<AccountDetailVO> page, @Param("memberId") Long memberId,
@Param("accountId") Long accountId, @Param("changeType") Integer changeType,
@Param("source") Integer source, @Param("startTime") String startTime,
@Param("endTime") String endTime);
}

View File

@ -0,0 +1,27 @@
package com.wzj.soopin.member.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.domain.bo.AccountDetailQueryBO;
import com.wzj.soopin.member.domain.vo.AccountDetailVO;
/**
* 账户明细查询服务接口
*/
public interface IAccountDetailService {
/**
* 分页查询账户明细
*/
IPage<AccountDetailVO> queryAccountDetailPage(AccountDetailQueryBO queryBO);
/**
* 根据账户类型判断用户类型
*/
Integer getUserTypeByAccountType(Integer accountType);
/**
* 查询当前登录用户的账户明细
*/
IPage<AccountDetailVO> queryCurrentUserAccountDetailPage(AccountDetailQueryBO queryBO);
}

View File

@ -0,0 +1,86 @@
package com.wzj.soopin.member.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.domain.bo.AccountDetailQueryBO;
import com.wzj.soopin.member.domain.vo.AccountDetailVO;
import com.wzj.soopin.member.enums.AccountTypeEnum;
import com.wzj.soopin.member.enums.UserTypeEnum;
import com.wzj.soopin.member.mapper.MemberAccountChangeRecordMapper;
import com.wzj.soopin.member.service.IAccountDetailService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.common.core.domain.model.LoginUser;
import org.springframework.stereotype.Service;
import java.time.format.DateTimeFormatter;
import java.util.List;
/**
* 账户明细查询服务实现类
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AccountDetailServiceImpl implements IAccountDetailService {
private final MemberAccountChangeRecordMapper accountChangeRecordMapper;
@Override
public IPage<AccountDetailVO> queryAccountDetailPage(AccountDetailQueryBO queryBO) {
// 构建分页对象
Page<AccountDetailVO> page = new Page<>(queryBO.getPageNum(), queryBO.getPageSize());
// 处理时间格式
String startTime = null;
String endTime = null;
if (queryBO.getStartTime() != null) {
startTime = queryBO.getStartTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
if (queryBO.getEndTime() != null) {
endTime = queryBO.getEndTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
// 查询数据
IPage<AccountDetailVO> result = accountChangeRecordMapper.selectAccountDetailPage(
page, queryBO.getMemberId(), queryBO.getAccountId(),
queryBO.getChangeType(), queryBO.getSource(), startTime, endTime
);
// 补充账户类型和用户类型描述
List<AccountDetailVO> records = result.getRecords();
for (AccountDetailVO record : records) {
// 设置账户类型描述
record.setAccountTypeDesc(AccountTypeEnum.getDesc(record.getAccountType()));
// 根据账户类型判断用户类型
Integer userType = getUserTypeByAccountType(record.getAccountType());
record.setUserType(userType);
record.setUserTypeDesc(UserTypeEnum.getDesc(userType));
}
return result;
}
@Override
public Integer getUserTypeByAccountType(Integer accountType) {
return UserTypeEnum.getUserTypeByAccountType(accountType);
}
@Override
public IPage<AccountDetailVO> queryCurrentUserAccountDetailPage(AccountDetailQueryBO queryBO) {
// 获取当前登录用户信息
LoginUser loginUser = LoginHelper.getLoginUser();
if (loginUser == null) {
throw new RuntimeException("用户未登录");
}
// 设置当前登录用户的会员ID
queryBO.setMemberId(loginUser.getUserId());
// 调用原有的分页查询方法
return queryAccountDetailPage(queryBO);
}
}

View File

@ -0,0 +1,52 @@
<?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.member.mapper.MemberAccountChangeRecordMapper">
<!-- 分页查询账户明细(关联会员账户表和租户账户表获取账户类型) -->
<select id="selectAccountDetailPage" resultType="com.wzj.soopin.member.domain.vo.AccountDetailVO">
SELECT
r.id,
r.member_id as memberId,
r.account_id as accountId,
COALESCE(ma.type, ta.type) as accountType,
CASE
WHEN ma.id IS NOT NULL THEN 2 -- 会员
WHEN ta.id IS NOT NULL THEN 1 -- 租户
ELSE 2 -- 默认会员
END as userType,
r.money_balance as moneyBalance,
r.before_balance as beforeBalance,
r.after_balance as afterBalance,
r.change_amount as changeAmount,
r.change_type as changeType,
r.change_desc as changeDesc,
r.source,
r.create_time as createTime
FROM ums_account_change_record r
LEFT JOIN ums_account ma ON r.account_id = ma.member_id
LEFT JOIN sys_tenant_account ta ON r.account_id = ta.tenant_id
<where>
<if test="memberId != null">
AND r.member_id = #{memberId}
</if>
<if test="accountId != null">
AND r.account_id = #{accountId}
</if>
<if test="changeType != null">
AND r.change_type = #{changeType}
</if>
<if test="source != null">
AND r.source = #{source}
</if>
<if test="startTime != null and startTime != ''">
AND r.create_time >= #{startTime}
</if>
<if test="endTime != null and endTime != ''">
AND r.create_time &lt;= #{endTime}
</if>
AND (ma.id IS NOT NULL OR ta.id IS NOT NULL)
</where>
ORDER BY r.create_time DESC
</select>
</mapper>