[fix]增加会员填充切面,自动根据member对象填充用户数据

This commit is contained in:
王庆祥 2025-06-19 15:36:30 +08:00
parent 409a8446c0
commit bfcb239df2
12 changed files with 230 additions and 20 deletions

View File

@ -1,4 +0,0 @@
package org.dromara.common.web.core;
public interface MemberFill {
}

View File

@ -0,0 +1,127 @@
package com.wzj.soopin.member.annotation;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.service.IMemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.dromara.common.core.domain.R;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.util.Collection;
@Aspect
@Component
@RequiredArgsConstructor
@Slf4j
public class MemberFillAspect {
private final IMemberService memberService;
@Around("@annotation(com.wzj.soopin.member.annotation.MemberFillMethod)")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
Object result = joinPoint.proceed();
if (result instanceof R<?>) {
Object data = ((R<?>) result).getData();
if (data != null) {
processObject(data);
}
}
return result;
}
private void processObject(Object obj) {
//基础类型跳过
if (obj == null || isPrimitiveType(obj.getClass())) return;
// 处理集合类型
if (obj instanceof Collection) {
for (Object item : (Collection<?>) obj) {
processObject(item);
}
return;
}
// 处理分页类型
if (obj instanceof IPage<?>) {
for (Object item : (Collection<?>)((IPage<?>) obj).getRecords()) {
processObject(item);
}
return;
}
// 处理数组类型
if (obj.getClass().isArray()) {
int length = java.lang.reflect.Array.getLength(obj);
for (int i = 0; i < length; i++) {
processObject(java.lang.reflect.Array.get(obj, i));
}
return;
}
// 同原 MemberFillInterceptor 中的逻辑简化处理
Class<?> clazz = obj.getClass();
while (clazz != null && clazz != Object.class) {
for (Field field : clazz.getDeclaredFields()) {
if (field.isAnnotationPresent(MemberFillField.class)) {
handleMemberFill(obj, field);
}
}
clazz = clazz.getSuperclass();
}
}
// 判断是否为基本类型或包装类型
private boolean isPrimitiveType(Class<?> clazz) {
return clazz.isPrimitive() ||
clazz.equals(String.class) ||
clazz.equals(Integer.class) ||
clazz.equals(Long.class) ||
clazz.equals(Double.class) ||
clazz.equals(Float.class) ||
clazz.equals(Boolean.class) ||
clazz.equals(Character.class) ||
clazz.equals(Short.class) ||
clazz.equals(Byte.class);
}
private void handleMemberFill(Object obj, Field field) {
try {
field.setAccessible(true);
MemberFillField annotation = field.getAnnotation(MemberFillField.class);
String memberIdFieldName = annotation.id();
Field idField = findField(obj.getClass(), memberIdFieldName);
idField.setAccessible(true);
Object memberId = idField.get(obj);
if (memberId instanceof Long) {
MemberVO member = memberService.getMemberInfo((Long) memberId);
if (member != null) {
field.set(obj, member);
}
}
} catch (Exception e) {
log.error("会员信息填充失败", e);
}
}
private Field findField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
try {
return clazz.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class<?> superClass = clazz.getSuperclass();
if (superClass == null) throw e;
return findField(superClass, fieldName);
}
}
}

View File

@ -0,0 +1,18 @@
package com.wzj.soopin.member.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义vo处理器用于标注需要填充member的对象
*
* @author ruoyi
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberFillField {
String id() default "";
}

View File

