refactor(membership): 重构标签成员删除逻辑并优化查询

- 将deleteById方法重命名为removeById以更准确表达物理删除操作
- 为MembershipTagMemberEntity添加deleted字段支持逻辑删除
- 优化用户查询SQL,移除不必要的标签关联查询
- 修改标签查询逻辑,使用EXISTS代替IN提升查询性能
This commit is contained in:
dzq 2025-12-08 16:34:09 +08:00
parent b0f11999de
commit a5fc5201aa
5 changed files with 48 additions and 27 deletions

View File

@ -61,15 +61,13 @@ public interface Ab98UserMapper extends BaseMapper<Ab98UserEntity> {
); );
@Select("SELECT * FROM (" + @Select("SELECT * FROM (" +
"SELECT DISTINCT u.ab98_user_id, u.openid, u.userid, u.qy_user_id, u.name, u.tel, u.idnum, u.sex, u.face_img, u.idcard_front, u.idcard_back, u.address, u.registered, u.creator_id, u.create_time, u.updater_id, u.update_time, u.deleted, u.ab98_balance, ub.balance, ub.use_balance, ub.balance_limit, w.wx_user_id, w.openid as wx_user_openid, w.nick_name as wx_nick_name, w.avatar as wx_avatar, mtm.tag_id " + "SELECT DISTINCT u.ab98_user_id, u.openid, u.userid, u.qy_user_id, u.name, u.tel, u.idnum, u.sex, u.face_img, u.idcard_front, u.idcard_back, u.address, u.registered, u.creator_id, u.create_time, u.updater_id, u.update_time, u.deleted, u.ab98_balance, ub.balance, ub.use_balance, ub.balance_limit, w.wx_user_id, w.openid as wx_user_openid, w.nick_name as wx_nick_name, w.avatar as wx_avatar " +
"FROM ab98_user u " + "FROM ab98_user u " +
"LEFT JOIN membership_tag_member mtm ON u.ab98_user_id = mtm.ab98_user_id " + "LEFT JOIN user_balance ub ON u.ab98_user_id = ub.ab98_user_id and ub.deleted = 0 " +
"LEFT JOIN user_balance ub ON u.ab98_user_id = ub.ab98_user_id " + "LEFT JOIN wx_user w ON u.ab98_user_id = w.ab98_user_id and w.deleted = 0 " +
"LEFT JOIN wx_user w ON u.ab98_user_id = w.ab98_user_id " +
" UNION ALL " + " UNION ALL " +
"SELECT NULL as ab98_user_id, NULL as openid, NULL as userid, NULL as qy_user_id, NULL as name, NULL as tel, NULL as idnum, NULL as sex, NULL as face_img, NULL as idcard_front, NULL as idcard_back, NULL as address, NULL as registered, NULL as creator_id, w.create_time as create_time, NULL as updater_id, w.update_time as update_time, NULL as deleted, NULL as ab98_balance, NULL as balance, NULL as use_balance, NULL as balance_limit, w.wx_user_id, w.openid as wx_user_openid, w.nick_name as wx_nick_name, w.avatar as wx_avatar, mtm.tag_id " + "SELECT NULL as ab98_user_id, NULL as openid, NULL as userid, NULL as qy_user_id, NULL as name, NULL as tel, NULL as idnum, NULL as sex, NULL as face_img, NULL as idcard_front, NULL as idcard_back, NULL as address, NULL as registered, NULL as creator_id, w.create_time as create_time, NULL as updater_id, w.update_time as update_time, NULL as deleted, NULL as ab98_balance, NULL as balance, NULL as use_balance, NULL as balance_limit, w.wx_user_id, w.openid as wx_user_openid, w.nick_name as wx_nick_name, w.avatar as wx_avatar " +
"FROM wx_user w " + "FROM wx_user w " +
"LEFT JOIN membership_tag_member mtm ON w.wx_user_id = mtm.wx_user_id " +
"WHERE w.ab98_user_id IS NULL" + "WHERE w.ab98_user_id IS NULL" +
") t ${ew.customSqlSegment} ORDER BY create_time DESC") ") t ${ew.customSqlSegment} ORDER BY create_time DESC")
Page<Ab98UserEntity> getUserListWithWx( Page<Ab98UserEntity> getUserListWithWx(

View File

@ -3,7 +3,12 @@ package com.agileboot.domain.ab98.user.query;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.agileboot.common.core.page.AbstractPageQuery; import com.agileboot.common.core.page.AbstractPageQuery;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -21,7 +26,7 @@ public class SearchAb98UserWithWxQuery<T> extends AbstractPageQuery<T> {
private Boolean registered; private Boolean registered;
private Date startTime; private Date startTime;
private Date endTime; private Date endTime;
private Long tagId; private String tagIds;
private String corpid; private String corpid;
private String wxUserOpenid; private String wxUserOpenid;
private Boolean hasAb98UserId; private Boolean hasAb98UserId;
@ -32,17 +37,33 @@ public class SearchAb98UserWithWxQuery<T> extends AbstractPageQuery<T> {
queryWrapper queryWrapper
.eq(ab98UserId != null, "ab98_user_id", ab98UserId) .eq(ab98UserId != null, "ab98_user_id", ab98UserId)
.eq(StrUtil.isNotEmpty(openid), "openid", openid) .eq(StrUtil.isNotBlank(openid), "openid", openid)
.eq(StrUtil.isNotEmpty(userid), "userid", userid) .eq(StrUtil.isNotBlank(userid), "userid", userid)
.like(StrUtil.isNotEmpty(name), "name", name) .like(StrUtil.isNotBlank(name), "name", name)
.like(StrUtil.isNotEmpty(tel), "tel", tel) .like(StrUtil.isNotBlank(tel), "tel", tel)
.like(StrUtil.isNotEmpty(idnum), "idnum", idnum) .like(StrUtil.isNotBlank(idnum), "idnum", idnum)
.eq(StrUtil.isNotEmpty(sex), "sex", sex) .eq(StrUtil.isNotBlank(sex), "sex", sex)
.eq(registered != null, "registered", registered) .eq(registered != null, "registered", registered)
.eq(StrUtil.isNotEmpty(wxUserOpenid), "wx_user_openid", wxUserOpenid) .eq(StrUtil.isNotBlank(wxUserOpenid), "wx_user_openid", wxUserOpenid)
.eq(tagId != null, "tag_id", tagId) /* .in(StrUtil.isNotBlank(tagIds), "tag_id", StrUtil.split(tagIds, ",")
.stream().map(Long::valueOf).collect(Collectors.toList())) */
.between(startTime != null && endTime != null, "create_time", startTime, endTime); .between(startTime != null && endTime != null, "create_time", startTime, endTime);
// 修改标签查询逻辑使用EXISTS代替IN
if (StrUtil.isNotBlank(tagIds)) {
// 构建EXISTS子查询
String existsSql = "EXISTS (SELECT 1 FROM membership_tag_member mtm " +
"WHERE (mtm.ab98_user_id = t.ab98_user_id " +
"OR mtm.wx_user_id = t.wx_user_id) " +
"AND mtm.deleted = 0 " +
"AND mtm.tag_id IN (" +
tagIds +
"))";
queryWrapper.apply(existsSql);
}
// 添加是否绑定ab98UserId的条件 // 添加是否绑定ab98UserId的条件
if (hasAb98UserId != null) { if (hasAb98UserId != null) {
if (hasAb98UserId) { if (hasAb98UserId) {

View File

@ -53,7 +53,7 @@ public class MembershipTagMemberApplicationService {
public void deleteTagMember(BulkOperationCommand<Long> command) { public void deleteTagMember(BulkOperationCommand<Long> command) {
for (Long tagMemberId : command.getIds()) { for (Long tagMemberId : command.getIds()) {
MembershipTagMemberModel model = tagMemberModelFactory.loadById(tagMemberId); MembershipTagMemberModel model = tagMemberModelFactory.loadById(tagMemberId);
model.deleteById(); model.removeById();
} }
} }

View File

@ -4,6 +4,7 @@ import com.agileboot.common.core.base.BaseEntity;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable; import java.io.Serializable;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
@ -31,6 +32,13 @@ public class MembershipTagMemberEntity extends BaseEntity<MembershipTagMemberEnt
@TableId(value = "id", type = IdType.AUTO) @TableId(value = "id", type = IdType.AUTO)
private Long id; private Long id;
/**
* deleted字段请在数据库中 设置为tinyInt 并且非null 默认值为0
*/
@ApiModelProperty("删除标志0代表存在 1代表删除")
@TableField("deleted")
private Boolean deleted;
@ApiModelProperty("企业微信id") @ApiModelProperty("企业微信id")
@TableField("corpid") @TableField("corpid")
private String corpid; private String corpid;

View File

@ -60,16 +60,10 @@ public class MembershipTagMemberModel extends MembershipTagMemberEntity {
// 可以在此添加更详细的用户存在性检查 // 可以在此添加更详细的用户存在性检查
} }
@Override /**
public boolean updateById() { * 物理删除标签关联
if (AgileBootConfig.isDemoEnabled() && isSpecialTagMember()) { */
throw new ApiException(ErrorCode.FAILED); public boolean removeById() {
} return tagMemberService.removeById(getId());
return super.updateById();
}
// 示例方法判断是否为特殊标签关联可根据业务需求实现
private boolean isSpecialTagMember() {
return false;
} }
} }