# 会员管理模块 (business-member)

## 模块概述

会员管理模块是企业级会员体系的核心模块，提供完整的会员全生命周期管理能力，包括会员注册、等级管理、积分体系、优惠券发放与核销等功能。

发票申请相关能力已迁移至 **`business-finance`** 模块（表名仍为 `app_member_invoice_apply`，管理端与小程序接口路径不变）。

---

## 模块结构

```
business-member/
├── business-member-bean/              # Bean层（Entity、DTO、VO、Convert）
│   └── src/main/java/com/jeesharp/business/modules/member/
│       ├── annotation/                # 自定义注解
│       │   ├── SensitiveField.java       # 敏感字段脱敏注解
│       │   └── SensitiveFieldSerializer.java  # 脱敏序列化器
│       ├── convert/                   # 转换器
│       │   └── MemberConvert.java        # 会员转换器
│       ├── dto/                       # 数据传输对象
│       │   └── MemberSaveDTO.java        # 会员保存DTO
│       ├── entity/                    # 实体类
│       │   ├── Member.java               # 会员实体
│       │   └── MemberLevel.java          # 会员等级实体
│       └── vo/                        # 视图对象
│           ├── MemberQueryVO.java        # 会员查询VO
│           ├── MemberInfoVO.java         # 会员信息VO
│           ├── MemberExportVO.java       # 会员导出VO
│           ├── MemberImportVO.java       # 会员导入VO
│           └── MemberLevelQueryVO.java   # 会员等级查询VO
│
├── business-member-service/           # Service层（Service、Mapper）
│   └── src/main/java/com/jeesharp/business/modules/member/
│       ├── mapper/                    # MyBatis Mapper
│       │   ├── MemberMapper.java         # 会员Mapper
│       │   ├── MemberLevelMapper.java    # 会员等级Mapper
│       │   └── xml/                      # Mapper XML
│       │       ├── MemberMapper.xml
│       │       └── MemberLevelMapper.xml
│       └── service/                   # 领域服务
│           ├── MemberService.java        # 会员服务接口
│           ├── MemberLevelService.java   # 会员等级服务接口
│           └── impl/                     # 服务实现
│               ├── MemberServiceImpl.java
│               └── MemberLevelServiceImpl.java
│
├── business-member-application/       # Application层（应用服务）
│   └── src/main/java/com/jeesharp/business/modules/member/
│       └── application/
│           └── MemberApplicationService.java  # 会员应用服务
│
├── business-member-controller/        # Controller层（控制器）
│   └── src/main/java/com/jeesharp/business/modules/member/
│       └── controller/
│           └── MemberController.java     # 会员管理控制器
│
└── src/main/resources/
    └── sql/
        └── member.sql                 # 数据库建表脚本
```

### 模块依赖关系

```
Controller → Application → Service → Bean
    │            │            │         │
    └────────────┴────────────┴─────────┴──→ jeesharp-spring-boot-starter-mybatis
```

---

## 敏感信息脱敏

本模块提供了完整的敏感信息脱敏解决方案，通过注解 `@SensitiveField` 实现。

### 支持的脱敏类型

| 类型 | 说明 | 示例 |
|------|------|------|
| `MOBILE` | 手机号脱敏（保留前3后4） | 138****1234 |
| `ID_CARD` | 身份证脱敏（保留前6后4） | 110101********1234 |
| `BANK_CARD` | 银行卡脱敏（保留前4后4） | 6222****1234 |
| `EMAIL` | 邮箱脱敏（保留@前2位和域名） | te****@example.com |
| `NAME` | 姓名脱敏（保留姓） | 张** |
| `ADDRESS` | 地址脱敏（保留前6位） | 北京市朝阳区**** |
| `PASSWORD` | 密码脱敏（全部替换） | ****** |
| `CUSTOM` | 自定义脱敏 | 支持自定义前后保留长度 |

### 使用示例

