Skip to content

会员关系表

1. 概述

会员关系表是梵医云系统中用于管理会员信息、会员等级、会员分组、会员标签等相关数据的核心模块。该模块提供了完整的会员管理体系,包括会员基本信息、会员等级体系、会员分组管理、会员标签管理、积分管理、经验管理等功能。

2. 表结构

2.1 会员用户表 (member_user)

会员用户表是会员模块的核心表,存储会员的基本信息、账号信息、等级信息等。

2.1.1 表结构

字段名类型长度允许空默认值说明
idbigint20-用户ID(主键)
mobilevarchar11NULL手机号
passwordvarchar100NULL加密后的密码
statustinyint40账号状态(0正常 1停用)
register_ipvarchar50NULL注册IP
register_terminaltinyint4NULL注册终端(1H5 2小程序 3APP)
login_ipvarchar50NULL最后登录IP
login_datedatetime-NULL最后登录时间
nicknamevarchar50NULL用户昵称
avatarvarchar512NULL用户头像
namevarchar50NULL真实名字
sextinyint4NULL性别(1男 2女 3未知)
birthdaydatetime-NULL出生日期
area_idint11NULL所在地
markvarchar500NULL用户备注
pointint110积分
tag_idsjson-NULL会员标签列表
level_idbigint20NULL会员级别编号
experienceint110会员经验
total_pay_amountbigint200消费总额
group_idbigint20NULL用户分组编号
old_mobilevarchar11NULL用户注销老手机号
active_usertinyint4NULL活动用户
promo_codevarchar50NULL营销代码
store_idbigint20NULL营销代码绑定门店ID
tenant_idbigint200租户编号
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.1.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
uk_mobile唯一mobile手机号唯一索引
idx_level_id普通level_id会员等级索引
idx_group_id普通group_id会员分组索引
idx_tenant_id普通tenant_id租户索引

2.1.3 Java 实体类

java
@TableName(value = "member_user", autoResultMap = true)
@KeySequence("member_user_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberUserDO extends TenantBaseDO {

    @TableId
    private Long id;
    private String mobile;
    private String password;
    private Integer status;
    private String registerIp;
    private Integer registerTerminal;
    private String loginIp;
    private LocalDateTime loginDate;
    private String nickname;
    private String avatar;
    private String name;
    private Integer sex;
    private LocalDateTime birthday;
    private Integer areaId;
    private String mark;
    private Integer point;
    @TableField(typeHandler = LongListTypeHandler.class)
    private List<Long> tagIds;
    private Long levelId;
    private Integer experience;
    private Long totalPayAmount;
    private Long groupId;
    private String oldMobile;
    private Integer activeUser;
    private String promoCode;
    private Long storeId;
}

2.2 会员分组表 (member_group)

会员分组表用于管理会员的分组信息,可以将会员按照不同的维度进行分组管理。

2.2.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
namevarchar50-分组名称
remarkvarchar500NULL备注
statustinyint40状态(0正常 1停用)
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.2.2 索引

索引名类型字段说明
PRIMARY主键id主键索引

2.2.3 Java 实体类

java
@TableName("member_group")
@KeySequence("member_group_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberGroupDO extends BaseDO {

    @TableId
    private Long id;
    private String name;
    private String remark;
    private Integer status;
}

2.3 会员标签表 (member_tag)

会员标签表用于管理会员的标签信息,可以给会员打上不同的标签,方便进行精准营销。

2.3.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
namevarchar50-标签名称
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.3.2 索引

索引名类型字段说明
PRIMARY主键id主键索引

2.3.3 Java 实体类

java
@TableName("member_tag")
@KeySequence("member_tag_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberTagDO extends BaseDO {

    @TableId
    private Long id;
    private String name;
}

2.4 会员等级表 (member_level)

会员等级表用于配置会员等级体系,每个等级对应不同的权益和折扣。

