|
|
@@ -0,0 +1,127 @@
|
|
|
+# Fund模块小数处理梳理
|
|
|
+
|
|
|
+**任务时间**: 2025年06月11日 14:42:17 CST
|
|
|
+**任务内容**: 梳理Fund模块目前关于小数的处理
|
|
|
+
|
|
|
+## 1. 概述
|
|
|
+
|
|
|
+Fund模块采用**整数存储、小数显示**的设计模式,通过精度配置实现小数处理。系统中存在多种小数处理方式,包括固定1000倍数处理和基于币种精度的动态处理。
|
|
|
+
|
|
|
+## 2. 数据存储结构
|
|
|
+
|
|
|
+### 2.1 核心表结构
|
|
|
+
|
|
|
+#### kku_fund 表
|
|
|
+- `balance` 字段:`bigint` 类型,存储整数形式的余额
|
|
|
+- 实际金额 = balance / (10^precision)
|
|
|
+
|
|
|
+#### kku_fund_currency 表
|
|
|
+- `data1` 字段:JSON格式,存储币种配置信息
|
|
|
+- 精度信息存储在 `data1.precision` 中
|
|
|
+
|
|
|
+#### kku_fund_logs 表
|
|
|
+- `amount` 字段:`bigint` 类型,存储整数形式的操作金额
|
|
|
+- `before_balance`、`later_balance`:整数形式的余额记录
|
|
|
+
|
|
|
+### 2.2 当前币种配置
|
|
|
+```sql
|
|
|
+-- 金币 (GOLD): {"balance":1} - 未配置precision
|
|
|
+-- 钻石 (OWG): {"balance":2} - 未配置precision
|
|
|
+-- 人民币 (CNY): {} - 空配置
|
|
|
+-- 美元 (USD): {} - 空配置
|
|
|
+```
|
|
|
+
|
|
|
+## 3. 小数处理方式
|
|
|
+
|
|
|
+### 3.1 固定1000倍数处理(历史遗留)
|
|
|
+
|
|
|
+#### 验证器
|
|
|
+- `UserFundCheck1000Validator`: 验证时将金额乘以1000
|
|
|
+- `DataFundCheck1000Validator`: 数据验证时乘以1000
|
|
|
+- `FundR1000CheckValidator`: 检查是否为1000的倍数
|
|
|
+
|
|
|
+#### 显示方法
|
|
|
+- `GridHelper::columnBalance1000()`: 显示时除以1000,保留3位小数
|
|
|
+- `GridHelper::columnAmount1000()`: 操作金额除以1000显示
|
|
|
+- `GridHelper::columnMoney1000()`: 通用金额格式化,除以1000
|
|
|
+
|
|
|
+### 3.2 基于币种精度的动态处理
|
|
|
+
|
|
|
+#### CurrencyService 类
|
|
|
+```php
|
|
|
+// 获取币种精度(默认2位小数)
|
|
|
+static public function getCurrencyPrecision($currency_id)
|
|
|
+
|
|
|
+// 格式化金额显示
|
|
|
+static public function formatAmount($amount, $currency_id)
|
|
|
+
|
|
|
+// 用户输入转存储格式
|
|
|
+static public function convertToStorageAmount($amount, $currency_id)
|
|
|
+
|
|
|
+// 存储格式转实际金额
|
|
|
+static public function convertFromStorageAmount($storageAmount, $currency_id)
|
|
|
+```
|
|
|
+
|
|
|
+#### CurrencyDto 类
|
|
|
+```php
|
|
|
+// 格式化金额显示
|
|
|
+public function formatAmount(int $amount): string
|
|
|
+
|
|
|
+// 用户输入转存储格式
|
|
|
+public function convertToStorageAmount(float $amount): int
|
|
|
+
|
|
|
+// 存储格式转实际金额
|
|
|
+public function convertFromStorageAmount(int $storageAmount): float
|
|
|
+```
|
|
|
+
|
|
|
+### 3.3 NumberWan 高精度处理
|
|
|
+
|
|
|
+支持40位精度(20位整数 + 20位小数)的万分位转换:
|
|
|
+- `formatToWan()`: 万分位格式化
|
|
|
+- `parseFromWan()`: 万分位反向转换
|
|
|
+- `smartFormat()`: 智能格式化选择
|
|
|
+
|
|
|
+## 4. 问题分析
|
|
|
+
|
|
|
+### 4.1 精度配置缺失
|
|
|
+- 当前币种的 `data1` 字段中缺少 `precision` 配置
|
|
|
+- `getCurrencyPrecision()` 方法默认返回2位小数
|
|
|
+- 实际业务可能需要不同的精度要求
|
|
|
+
|
|
|
+### 4.2 处理方式不统一
|
|
|
+- 同时存在1000倍数处理和动态精度处理
|
|
|
+- 不同模块可能使用不同的处理方式
|
|
|
+- 缺乏统一的小数处理标准
|
|
|
+
|
|
|
+### 4.3 显示格式不一致
|
|
|
+- `columnBalance()`: 整数显示,无小数
|
|
|
+- `columnBalance1000()`: 固定3位小数
|
|
|
+- `formatAmount()`: 基于币种精度的动态小数位
|
|
|
+
|
|
|
+## 5. 建议改进方案
|
|
|
+
|
|
|
+### 5.1 统一精度配置
|
|
|
+1. 为所有币种配置明确的 `precision` 值
|
|
|
+2. 金币建议精度0(整数)
|
|
|
+3. 钻石建议精度0(整数)
|
|
|
+4. 法币(CNY/USD)建议精度2(分)
|
|
|
+
|
|
|
+### 5.2 统一处理接口
|
|
|
+1. 废弃固定1000倍数的处理方式
|
|
|
+2. 全面使用基于币种精度的动态处理
|
|
|
+3. 建立统一的金额转换服务类
|
|
|
+
|
|
|
+### 5.3 规范显示格式
|
|
|
+1. 后台显示统一使用币种精度
|
|
|
+2. 前端显示根据业务需求选择格式
|
|
|
+3. 建立统一的格式化助手方法
|
|
|
+
|
|
|
+## 6. 当前状态总结
|
|
|
+
|
|
|
+Fund模块的小数处理目前处于**过渡状态**:
|
|
|
+- ✅ 已建立基于币种精度的动态处理框架
|
|
|
+- ⚠️ 仍保留历史的1000倍数处理方式
|
|
|
+- ❌ 币种精度配置不完整
|
|
|
+- ❌ 处理方式不统一
|
|
|
+
|
|
|
+建议优先完善币种精度配置,然后逐步统一处理方式,最终废弃历史遗留的固定倍数处理。
|