```java
@Data
public class MemberInfoVO {

    @SensitiveField(SensitiveField.SensitiveType.MOBILE)
    @JsonSerialize(using = SensitiveFieldSerializer.class)
    private String mobile;

    @SensitiveField(SensitiveField.SensitiveType.ID_CARD)
    @JsonSerialize(using = SensitiveFieldSerializer.class)
    private String idCard;

    @SensitiveField(value = SensitiveField.SensitiveType.CUSTOM, prefixLength = 2, suffixLength = 4)
    @JsonSerialize(using = SensitiveFieldSerializer.class)
    private String customField;
}
```

---

## API 接口

### 接口基础路径

```
${jeesharp.web.adminPath}/member/member/v1
```

> 命名规则：`${jeesharp.web.adminPath}/模块名/类名/版本号`

### 会员管理接口

| 接口 | 方法 | URL | 说明 |
|------|------|-----|------|
| 获取详情 | GET | `/v1/info?id=xxx` | 获取会员详细信息 |
| 分页列表 | POST | `/v1/list` | 分页查询会员列表 |
| 保存 | POST | `/v1/save` | 新增或更新会员 |
| 删除 | GET | `/v1/delete?ids=xxx` | 批量删除会员 |
| 导出 | POST | `/v1/export` | 导出会员Excel |
| 导入 | POST | `/v1/import` | 导入会员Excel |
| 下载模板 | GET | `/v1/import/template` | 下载导入模板 |
| 禁用 | GET | `/v1/disable?id=xxx` | 禁用会员 |
| 启用 | GET | `/v1/enable?id=xxx` | 启用会员 |
| 增加积分 | POST | `/v1/addPoints` | 增加会员积分 |
| 扣减积分 | POST | `/v1/deductPoints` | 扣减会员积分 |
| 增加成长值 | POST | `/v1/addGrowthValue` | 增加成长值 |

### 权限配置

| 权限标识 | 说明 |
|----------|------|
| `member:member:info` | 查看会员详情 |
| `member:member:list` | 查看会员列表 |
| `member:member:save` | 保存会员 |
| `member:member:delete` | 删除会员 |
| `member:member:export` | 导出会员 |
| `member:member:import` | 导入会员 |
| `member:member:disable` | 禁用会员 |
| `member:member:enable` | 启用会员 |
| `member:member:points` | 积分管理 |
| `member:member:growth` | 成长值管理 |

---

## 基础字段规范

所有表均包含以下标准基础字段：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| `id` | VARCHAR(64) | 主键ID |
| `create_by` | VARCHAR(64) | 创建者 |
| `create_date` | DATETIME | 创建时间 |
| `update_by` | VARCHAR(64) | 更新者 |
| `update_date` | DATETIME | 更新时间 |
| `del_flag` | CHAR(1) | 删除标记：0-正常 1-删除 |
| `remarks` | VARCHAR(255) | 备注信息 |
| `tenant_code` | VARCHAR(64) | 租户编码 |
| `tenant_id` | VARCHAR(64) | 租户ID |

## 功能特性

- **会员管理**：注册、认证、信息维护、状态管理
- **等级体系**：多级会员等级、自动升降级、等级特权配置
- **积分系统**：积分获取、消费、冻结、过期等全流程管理
- **优惠券系统**：优惠券模板、发放、领取、核销、退回
- **会员标签**：标签管理、自动打标、精准营销
- **数据统计**：消费统计、行为分析、会员画像

---

## 数据库表设计

### 表结构概览

| 序号 | 表名 | 说明 | 必需 |
|------|------|------|------|
| 1 | `app_member_level` | 会员等级配置表 | ✅ |
| 2 | `app_member` | 会员主表 | ✅ |
| 3 | `app_member_points_log` | 积分流水表 | ✅ |
| 4 | `app_coupon_template` | 优惠券模板表 | ✅ |
| 5 | `app_member_coupon` | 会员优惠券领取记录表 | ✅ |
| 6 | `app_member_growth_log` | 会员成长值流水表 | 可选 |
| 7 | `app_member_balance_log` | 会员余额流水表 | 可选 |
| 8 | `app_member_tag` | 会员标签表 | 可选 |
| 9 | `app_member_tag_relation` | 会员标签关联表 | 可选 |

### ER 关系图

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                           会员管理系统 ER 图                                  │
└─────────────────────────────────────────────────────────────────────────────┘

