# 账户数据模型

<cite>
**本文档引用的文件**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)
- [v_1_account_history_info.go](file://internal/model/entity/v_1_account_history_info.go)
- [v_1_account_info.go](file://internal/dao/internal/v_1_account_info.go)
- [account.go](file://internal/logic/account/account.go)
- [account.go](file://internal/service/account.go)
</cite>

## 目录
1. [介绍](#介绍)
2. [核心数据结构](#核心数据结构)
3. [字段定义与业务含义](#字段定义与业务含义)
4. [主键与索引设计](#主键与索引设计)
5. [外键关系](#外键关系)
6. [验证规则与业务逻辑](#验证规则与业务逻辑)
7. [数据表模式与示例数据](#数据表模式与示例数据)
8. [访问模式与缓存策略](#访问模式与缓存策略)
9. [数据生命周期管理](#数据生命周期管理)
10. [ORM映射与并发安全操作](#orm映射与并发安全操作)

## 介绍
本文档全面描述了kami_backend系统中账户数据模型的设计与实现。重点分析v_1_account_info实体的结构、字段含义、业务规则以及与其他实体的关系。文档还涵盖了账户数据的生命周期管理、访问模式、缓存策略以及GoFrame ORM框架下的实现细节。

## 核心数据结构

本节详细描述账户数据模型的核心结构，包括账户信息和账户历史信息两个主要实体。

```mermaid
erDiagram
v_1_account_info {
uint id PK
string status
string account_uid UK
string account_name
decimal balance
decimal settle_amount
decimal loan_amount
decimal wait_amount
decimal freeze_amount
decimal payfor_amount
datetime update_time
datetime create_time
}
v_1_account_history_info {
uint id PK
string account_uid FK
string account_name
string type
decimal amount
decimal balance
string order_id
datetime update_time
datetime create_time
float fee_amount
}
v_1_account_info ||--o{ v_1_account_history_info : "包含"
```

**图表来源**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)
- [v_1_account_history_info.go](file://internal/model/entity/v_1_account_history_info.go)

**本节来源**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)
- [v_1_account_history_info.go](file://internal/model/entity/v_1_account_history_info.go)

## 字段定义与业务含义

### 账户信息实体字段

| 字段名 | 数据类型 | 业务含义 |
|--------|--------|--------|
| Id | uint | 主键，自增唯一标识 |
| Status | string | 账户状态（正常、冻结、禁用等） |
| AccountUid | string | 账户UID，对应商户或代理的唯一标识 |
| AccountName | string | 账户名称，对应商户或代理的名称 |
| Balance | decimal.Decimal | 账户当前可用余额 |
| SettleAmount | decimal.Decimal | 已经结算的金额 |
| LoanAmount | decimal.Decimal | 押款金额，用于保证交易的资金 |
| WaitAmount | decimal.Decimal | 待结算资金，已完成但未结算的金额 |
| FreezeAmount | decimal.Decimal | 账户冻结金额，暂时不可用的资金 |
| PayforAmount | decimal.Decimal | 账户代付中金额，正在处理的代付资金 |
| UpdateTime | *gtime.Time | 记录最后更新时间 |
| CreateTime | *gtime.Time | 记录创建时间 |

**本节来源**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)

## 主键与索引设计

### 主键设计
- **主键**: `Id` 字段作为主键，采用自增整数类型，确保每条记录的唯一性。

### 索引设计
- **唯一索引**: `account_uid` 字段上建立唯一索引，确保每个账户UID的唯一性。
- **状态索引**: `status` 字段上建立索引，优化按状态查询的性能。
- **时间索引**: `create_time` 和 `update_time` 字段上建立索引，优化按时间范围查询的性能。

```mermaid
classDiagram
class V1AccountInfo {
+uint Id
+string Status
+string AccountUid
+string AccountName
+decimal.Decimal Balance
+decimal.Decimal SettleAmount
+decimal.Decimal LoanAmount
+decimal.Decimal WaitAmount
+decimal.Decimal FreezeAmount
+decimal.Decimal PayforAmount
+*gtime.Time UpdateTime
+*gtime.Time CreateTime
}
class V1AccountInfoColumns {
+string Id
+string Status
+string AccountUid
+string AccountName
+string Balance
+string SettleAmount
+string LoanAmount
+string WaitAmount
+string FreezeAmount
+string PayforAmount
+string UpdateTime
+string CreateTime
}
V1AccountInfo --> V1AccountInfoColumns : "列定义"
```

**图表来源**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)
- [v_1_account_info.go](file://internal/dao/internal/v_1_account_info.go)

**本节来源**
- [v_1_account_info.go](file://internal/dao/internal/v_1_account_info.go)

## 外键关系

账户数据模型与其他实体存在以下外键关系：

- **与商户/代理实体关系**: `account_uid` 字段关联到商户或代理的唯一标识，形成一对多关系。
- **与订单实体关系**: 账户历史记录中的 `order_id` 字段关联到订单实体，记录每笔交易的来源。
- **与用户实体关系**: 账户创建和操作关联到系统用户，通过审计日志追踪操作者。

```mermaid
graph TD
A[v_1_account_info] --> B[v_1_merchant_info]
A --> C[v_1_order_info]
A --> D[v_1_sys_user]
E[v_1_account_history_info] --> A
E --> C
```

**图表来源**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)
- [v_1_account_history_info.go](file://internal/model/entity/v_1_account_history_info.go)

## 验证规则与业务逻辑

### 账户状态管理
- 账户状态包括：正常、冻结、禁用等状态。
- 状态变更需要通过事务处理，确保数据一致性。
- 状态变更操作记录在账户历史中。

### 余额变更规则
- 余额变更必须通过事务处理，确保原子性。
- 每次余额变更生成一条历史记录。
- 余额不能为负数，除非有特殊业务场景允许透支。

```mermaid
flowchart TD
Start([开始余额变更]) --> Validate["验证输入参数"]
Validate --> CheckBalance["检查余额是否足够"]
CheckBalance --> |足够| UpdateBalance["更新余额"]
CheckBalance --> |不足| ReturnError["返回余额不足错误"]
UpdateBalance --> CreateHistory["创建账户历史记录"]
CreateHistory --> Commit["提交事务"]
Commit --> End([结束])
ReturnError --> End
```

**图表来源**
- [account.go](file://internal/logic/account/account.go)

**本节来源**
- [account.go](file://internal/logic/account/account.go)
- [account.go](file://internal/service/account.go)

## 数据表模式与示例数据

### 数据表模式
```sql
CREATE TABLE v1_account_info (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    status VARCHAR(50) NOT NULL,
    account_uid VARCHAR(100) NOT NULL UNIQUE,
    account_name VARCHAR(100) NOT NULL,
    balance DECIMAL(18,2) NOT NULL DEFAULT 0.00,
    settle_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00,
    loan_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00,
    wait_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00,
    freeze_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00,
    payfor_amount DECIMAL(18,2) NOT NULL DEFAULT 0.00,
    update_time DATETIME NOT NULL,
    create_time DATETIME NOT NULL,
    INDEX idx_status (status),
    INDEX idx_create_time (create_time)
);
```

### 示例数据
| id | status | account_uid | account_name | balance | settle_amount | loan_amount | wait_amount | freeze_amount | payfor_amount | update_time | create_time |
|----|--------|-------------|--------------|---------|---------------|-------------|-------------|---------------|---------------|-------------|-------------|
| 1 | normal | MCH001 | 商户A | 10000.00 | 5000.00 | 2000.00 | 3000.00 | 0.00 | 0.00 | 2024-01-01 10:00:00 | 2024-01-01 10:00:00 |

**本节来源**
- [v_1_account_info.go](file://internal/model/entity/v_1_account_info.go)

## 访问模式与缓存策略

### 访问模式
- **高频读取**: 账户余额查询是高频操作。
- **低频写入**: 账户信息变更相对较少。
- **批量操作**: 账户状态批量更新。

### 缓存策略
- **账户余额缓存**: 使用Redis缓存账户余额，设置合理的过期时间。
- **热点账户缓存**: 对频繁访问的账户信息进行缓存。
- **缓存更新策略**: 采用写穿透模式，更新数据库后同步更新缓存。

```mermaid
sequenceDiagram
participant Client as "客户端"
participant Cache as "Redis缓存"
participant DB as "数据库"
Client->>Cache : 查询账户余额
alt 缓存命中
Cache-->>Client : 返回缓存余额
else 缓存未命中
Cache->>DB : 查询数据库
DB-->>Cache : 返回余额
Cache->>Client : 返回余额并缓存
end
Client->>DB : 更新账户余额
DB-->>Client : 返回结果
DB->>Cache : 删除缓存
```

**图表来源**
- [account.go](file://internal/logic/account/account.go)

## 数据生命周期管理

### 账户生命周期
1. **创建**: 新商户或代理注册时创建账户。
2. **激活**: 完成身份验证后激活账户。
3. **正常使用**: 处理交易和资金流动。
4. **冻结**: 违规或风险控制时冻结账户。
5. **注销**: 商户或代理终止合作时注销账户。

### 保留策略
- **活跃账户**: 永久保留。
- **非活跃账户**: 保留3年，之后归档。
- **历史记录**: 账户历史记录永久保留。

### 归档规则
- 超过3年未活动的账户标记为归档状态。
- 归档账户数据迁移到历史数据库。
- 归档账户保留基本信息，详细交易数据压缩存储。

**本节来源**
- [account.go](file://internal/logic/account/account.go)

## ORM映射与并发安全操作

### GoFrame ORM映射
GoFrame ORM框架将账户数据模型映射到Go结构体，通过标签定义字段映射关系：

```go
type V1AccountInfo struct {
	Id           uint            `json:"id"           orm:"id"            description:"主键，自增"`
	Status       string          `json:"status"       orm:"status"        description:"状态"`
	AccountUid   string          `json:"accountUid"   orm:"account_uid"   description:"账户uid，对应为merchant_uid或者agent_uid"`
	// ... 其他字段
}
```

### DAO层并发安全操作
DAO层实现账户数据的并发安全操作，使用数据库事务确保数据一致性：

```mermaid
classDiagram
class V1AccountInfoDao {
-string group
-string table
-V1AccountInfoColumns columns
-[]gdb.ModelHandler handlers
+DB() gdb.DB
+Table() string
+Columns() V1AccountInfoColumns
+Group() string
+Ctx(ctx context.Context) *gdb.Model
+Transaction(ctx context.Context, f func(ctx context.Context, tx gdb.TX) error) error
}
class V1AccountInfoColumns {
+string Id
+string Status
+string AccountUid
+string AccountName
+string Balance
+string SettleAmount
+string LoanAmount
+string WaitAmount
+string FreezeAmount
+string PayforAmount
+string UpdateTime
+string CreateTime
}
V1AccountInfoDao --> V1AccountInfoColumns : "包含"
```

**图表来源**
- [v_1_account_info.go](file://internal/dao/internal/v_1_account_info.go)

**本节来源**
- [v_1_account_info.go](file://internal/dao/internal/v_1_account_info.go)
- [account.go](file://internal/logic/account/account.go)