2.4.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
namevarchar50-等级名称
levelint11-等级
experienceint11-升级经验
discount_percentint11-享受折扣
iconvarchar512NULL等级图标
background_urlvarchar512NULL等级背景图
statustinyint40状态(0正常 1停用)
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.4.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_level普通level等级索引

2.4.3 Java 实体类

java
@TableName("member_level")
@KeySequence("member_level_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberLevelDO extends BaseDO {

    @TableId
    private Long id;
    private String name;
    private Integer level;
    private Integer experience;
    private Integer discountPercent;
    private String icon;
    private String backgroundUrl;
    private Integer status;
}

2.5 层级人员管理表 (member_hierarchical_personnel)

层级人员管理表用于管理门店或机构的层级人员关系。

2.5.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
remarkvarchar500NULL备注
post_managementint11NULL岗位管理
parentbigint20NULL父节点
user_idbigint20NULL绑定节点
namevarchar50NULL姓名
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.5.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_parent普通parent父节点索引
idx_user_id普通user_id用户索引

2.5.3 Java 实体类

java
@TableName("member_hierarchical_personnel")
@KeySequence("member_hierarchical_personnel_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class HierarchicalPersonnelDO extends BaseDO {

    public static final Long PARENT_ROOT = 0L;

    @TableId
    private Long id;
    private String remark;
    private Integer postManagement;
    private Long parent;
    private Long userId;
    private String name;
}

2.6 会员地址表 (member_address)

会员地址表用于管理会员的收货地址信息。

2.6.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
user_idbigint20-用户编号
namevarchar50-收件人名称
mobilevarchar11-手机号
area_idbigint20NULL地区编号
detail_addressvarchar500-收件详细地址
longitudevarchar50NULL经度
latitudevarchar50NULL纬度
default_statusbit1b'0'是否默认
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.6.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_user_id普通user_id用户索引

2.6.3 Java 实体类

java
@TableName("member_address")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberAddressDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private String name;
    private String mobile;
    private Long areaId;
    private String detailAddress;
    private String longitude;
    private String latitude;
    private Boolean defaultStatus;
}

2.7 会员积分记录表 (member_point_record)

会员积分记录表用于记录会员积分的变动情况。

2.7.1 表结构

字段名类型长度允许空默认值说明
idbigint20-自增主键
user_idbigint20-用户编号
biz_idvarchar64NULL业务编码
biz_typeint11-业务类型
titlevarchar100NULL积分标题
descriptionvarchar500NULL积分描述
pointint11-变动积分
total_pointint11-变动后的积分
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.7.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_user_id普通user_id用户索引
idx_biz_id普通biz_id业务编码索引

2.7.3 Java 实体类

java
@TableName("member_point_record")
@KeySequence("member_point_record_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberPointRecordDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private String bizId;
    private Integer bizType;
    private String title;
    private String description;
    private Integer point;
    private Integer totalPoint;
}

2.8 会员经验记录表 (member_experience_record)

会员经验记录表用于记录会员经验的变动情况。

2.8.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
user_idbigint20-用户编号
biz_typeint11-业务类型
biz_idvarchar64NULL业务编号
titlevarchar100NULL标题
descriptionvarchar500NULL描述
experienceint11-经验
total_experienceint11-变更后的经验
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.8.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_user_id普通user_id用户索引
idx_biz_id普通biz_id业务编码索引

2.8.3 Java 实体类

java
@TableName("member_experience_record")
@KeySequence("member_experience_record_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberExperienceRecordDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private Integer bizType;
    private String bizId;
    private String title;
    private String description;
    private Integer experience;
    private Integer totalExperience;
}

2.9 会员等级记录表 (member_level_record)

会员等级记录表用于记录会员等级的变更历史。

2.9.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
user_idbigint20-用户编号
level_idbigint20-等级编号
levelint11-会员等级
discount_percentint11-享受折扣
experienceint11-升级经验
user_experienceint11-会员此时的经验
remarkvarchar500NULL备注
descriptionvarchar500NULL描述
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.9.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_user_id普通user_id用户索引