┌──────────────────┐         ┌──────────────────┐
│ app_member_level │ 1    n  │    app_member    │
│   (会员等级配置)   │◄────────│     (会员主表)    │
└──────────────────┘         └────────┬─────────┘
                                      │
           ┌──────────────────────────┼──────────────────────────┐
           │                          │                          │
           ▼                          ▼                          ▼
┌──────────────────┐     ┌──────────────────┐     ┌──────────────────┐
│app_member_points │     │ app_member_coupon│     │app_member_growth │
│     _log         │     │                  │     │     _log         │
│   (积分流水)      │     │  (优惠券领取记录) │     │   (成长值流水)    │
└──────────────────┘     └────────┬─────────┘     └──────────────────┘
                                  │
                                  │ n
                                  │
                                  ▼ 1
                         ┌──────────────────┐
                         │app_coupon_template│
                         │   (优惠券模板)    │
                         └──────────────────┘
```

---

## 核心表详细设计

### 1. 会员等级配置表 (app_member_level)

存储会员等级的配置信息，包括升级条件、折扣率、积分倍率等特权配置。

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | VARCHAR(64) | 主键ID |
| level_code | VARCHAR(32) | 等级编码（NORMAL/SILVER/GOLD/PLATINUM/DIAMOND） |
| level_name | VARCHAR(64) | 等级名称 |
| level_sort | INT | 等级排序（越大越高） |
| min_growth_value | INT | 升级所需最低成长值 |
| max_growth_value | INT | 该等级成长值上限 |
| discount_rate | DECIMAL(3,2) | 折扣率（0.95 = 95折） |
| points_rate | DECIMAL(5,2) | 积分倍率（1.5 = 1.5倍积分） |
| birthday_points | INT | 生日赠送积分 |
| upgrade_gift_points | INT | 升级赠送积分 |
| privileges | TEXT | 会员特权（JSON格式） |
| downgrade_enabled | TINYINT | 是否启用降级 |

**默认等级数据**：

| 等级编码 | 等级名称 | 成长值范围 | 折扣 | 积分倍率 |
|----------|----------|------------|------|----------|
| NORMAL | 普通会员 | 0-999 | 无折扣 | 1倍 |
| SILVER | 白银会员 | 1000-4999 | 98折 | 1.2倍 |
| GOLD | 黄金会员 | 5000-19999 | 95折 | 1.5倍 |
| PLATINUM | 铂金会员 | 20000-49999 | 92折 | 2倍 |
| DIAMOND | 钻石会员 | 50000+ | 88折 | 3倍 |

---

### 2. 会员主表 (app_member)

存储会员基本信息、等级信息、积分信息、消费统计等核心数据。

**基本信息字段**：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | VARCHAR(64) | 主键（会员ID） |
| member_no | VARCHAR(32) | 会员编号（对外展示） |
| user_id | VARCHAR(64) | 关联系统用户ID |
| nickname | VARCHAR(64) | 昵称 |
| real_name | VARCHAR(64) | 真实姓名 |
| mobile | VARCHAR(20) | 手机号（加密） |
| avatar | VARCHAR(500) | 头像URL |
| gender | TINYINT | 性别：0-未知 1-男 2-女 |
| birthday | DATE | 生日 |

**第三方登录（OAuth）**：不在 `app_member` 冗余 openid/unionid，统一见表 **`app_member_oauth`**（平台、应用类型、appId、openid、unionid 等）。

**等级相关字段**：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| level_id | VARCHAR(64) | 当前等级ID |
| level_code | VARCHAR(32) | 当前等级编码 |
| growth_value | INT | 成长值 |
| level_expire_date | DATETIME | 等级过期时间 |

**积分相关字段**：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| total_points | INT | 累计获得积分 |
| available_points | INT | 可用积分 |
| frozen_points | INT | 冻结积分 |
| used_points | INT | 已使用积分 |
| expired_points | INT | 已过期积分 |

**消费统计字段**：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| total_consume_amount | DECIMAL(12,2) | 累计消费金额 |
| total_consume_count | INT | 累计消费次数 |
| last_consume_date | DATETIME | 最后消费时间 |
| avg_consume_amount | DECIMAL(10,2) | 平均消费金额 |

**状态字段**：

| 字段名 | 类型 | 说明 |
|--------|------|------|
| status | TINYINT | 状态：0-禁用 1-正常 2-待审核 3-已注销 |
| source | VARCHAR(32) | 来源：APP/WECHAT_MINI/WECHAT_MP/H5/PC/HUAWEI/ALIPAY/QQ/WEIBO/APPLE/DOUYIN/DINGTALK/FEISHU |
| last_login_type | VARCHAR(32) | 最后登录方式 |
| is_real_name | TINYINT | 是否实名认证 |

---

### 3. 积分流水表 (app_member_points_log)

记录会员积分的所有变动记录，支持积分追溯和对账。

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | VARCHAR(64) | 主键ID |
| member_id | VARCHAR(64) | 会员ID |
| points_type | TINYINT | 类型：1-获取 2-消费 3-冻结 4-解冻 5-过期 6-调整 |
| points | INT | 变动数量（正/负） |
| before_points | INT | 变动前可用积分 |
| after_points | INT | 变动后可用积分 |
| biz_type | VARCHAR(32) | 业务类型 |
| biz_id | VARCHAR(64) | 业务ID |
| expire_date | DATETIME | 积分过期时间 |

**业务类型枚举 (biz_type)**：

| 编码 | 说明 |
|------|------|
| CONSUME | 消费获取 |
| ORDER_CANCEL | 订单取消扣回 |
| SIGN_IN | 签到获取 |
| SHARE | 分享获取 |
| INVITE | 邀请好友 |
| BIRTHDAY | 生日赠送 |
| UPGRADE | 升级赠送 |
| EXCHANGE | 积分兑换 |
| REFUND | 退款扣减 |
| MANUAL | 人工调整 |
| EXPIRE | 过期清零 |
| ACTIVITY | 活动获取 |

---

### 4. 优惠券模板表 (app_coupon_template)

定义优惠券的规则，包括优惠方式、使用条件、发放规则等。

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | VARCHAR(64) | 主键ID |
| coupon_code | VARCHAR(32) | 优惠券编码 |
| coupon_name | VARCHAR(128) | 优惠券名称 |
| coupon_type | TINYINT | 类型：1-满减券 2-折扣券 3-无门槛券 4-兑换券 |
| discount_type | TINYINT | 优惠方式：1-金额 2-折扣 |
| discount_value | DECIMAL(10,2) | 优惠值 |
| min_consume_amount | DECIMAL(10,2) | 最低消费金额 |
| max_discount_amount | DECIMAL(10,2) | 最大优惠金额 |
| total_count | INT | 发行总量（-1不限） |
| per_member_limit | INT | 每人限领数量 |
| get_type | TINYINT | 领取方式：1-手动 2-自动 3-兑换 |
| validity_type | TINYINT | 有效期类型：1-固定时间段 2-领取后N天 |
| status | TINYINT | 状态：0-下架 1-进行中 2-已结束 3-待开始 |

---

### 5. 会员优惠券领取记录表 (app_member_coupon)

记录会员领取的优惠券实例，包含领取信息、使用状态、核销记录等。

| 字段名 | 类型 | 说明 |
|--------|------|------|
| id | VARCHAR(64) | 主键ID |
| coupon_sn | VARCHAR(64) | 优惠券唯一码（券码） |
| member_id | VARCHAR(64) | 会员ID |
| template_id | VARCHAR(64) | 优惠券模板ID |
| coupon_name | VARCHAR(128) | 优惠券名称（冗余） |
| get_type | TINYINT | 领取方式 |
| get_date | DATETIME | 领取时间 |
| valid_start_date | DATETIME | 有效期开始 |
| valid_end_date | DATETIME | 有效期结束 |
| status | TINYINT | 状态：0-未使用 1-已使用 2-已过期 3-已冻结 4-已作废 |
| use_date | DATETIME | 使用时间 |
| use_order_id | VARCHAR(64) | 使用订单ID |
| use_amount | DECIMAL(10,2) | 实际抵扣金额 |

---

## 业务流程

### 会员等级升级流程

```
消费/签到/邀请等行为
        │
        ▼
  ┌─────────────┐
  │ 计算成长值   │
  └──────┬──────┘
         │
         ▼
  ┌─────────────┐    否
  │ 是否达到升级 │────────┐
  │   条件？    │        │
  └──────┬──────┘        │
         │是             │
         ▼               │
  ┌─────────────┐        │
  │ 更新会员等级 │        │
  │ 发放升级礼包 │        │
  │ 记录成长值流水│       │
  └──────┬──────┘        │
         │               │
         ▼               │
  ┌─────────────┐        │
  │  完成       │◄───────┘
  └─────────────┘
