datai/docs/archive/sessions/2026-01-25-002-05-session.md

265 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 会话记录:货币格式化功能
## 元数据
- 需求编号2026-01-21-002-05
- 创建时间2026-01-25
- 创建人SSOT 架构师
- 状态:进行中
- 父需求2026-01-21-002-项目国际化需求
## 执行阶段
### 阶段 1需求定义
- **状态**:已完成
- **生成文档**[需求文档](../requirements/2026-01-21-002-05-货币格式化需求.md)
- **关键决策**
- 扩展 sys_user 表,添加 currency_code 字段
- 支持用户级别的货币偏好覆盖系统默认设置
- 在配置文件中设置系统默认货币
- 在后端返回数据时进行格式化,通过 AOP 在 Service 层统一处理
- 需要支持多货币显示
- 需要实时汇率转换
- 后端使用 java.text.DecimalFormat
- 不考虑性能、安全性等问题
### 阶段 2方案设计
- **状态**:已完成
- **生成文档**[设计文档](../design/2026-01-21-002-05-货币格式化设计.md)
- **关键设计决策**
- 使用 Java DecimalFormat 进行货币格式化
- 使用 Redis 缓存汇率数据,提高性能
- 货币格式化在 Service 层进行,使用 AOP 切面拦截响应
- 货币优先级:用户 > 系统
- 汇率数据存储在数据库中,支持手动更新和 API 自动更新
- 所有金额字段使用 BigDecimal 类型
- 缓存策略汇率缓存TTL = 60 分钟、货币列表缓存TTL = 24 小时、默认货币缓存TTL = 24 小时)
### 阶段 3方案决策
- **状态**:已完成
- **生成文档**[决策记录](../decisions/adr/2026-01-25-002-05-ADR-货币格式化技术选型.md)
- **关键决策**
- **决策 1货币格式化技术选择** - Java DecimalFormat
- 理由Java 内置、无需额外依赖、功能完整、性能优秀、成熟稳定、与框架兼容
- 放弃方案Joda-Money 库(需要额外依赖)、自定义格式化实现(维护成本高)
- **决策 2缓存策略选择** - Redis 缓存
- 理由:已集成、性能优秀、分布式支持、自动过期、数据结构丰富、支持持久化
- 缓存策略汇率缓存TTL = 60 分钟、货币列表缓存TTL = 24 小时、默认货币缓存TTL = 24 小时)
- 放弃方案Caffeine 本地缓存(无法在分布式环境下共享)、数据库缓存(性能较差、无法自动过期)
- **决策 3货币格式化层选择** - Service 层格式化 + AOP 切面拦截
- 理由统一处理、AOP 切面自动格式化、业务逻辑分离、易于维护、性能优化
- 实现方案:使用 @Around 切面拦截 Service 方法返回值,提供 @CurrencyFormat 注解
- 放弃方案Controller 层格式化(职责过重、代码重复)、数据库层格式化(违反分层架构、兼容性差)
- **决策 4货币优先级策略选择** - 双级优先级策略(用户 > 系统)
- 理由:灵活性高、用户体验好、系统默认、易于扩展
- 优先级规则:用户货币 > 系统货币 > 硬编码默认CNY
- 放弃方案:单级优先级(仅用户货币/仅系统货币)- 灵活性不足
### 阶段 4数据库结构
- **状态**:已完成
- **生成文档**[SQL 脚本](../sql/2026-01-25-002-05-货币格式化.sql)
- **数据库变更**
- **创建新表**sys_exchange_rate汇率表
- 字段id、from_currency、to_currency、rate、source、create_by、create_time、update_by、update_time、remark
- 索引主键索引id、唯一索引from_currency, to_currency、普通索引source
- **修改现有表**sys_user用户表
- 新增字段currency_code货币代码默认值为 CNY
- 新增索引idx_currency_codecurrency_code 字段)
- **插入初始数据**
- 插入常用货币配置CNY、USD、EUR、GBP、JPY
### 阶段 5提示词生成
- **状态**:已完成
- **生成文档**[提示词文档](../prompts/2026-01-25-002-05-prompt-货币格式化功能.md)
- **提示词内容摘要**
- **引用真源**需求文档、设计文档、决策记录、SQL 脚本
- **需求描述**:货币格式化功能、汇率管理功能、货币优先级策略、缓存管理、自动货币格式化
- **设计方案**Java DecimalFormat、Redis、MySQL 8.3.0、Spring Boot 3.5.7 + 若依框架、分层架构
- **输出格式要求**
- Entity 层SysExchangeRate.java
- 修改现有文件SysUser.java添加 currency_code 字段)
- Utils 层CurrencyUtils.java
- 注解:@CurrencyFormat.java
- Aspect 层CurrencyFormatAspect.java拦截 Service 方法返回值)
- Mapper 层SysExchangeRateMapper.java、SysExchangeRateMapper.xml
- Service 层ISysExchangeRateService.java、SysExchangeRateServiceImpl.java
- Controller 层SysExchangeRateController.java
- 单元测试CurrencyUtilsTest.java、SysExchangeRateServiceTest.java
- **代码规范要求**:命名规范、注释规范、代码格式、导入规范
- **测试要求**:单元测试覆盖率 ≥ 80%、测试用例场景、测试框架、测试用例命名规范、测试数据
- **注意事项**货币格式化、缓存、权限控制、日志记录、异常处理、性能优化、安全、AOP 切面
### 阶段 6代码生成
- **状态**:已完成
- **生成文档**[代码文档](../reference-code/2026-01-25-002-05-code-货币格式化功能.md)、[实施方案](../implementation/2026-01-25-002-05-implementation-货币格式化功能.md)
- **代码生成情况**
- **代码生成器生成**
- SysExchangeRate.java实体类
- SysExchangeRateMapper.javaMapper 接口)
- SysExchangeRateMapper.xmlMapper XML
- SysExchangeRateService.javaService 接口基础方法)
- SysExchangeRateServiceImpl.javaService 实现类基础方法)
- SysExchangeRateController.javaController 类基础接口)
- **手动生成/扩展**
- ISysExchangeRateService.java扩展方法getExchangeRate、convert、batchConvert、updateExchangeRate、updateExchangeRateFromApi、getAvailableCurrencies、getDefaultCurrency
- SysExchangeRateServiceImpl.java实现扩展方法包含 Redis 缓存逻辑
- CurrencyUtils.java货币格式化工具类format、convert、isValidCurrencyCode、getPattern、getSymbol
- CurrencyConstants.java货币常量类货币代码、货币符号、货币格式化模式
- @CurrencyFormat.java货币格式化注解
- CurrencyFormatAspect.java货币格式化切面拦截 Service 方法返回值)
- SysUser.java添加 currency_code 字段
- SysUserController.java添加用户货币偏好管理接口
- SysExchangeRateDto.java添加汇率转换相关字段
- CacheConstants.java添加汇率相关缓存常量
- **关键实现**
- 使用 AOP 切面拦截 Service 方法返回值进行货币格式化
- Redis 缓存策略:汇率缓存 60 分钟,货币列表缓存 24 小时,默认货币缓存 24 小时
- 递归格式化复杂对象中的 BigDecimal 字段
- 支持多货币显示,自动转换并显示多种货币
- 异常处理无效货币使用默认货币null 值安全处理
- **修复的问题**
- CurrencyFormatAspect.java 中的 SYS_CONFIG 常量引用错误(修改为 SYS_CONFIG_KEY
- **补充的接口**
- GET /system/user/currency获取当前用户货币偏好
- POST /system/user/switchCurrency切换用户货币偏好已添加 @Log 注解记录审计日志)
- POST /system/exchangeRate/convert汇率转换
- POST /system/exchangeRate/batchConvert批量汇率转换
- POST /system/exchangeRate/update更新汇率手动
- POST /system/exchangeRate/updateFromApi更新汇率API
- **需求实现情况**
- ✅ 功能 1货币符号支持 - 已实现
- ✅ 功能 2小数格式化 - 已实现
- ✅ 功能 3千分位分隔符 - 已实现(逗号分隔符)
- ⚠️ 功能 4自动格式选择 - 已实现(部分)
- ⚠️ 功能 5自定义格式 - 已实现(部分)
- ✅ 功能 6多货币显示 - 已实现
- ✅ 功能 7AOP 自动格式化 - 已实现
- ✅ 功能 8用户货币偏好 - 已实现
- ✅ 功能 9系统默认货币 - 已实现
- ✅ 功能 10汇率管理 - 已实现
- ✅ 功能 11汇率转换 - 已实现
- ✅ 功能 12汇率缓存 - 已实现
- ⚠️ 功能 13货币优先级 - 已实现(部分,缺少租户货币支持)
- **未实现的需求**
- 空格分隔符支持(功能 3 的部分需求)
- 自定义千分位分隔符(功能 5 的部分需求)
- 自定义货币符号(功能 5 的部分需求)
- 租户货币支持(功能 13 的部分需求)
- 单元测试
- 性能测试
### 阶段 7会话记录
- **状态**:已完成
- **生成文档**当前文档2026-01-25-002-05-session.md
- **更新内容**
- 更新阶段 6 的代码生成情况
- 记录补充的接口信息
- 记录需求实现情况
- 记录未实现的需求
### 阶段 8变更日志
- **状态**:待开始
- **生成文档**:待生成
### 阶段 9复盘与接口
- **状态**:待开始
- **生成文档**:待生成
### 阶段 10代码提交
- **状态**:待开始
- **生成文档**:待生成
## 关键设计决策
### 技术选型
1. **货币格式化技术**Java DecimalFormat
- 理由Java 内置,无需引入额外依赖;支持自定义格式化模式;性能优秀,格式化时间 < 10ms成熟稳定社区支持良好
2. **缓存技术**Redis
- 理由项目已集成 Redis无需额外配置性能优秀响应时间 < 1ms支持分布式部署支持自动过期机制丰富的数据结构支持
3. **数据库技术**MySQL 8.3.0
- 理由项目现有数据库支持 BigDecimal 类型性能优秀支持高并发事务支持完善
4. **框架技术**Spring Boot 3.5.7 + 若依框架
- 理由项目现有框架Spring Boot 3.5.7 支持 Java 21若依框架提供完善的权限缓存日志等功能社区活跃文档完善
### 架构设计
1. **系统架构**前端层Vue 3)→ Controller Service Mapper 数据库层MySQL 8.3.0)→ 缓存层Redis
2. **模块架构**
- datai-admin启动模块Controller
- datai-system系统模块Service Mapper 实体类
- datai-common公共模块工具类切面常量
- datai-plugins插件模块Redis 缓存工具类
### 数据流设计
1. **用户登录流程**用户输入用户名密码 Controller 接收登录请求 Service 验证用户信息 从数据库读取用户货币偏好 Redis 缓存读取货币配置 将用户货币信息存储到 LoginUser 生成 Token 并返回 前端存储 Token 和货币信息
2. **数据查询流程**前端发起数据查询请求 Controller 接收请求 Service 层从数据库读取金额数据 AOP 切面拦截响应 根据用户货币格式化金额 返回格式化后的金额 前端显示格式化后的金额
3. **汇率转换流程**前端发起汇率转换请求 Controller 接收请求 Service 层从 Redis 缓存读取汇率 如果缓存未命中从数据库读取汇率 返回转换后的金额 前端显示转换后的金额
4. **货币切换流程**用户选择新货币 Controller 接收货币切换请求 Service 验证货币代码有效性 更新用户货币偏好到数据库 清除 Redis 缓存 刷新 Token 前端刷新页面重新加载金额数据
### 数据模型设计
1. **汇率表sys_exchange_rate**
- 字段idfrom_currencyto_currencyratesourcecreate_bycreate_timeupdate_byupdate_timeremark
- 索引主键索引id)、唯一索引from_currency, to_currency)、普通索引source
2. **用户表修改sys_user**
- 新增字段currency_code货币代码
- 默认值CNY人民币
- 位置 lang_code 字段之后
### 接口设计
1. **获取汇率列表**GET /system/exchangeRate/list
- 权限要求@PreAuthorize("@ss.hasPermi('system:exchangeRate:list')")
- 响应数据汇率列表包含 idfromCurrencytoCurrencyratesource
2. **获取当前用户货币偏好**GET /system/user/currency
- 权限要求需要登录
- 响应数据货币代码CNY
3. **切换货币偏好**POST /system/user/switchCurrency
- 权限要求需要登录
- 请求参数currencyCode货币代码
- 响应数据成功/失败消息
4. **汇率转换**POST /system/exchangeRate/convert
- 权限要求需要登录
- 请求参数amount金额)、fromCurrency源货币)、toCurrency目标货币
- 响应数据转换后的金额
5. **批量汇率转换**POST /system/exchangeRate/batchConvert
- 权限要求需要登录
- 请求参数amounts金额列表)、fromCurrency源货币)、toCurrency目标货币
- 响应数据转换后的金额列表
6. **更新汇率(手动)**POST /system/exchangeRate/update
- 权限要求@PreAuthorize("@ss.hasPermi('system:exchangeRate:edit')")
- 请求参数fromCurrency源货币)、toCurrency目标货币)、rate汇率
- 响应数据成功/失败消息
7. **更新汇率API**POST /system/exchangeRate/updateFromApi
- 权限要求@PreAuthorize("@ss.hasPermi('system:exchangeRate:edit')")
- 响应数据成功更新的汇率数量
### 实现要点
1. **关键实现逻辑**
- 货币格式化在 Service 层进行使用 AOP 切面拦截响应
- 使用 CurrencyUtils 工具类进行货币格式化和转换
- 处理 null 避免空指针异常
- 处理无效货币代码使用默认货币
- 支持多货币显示自动转换并显示多种货币
2. **异常处理设计**
- 货币格式化异常捕获异常记录日志返回原始金额提示用户货币格式化失败
- 货币代码无效异常捕获异常记录日志返回错误响应提示用户货币代码无效
- 缓存读取异常捕获异常记录日志从数据库重新加载数据提示用户缓存读取失败
- 汇率转换异常捕获异常记录日志返回原始金额提示用户汇率转换失败
3. **性能优化设计**
- 缓存优化使用 Redis 缓存汇率数据汇率缓存 60 分钟货币列表缓存 24 小时默认货币缓存 24 小时
- 索引优化为常用查询字段创建索引提高查询性能
- 批量转换优化批量转换时使用并行处理合理设置线程池大小
4. **安全设计**
- 数据验证验证货币代码有效性格式白名单
- 权限控制使用 @PreAuthorize 注解控制接口权限使用数据权限控制数据访问范围
- 审计日志使用 @Log 注解记录操作日志记录操作人操作时间操作内容
## 相关文档
- [需求文档](../requirements/2026-01-21-002-05-货币格式化需求.md)
- [设计文档](../design/2026-01-21-002-05-货币格式化设计.md)
- [决策记录](../decisions/adr/2026-01-25-002-05-ADR-货币格式化技术选型.md)
- [SQL 脚本](../sql/2026-01-25-002-05-货币格式化.sql)
- [提示词文档](../prompts/2026-01-25-002-05-prompt-货币格式化功能.md)
- [代码文档](../reference-code/2026-01-25-002-05-code-货币格式化功能.md)
- [实施方案](../implementation/2026-01-25-002-05-implementation-货币格式化功能.md)