2.9.3 Java 实体类

java
@TableName("member_level_record")
@KeySequence("member_level_record_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberLevelRecordDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private Long levelId;
    private Integer level;
    private Integer discountPercent;
    private Integer experience;
    private Integer userExperience;
    private String remark;
    private String description;
}

2.10 签到记录表 (member_sign_in_record)

签到记录表用于记录会员的签到情况。

2.10.1 表结构

字段名类型长度允许空默认值说明
idbigint20-编号(主键)
user_idbigint20-签到用户
dayint11-第几天签到
pointint11-签到的积分
experienceint11-签到的经验
creatorvarchar64''创建者
create_timedatetime-CURRENT_TIMESTAMP创建时间
updatervarchar64''更新者
update_timedatetime-CURRENT_TIMESTAMP更新时间
deletedbit1b'0'是否删除

2.10.2 索引

索引名类型字段说明
PRIMARY主键id主键索引
idx_user_id普通user_id用户索引

2.10.3 Java 实体类

java
@TableName("member_sign_in_record")
@KeySequence("member_sign_in_record_seq")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MemberSignInRecordDO extends BaseDO {

    @TableId
    private Long id;
    private Long userId;
    private Integer day;
    private Integer point;
    private Integer experience;
}

3. 表关系图

member_user (会员用户表)
    ├── member_group (会员分组表) - 通过 group_id 关联
    ├── member_tag (会员标签表) - 通过 tag_ids 关联
    ├── member_level (会员等级表) - 通过 level_id 关联
    ├── member_address (会员地址表) - 通过 user_id 关联
    ├── member_point_record (会员积分记录表) - 通过 user_id 关联
    ├── member_experience_record (会员经验记录表) - 通过 user_id 关联
    ├── member_level_record (会员等级记录表) - 通过 user_id 关联
    ├── member_sign_in_record (签到记录表) - 通过 user_id 关联
    └── member_hierarchical_personnel (层级人员管理表) - 通过 user_id 关联

4. 使用示例

4.1 创建会员

java
@Service
public class MemberUserServiceImpl implements MemberUserService {

    @Resource
    private MemberUserMapper memberUserMapper;

    public Long createMember(MemberUserSaveReqVO createReqVO) {
        MemberUserDO memberUser = MemberUserDO.builder()
            .mobile(createReqVO.getMobile())
            .password(encodePassword(createReqVO.getPassword()))
            .nickname(createReqVO.getNickname())
            .avatar(createReqVO.getAvatar())
            .status(CommonStatusEnum.ENABLE.getStatus())
            .build();
        
        memberUserMapper.insert(memberUser);
        return memberUser.getId();
    }
}

4.2 查询会员列表

java
@Service
public class MemberUserServiceImpl implements MemberUserService {

    @Resource
    private MemberUserMapper memberUserMapper;

    public PageResult<MemberUserDO> getMemberUserPage(MemberUserPageReqVO pageReqVO) {
        return memberUserMapper.selectPage(pageReqVO, 
            new LambdaQueryWrapperX<MemberUserDO>()
                .likeIfPresent(MemberUserDO::getNickname, pageReqVO.getNickname())
                .eqIfPresent(MemberUserDO::getMobile, pageReqVO.getMobile())
                .eqIfPresent(MemberUserDO::getLevelId, pageReqVO.getLevelId())
                .eqIfPresent(MemberUserDO::getGroupId, pageReqVO.getGroupId())
                .betweenIfPresent(MemberUserDO::getCreateTime, pageReqVO.getCreateTime())
                .orderByDesc(MemberUserDO::getId));
    }
}

4.3 增加会员积分

java
@Service
public class MemberPointServiceImpl implements MemberPointService {

    @Resource
    private MemberUserMapper memberUserMapper;

    @Resource
    private MemberPointRecordMapper memberPointRecordMapper;