```

### 积分消费流程

```
用户下单使用积分
        │
        ▼
  ┌─────────────┐
  │ 校验积分余额 │
  └──────┬──────┘
         │
         ▼
  ┌─────────────┐    否
  │ 积分是否充足？│────────┐
  └──────┬──────┘        │
         │是             │
         ▼               ▼
  ┌─────────────┐  ┌─────────────┐
  │ 冻结积分    │  │ 提示余额不足 │
  └──────┬──────┘  └─────────────┘
         │
         ▼
  ┌─────────────┐
  │ 支付成功    │
  └──────┬──────┘
         │
         ▼
  ┌─────────────┐
  │ 扣减积分    │
  │ 记录流水    │
  └─────────────┘
```

### 优惠券核销流程

```
用户选择优惠券下单
        │
        ▼
  ┌─────────────┐
  │ 校验优惠券   │
  │ 状态/有效期  │
  └──────┬──────┘
         │
         ▼
  ┌─────────────┐    否
  │ 是否满足    │────────┐
  │ 使用条件？   │        │
  └──────┬──────┘        │
         │是             ▼
         ▼        ┌─────────────┐
  ┌─────────────┐ │ 提示不满足  │
  │ 冻结优惠券   │ │ 使用条件    │
  └──────┬──────┘ └─────────────┘
         │
         ▼
  ┌─────────────┐
  │ 支付成功    │
  └──────┬──────┘
         │
         ▼
  ┌─────────────┐
  │ 核销优惠券   │
  │ 更新状态    │
  │ 记录抵扣金额 │
  └─────────────┘