@ -0,0 +1,15 @@
package com.wzj.soopin.member.annotation;
import java.lang.annotation.*;
/**
* 自定义vo处理器用于标注需要填充member的对象
*
* @author ruoyi
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MemberFillMethod {
String id() default "";
}

View File

@ -1,19 +1,17 @@
package com.wzj.soopin.member.controller; package com.wzj.soopin.member.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.annotation.MemberFillMethod;
import com.wzj.soopin.member.convert.FansConvert; import com.wzj.soopin.member.convert.FansConvert;
import com.wzj.soopin.member.convert.FeedbackConvert; import com.wzj.soopin.member.convert.MemberBlockConvert;
import com.wzj.soopin.member.domain.bo.FansBO; import com.wzj.soopin.member.domain.bo.FansBO;
import com.wzj.soopin.member.domain.bo.FeedbackBO;
import com.wzj.soopin.member.domain.po.Fans; import com.wzj.soopin.member.domain.po.Fans;
import com.wzj.soopin.member.domain.po.Feedback;
import com.wzj.soopin.member.domain.po.Member; import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.po.MemberBlock; import com.wzj.soopin.member.domain.po.MemberBlock;
import com.wzj.soopin.member.domain.vo.FansVO; import com.wzj.soopin.member.domain.vo.FansVO;
import com.wzj.soopin.member.domain.vo.FeedbackVO; import com.wzj.soopin.member.domain.vo.MemberBlockVO;
import com.wzj.soopin.member.service.IFansService; import com.wzj.soopin.member.service.IFansService;
import com.wzj.soopin.member.service.IMemberBlockService; import com.wzj.soopin.member.service.IMemberBlockService;
import com.wzj.soopin.member.service.IMemberService; import com.wzj.soopin.member.service.IMemberService;
@ -22,7 +20,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.CacheConstants;
import org.dromara.common.core.domain.R; import org.dromara.common.core.domain.R;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.log.annotation.Log; import org.dromara.common.log.annotation.Log;
import org.dromara.common.log.enums.BusinessType; import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.redis.utils.RedisUtils; import org.dromara.common.redis.utils.RedisUtils;
@ -45,28 +42,29 @@ public class FansController {
private final IMemberBlockService memberBlockService; private final IMemberBlockService memberBlockService;
private final MemberBlockConvert memberblockconvert;
@Tag(name ="粉丝列表") @Tag(name ="粉丝列表")
@PostMapping("/fan/list") @PostMapping("/fan/list")
public R<IPage<FansVO>> fansList( Long memberId, @RequestBody Page page) { public R<IPage<FansVO>> fansList(@RequestBody FansBO bo, @RequestBody Page page) {
LambdaQueryWrapper< Fans> fansQuery = new LambdaQueryWrapper<>(); LambdaQueryWrapper< Fans> fansQuery = new LambdaQueryWrapper<>();
fansQuery.eq(Fans::getVloggerId, memberId); fansQuery.eq(Fans::getVloggerId, bo.getMemberId());
Page<Fans> fans= service.page(page,fansQuery); Page<Fans> fans= service.page(page,fansQuery);
return R.ok(convert.toVO( fans)); return R.ok(convert.toVO( fans));
} }
@Tag(name ="关注列表") @Tag(name ="关注列表")
@PostMapping("/follow/list") @PostMapping("/follow/list")
public R<IPage<FansVO>> followList( Long memberId, @RequestBody Page page) { public R<IPage<FansVO>> followList(@RequestBody FansBO bo, @RequestBody Page page) {
LambdaQueryWrapper< Fans> fansQuery = new LambdaQueryWrapper<>(); LambdaQueryWrapper< Fans> fansQuery = new LambdaQueryWrapper<>();
fansQuery.eq(Fans::getFanId, memberId); fansQuery.eq(Fans::getFanId, bo.getMemberId());
Page<Fans> fans= service.page(page,fansQuery); Page<Fans> fans= service.page(page,fansQuery);
return R.ok(convert.toVO( fans)); return R.ok(convert.toVO( fans));
} }
@Tag(name ="朋友列表") @Tag(name ="朋友列表")
@PostMapping("/friend/list") @PostMapping("/friend/list")
public R<IPage<FansVO>> friendList( Long memberId, @RequestBody Page page) { public R<IPage<FansVO>> friendList( @RequestBody FansBO bo, @RequestBody Page page) {
LambdaQueryWrapper< Fans> fansQuery = new LambdaQueryWrapper<>(); LambdaQueryWrapper< Fans> fansQuery = new LambdaQueryWrapper<>();
fansQuery.eq(Fans::getVloggerId, memberId); fansQuery.eq(Fans::getVloggerId, bo.getMemberId());
fansQuery.eq(Fans::getFriendFlag, 1); fansQuery.eq(Fans::getFriendFlag, 1);
Page<Fans> fans= service.page(page,fansQuery); Page<Fans> fans= service.page(page,fansQuery);
return R.ok(convert.toVO( fans)); return R.ok(convert.toVO( fans));
@ -152,9 +150,12 @@ public class FansController {
} }
@GetMapping("block/list") @GetMapping("block/list")
public R<List<MemberBlock>> queryBlockVloger(@RequestParam Long myId) { @MemberFillMethod
public R<List<MemberBlockVO>> queryBlockVloger(@RequestParam Long myId) {
return R.ok(memberBlockService.list(new LambdaQueryWrapper<MemberBlock>().eq(MemberBlock::getMemberId, myId))); List<MemberBlock> blockList= memberBlockService.list(new LambdaQueryWrapper<MemberBlock>().eq(MemberBlock::getMemberId, myId));
return R.ok(memberblockconvert.toVO(blockList));
} }
/** /**

View File

@ -112,7 +112,7 @@ public class FeedbackController {
@Tag(name = ("处理")) @Tag(name = ("处理"))
@Log(title = "意见反馈", businessType = BusinessType.UPDATE) @Log(title = "意见反馈", businessType = BusinessType.UPDATE)
@PostMapping("/handle/handle") @PostMapping("/handle")
public R changeStatus(@RequestBody FeedbackBO bo) { public R changeStatus(@RequestBody FeedbackBO bo) {
service.handle(convert.toPo(bo)); service.handle(convert.toPo(bo));
return R.ok(); return R.ok();

View File

@ -0,0 +1,20 @@
package com.wzj.soopin.member.convert;
import com.wzj.soopin.member.domain.bo.FeedbackBO;
import com.wzj.soopin.member.domain.po.Feedback;
import com.wzj.soopin.member.domain.po.MemberBlock;
import com.wzj.soopin.member.domain.vo.FeedbackVO;
import com.wzj.soopin.member.domain.vo.MemberBlockVO;
import org.dromara.common.web.core.BaseConverter;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
/**
* 意见反馈 DO <=> VO / BO
*
* @author zcc
*/
@Mapper(componentModel = "spring",uses = BaseConverter.class)
public interface MemberBlockConvert extends BaseConverter<MemberBlockVO, MemberBlock, MemberBlock> {
}