    @Transactional(rollbackFor = Exception.class)
    public void addPoint(Long userId, Integer point, Integer bizType, String bizId, String title) {
        MemberUserDO user = memberUserMapper.selectById(userId);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }

        Integer totalPoint = user.getPoint() + point;
        
        memberUserMapper.updateById(MemberUserDO.builder()
            .id(userId)
            .point(totalPoint)
            .build());

        memberPointRecordMapper.insert(MemberPointRecordDO.builder()
            .userId(userId)
            .bizId(bizId)
            .bizType(bizType)
            .title(title)
            .point(point)
            .totalPoint(totalPoint)
            .build());
    }
}

4.4 升级会员等级

java
@Service
public class MemberLevelServiceImpl implements MemberLevelService {

    @Resource
    private MemberUserMapper memberUserMapper;

    @Resource
    private MemberLevelRecordMapper memberLevelRecordMapper;

    @Transactional(rollbackFor = Exception.class)
    public void upgradeLevel(Long userId, Long levelId) {
        MemberUserDO user = memberUserMapper.selectById(userId);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }

        MemberLevelDO level = memberLevelMapper.selectById(levelId);
        if (level == null) {
            throw exception(LEVEL_NOT_EXISTS);
        }

        memberUserMapper.updateById(MemberUserDO.builder()
            .id(userId)
            .levelId(levelId)
            .build());

        memberLevelRecordMapper.insert(MemberLevelRecordDO.builder()
            .userId(userId)
            .levelId(levelId)
            .level(level.getLevel())
            .discountPercent(level.getDiscountPercent())
            .experience(level.getExperience())
            .userExperience(user.getExperience())
            .description("会员等级升级")
            .build());
    }
}

4.5 会员签到

java
@Service
public class MemberSignInServiceImpl implements MemberSignInService {

    @Resource
    private MemberUserMapper memberUserMapper;

    @Resource
    private MemberSignInRecordMapper memberSignInRecordMapper;

    @Transactional(rollbackFor = Exception.class)
    public void signIn(Long userId) {
        MemberUserDO user = memberUserMapper.selectById(userId);
        if (user == null) {
            throw exception(USER_NOT_EXISTS);
        }

        Integer day = getSignInDay(userId);
        Integer point = getSignInPoint(day);
        Integer experience = getSignInExperience(day);

        memberUserMapper.updateById(MemberUserDO.builder()
            .id(userId)
            .point(user.getPoint() + point)
            .experience(user.getExperience() + experience)
            .build());

        memberSignInRecordMapper.insert(MemberSignInRecordDO.builder()
            .userId(userId)
            .day(day)
            .point(point)
            .experience(experience)
            .build());
    }
}

5. 业务规则

5.1 会员等级升级规则

  1. 会员经验达到下一等级的升级经验值时,自动升级
  2. 升级后享受对应等级的折扣权益
  3. 等级变更记录在 member_level_record 表中

5.2 积分规则

  1. 积分可以通过签到、消费、活动等方式获得
  2. 积分可以用于兑换商品或抵扣金额
  3. 积分变动记录在 member_point_record 表中

5.3 经验规则

  1. 经验可以通过签到、消费、活动等方式获得
  2. 经验用于会员等级升级
  3. 经验变动记录在 member_experience_record 表中

5.4 签到规则

  1. 每天签到可以获得积分和经验
  2. 连续签到天数越多,获得的奖励越多
  3. 签到记录在 member_sign_in_record 表中

6. 注意事项

  1. 会员手机号必须唯一,使用 uk_mobile 唯一索引保证
  2. 会员密码使用 BCrypt 加密存储
  3. 会员标签使用 JSON 类型存储,使用 LongListTypeHandler 处理
  4. 所有表都支持多租户,通过 tenant_id 字段隔离
  5. 所有表都支持逻辑删除,通过 deleted 字段标记
  6. 会员等级升级时,需要记录等级变更历史
  7. 积分和经验变动时,需要记录变动历史

注意:本文档持续更新中,如有问题请及时反馈。