```

---

## 索引设计说明

### 会员主表索引

| 索引名 | 字段 | 类型 | 说明 |
|--------|------|------|------|
| uk_member_no | member_no | UNIQUE | 会员编号唯一 |
| uk_mobile_tenant | mobile, tenant_id | UNIQUE | 手机号+租户唯一 |
| uk_openid | openid | UNIQUE | 微信OpenID唯一 |
| uk_invite_code | invite_code | UNIQUE | 邀请码唯一 |
| idx_level_code | level_code | INDEX | 等级查询 |
| idx_status | status | INDEX | 状态筛选 |
| idx_register_date | register_date | INDEX | 注册时间范围查询 |

### 积分流水表索引

| 索引名 | 字段 | 说明 |
|--------|------|------|
| idx_member_id | member_id | 会员积分查询 |
| idx_biz_type | biz_type | 业务类型筛选 |
| idx_create_date | create_date | 时间范围查询 |
| idx_expire_date | expire_date | 过期积分处理 |

### 优惠券领取表索引

| 索引名 | 字段 | 说明 |
|--------|------|------|
| uk_coupon_sn | coupon_sn | 券码唯一 |
| idx_member_status | member_id, status | 会员可用券查询 |
| idx_valid_end_date | valid_end_date | 过期券处理 |

---

## 使用说明

### 执行 SQL

```bash
# 执行建表语句
mysql -u root -p your_database < src/main/resources/sql/member.sql
```

### 注意事项

1. **敏感信息加密**：手机号、身份证号等敏感字段建议加密存储
2. **积分过期处理**：需要定时任务处理过期积分
3. **优惠券过期处理**：需要定时任务更新过期优惠券状态
4. **等级降级处理**：如启用降级机制，需要定时任务检查保级条件
5. **多租户支持**：所有表均包含 `tenant_id` 和 `tenant_code` 字段

---

## 版本记录

| 版本 | 日期 | 说明 |
|------|------|------|
| 1.0.0 | 2026-01-24 | 初始版本，包含核心表设计 |