View File

@ -19,6 +19,14 @@ import org.springframework.boot.actuate.integration.IntegrationGraphEndpoint;
public class FansBO extends BaseBO<Fans> { public class FansBO extends BaseBO<Fans> {
/**
* 用户
*/
@Schema(description ="用户id")
private String memberId;
/** /**
* 博主id * 博主id
*/ */

View File

@ -1,5 +1,6 @@
package com.wzj.soopin.member.domain.vo; package com.wzj.soopin.member.domain.vo;
import com.wzj.soopin.member.annotation.MemberFillField;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
@ -17,6 +18,7 @@ public class FansVO {
@Schema(description ="博主id") @Schema(description ="博主id")
@Excel(name = "博主id") @Excel(name = "博主id")
@MemberFillField(id = "vloggerId")
private MemberVO vlogger; private MemberVO vlogger;
@Schema(description ="博主id") @Schema(description ="博主id")
@ -24,6 +26,7 @@ public class FansVO {
@Schema(description ="粉丝id") @Schema(description ="粉丝id")
@Excel(name = "粉丝id") @Excel(name = "粉丝id")
@MemberFillField(id = "fanId")
private MemberVO fan; private MemberVO fan;
@Schema(description ="粉丝id") @Schema(description ="粉丝id")

View File

@ -1,7 +1,7 @@
package com.wzj.soopin.member.domain.vo; package com.wzj.soopin.member.domain.vo;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.wzj.soopin.member.annotation.MemberFillField;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data; import lombok.Data;
import org.dromara.common.core.domain.model.BaseAudit; import org.dromara.common.core.domain.model.BaseAudit;
@ -20,8 +20,15 @@ public class MemberBlockVO extends BaseAudit {
@Schema(description ="用户id") @Schema(description ="用户id")
private Long memberId; private Long memberId;
@Schema(description ="用户")
@MemberFillField(id = "memberId")
private MemberVO member;
@Schema(description ="被拉黑人id") @Schema(description ="被拉黑人id")
private Long blockMemberId; private Long blockMemberId;
@Schema(description ="被拉黑人")
@MemberFillField(id = "blockMemberId")
private MemberVO blockMember;
} }

View File

@ -7,6 +7,7 @@ import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.vo.MemberVO; import com.wzj.soopin.member.domain.vo.MemberVO;
import org.dromara.common.core.constant.ResultCode; import org.dromara.common.core.constant.ResultCode;
import java.io.Serializable;
import java.util.List; import java.util.List;
public interface IMemberService extends IService<Member> { public interface IMemberService extends IService<Member> {
@ -60,4 +61,7 @@ public interface IMemberService extends IService<Member> {
String getPhoneDecrypted(String phoneEncrypted) ; String getPhoneDecrypted(String phoneEncrypted) ;
MemberVO getMemberInfo(Serializable id);
} }

View File

@ -6,10 +6,12 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzj.soopin.member.convert.MemberConvert;
import com.wzj.soopin.member.domain.bo.MemberBO; import com.wzj.soopin.member.domain.bo.MemberBO;
import com.wzj.soopin.member.domain.form.ChangeMemberStatusForm; import com.wzj.soopin.member.domain.form.ChangeMemberStatusForm;
import com.wzj.soopin.member.domain.po.Member; import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.domain.po.MemberAccount; import com.wzj.soopin.member.domain.po.MemberAccount;
import com.wzj.soopin.member.domain.vo.MemberVO;
import com.wzj.soopin.member.mapper.MemberAccountMapper; import com.wzj.soopin.member.mapper.MemberAccountMapper;
import com.wzj.soopin.member.mapper.MemberCartMapper; import com.wzj.soopin.member.mapper.MemberCartMapper;
import com.wzj.soopin.member.mapper.MemberMapper; import com.wzj.soopin.member.mapper.MemberMapper;
@ -54,6 +56,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper,Member> implemen
private final MemberAccountMapper memberAccountMapper; private final MemberAccountMapper memberAccountMapper;
private final MemberConvert memberConvert;
@Override @Override
public boolean usernameExists(String username) { public boolean usernameExists(String username) {
return baseMapper.countByUsername(username) > 0; // 确保实现 return baseMapper.countByUsername(username) > 0; // 确保实现
@ -252,4 +257,10 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper,Member> implemen
public Member getById(Serializable id) { public Member getById(Serializable id) {
return super.getById(id); return super.getById(id);
} }
@Override
public MemberVO getMemberInfo(Serializable id) {
return memberConvert.toVO(getById(id));
}
} }