datai/datai-scenes/datai-scene-salesforce/docs/api-docs/2026-01-25-002-05-api.md
Kris 238764c694 feat: 实现货币格式化功能
- 新增货币格式化工具类 CurrencyUtils,支持多种货币格式化
- 新增 @CurrencyFormat 注解和 CurrencyFormatAspect AOP 切面,实现自动货币格式化
- 新增汇率管理功能,包括汇率查询、转换、更新等接口
- 新增用户货币偏好设置功能,支持用户切换货币
- 扩展 SysUser 表,添加 currency_code 字段
- 扩展 CacheConstants,添加货币相关缓存常量
- 新增 CurrencyConstants,定义货币相关常量
- 完善文档:需求文档、设计文档、ADR、提示词文档、会话记录、变更日志、复盘文档、API 文档
- 更新文档索引

需求编号:2026-01-21-002-05
父需求:2026-01-21-002-项目国际化需求
2026-01-25 21:47:26 +08:00

693 lines
13 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.

# API 文档:货币格式化功能
## 元数据
- 需求编号2026-01-21-002-05
- 创建时间2026-01-25
- 创建人SSOT 架构师
- 父需求2026-01-21-002-项目国际化需求
## API 概述
货币格式化功能 API 提供了货币管理、汇率转换、货币偏好设置等功能支持用户设置货币偏好、切换货币、查询汇率、进行汇率转换等操作。API 遵循 RESTful 规范,使用标准的 HTTP 方法GET、POST、PUT、DELETE进行数据交互。
## 接口列表
### 接口 1获取用户货币偏好
#### 功能描述
获取当前用户的货币偏好,包括货币代码、货币符号、货币名称等信息。
#### 请求方式
GET
#### 请求路径
`/system/user/currency`
#### 权限要求
- 无(需要登录)
#### 请求参数
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | String | 货币代码例如CNY、USD、EUR |
#### 成功示例
```json
{
"code": 200,
"msg": "操作成功",
"data": "CNY"
}
```
#### 失败示例
```json
{
"code": 401,
"msg": "未登录或登录已过期"
}
```
---
### 接口 2切换用户货币偏好
#### 功能描述
切换当前用户的货币偏好,并清除相关缓存。切换操作会被记录到审计日志中。
#### 请求方式
POST
#### 请求路径
`/system/user/switchCurrency`
#### 权限要求
- 无(需要登录)
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| currencyCode | String | 是 | 货币代码例如CNY、USD、EUR |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
#### 成功示例
```json
{
"code": 200,
"msg": "货币切换成功"
}
```
#### 失败示例
```json
{
"code": 401,
"msg": "未登录或登录已过期"
}
```
```json
{
"code": 500,
"msg": "未找到用户信息"
}
```
---
### 接口 3汇率转换
#### 功能描述
将指定金额从源货币转换为目标货币。汇率数据会从缓存或数据库中获取。
#### 请求方式
POST
#### 请求路径
`/system/exchangeRate/convert`
#### 权限要求
- `system:exchangeRate:convert` - 汇率转换权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| amount | BigDecimal | 是 | 转换金额 |
| fromCurrency | String | 是 | 源货币代码例如USD |
| toCurrency | String | 是 | 目标货币代码例如CNY |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | BigDecimal | 转换后的金额 |
#### 成功示例
```json
{
"code": 200,
"msg": "转换成功",
"data": 723.50
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "汇率数据不存在"
}
```
---
### 接口 4批量汇率转换
#### 功能描述
批量将多个金额从源货币转换为目标货币。汇率数据会从缓存或数据库中获取。
#### 请求方式
POST
#### 请求路径
`/system/exchangeRate/batchConvert`
#### 权限要求
- `system:exchangeRate:convert` - 汇率转换权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| amounts | List<BigDecimal> | 是 | 转换金额列表 |
| fromCurrency | String | 是 | 源货币代码例如USD |
| toCurrency | String | 是 | 目标货币代码例如CNY |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | List<BigDecimal> | 转换后的金额列表 |
#### 成功示例
```json
{
"code": 200,
"msg": "转换成功",
"data": [723.50, 1447.00, 2170.50]
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "汇率数据不存在"
}
```
---
### 接口 5更新汇率手动
#### 功能描述
手动更新汇率数据。更新操作会被记录到审计日志中。
#### 请求方式
POST
#### 请求路径
`/system/exchangeRate/update`
#### 权限要求
- `system:exchangeRate:edit` - 汇率编辑权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| fromCurrency | String | 是 | 源货币代码例如USD |
| toCurrency | String | 是 | 目标货币代码例如CNY |
| rate | BigDecimal | 是 | 汇率1 源货币 = rate 目标货币) |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
#### 成功示例
```json
{
"code": 200,
"msg": "汇率更新成功"
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "汇率不存在"
}
```
---
### 接口 6更新汇率API
#### 功能描述
从外部 API 获取最新汇率数据并更新到数据库。更新操作会被记录到审计日志中。
#### 请求方式
POST
#### 请求路径
`/system/exchangeRate/updateFromApi`
#### 权限要求
- `system:exchangeRate:edit` - 汇率编辑权限
#### 请求参数
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Integer | 更新的汇率数量 |
#### 成功示例
```json
{
"code": 200,
"msg": "汇率更新成功",
"data": 10
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "外部 API 调用失败"
}
```
---
### 接口 7查询汇率列表
#### 功能描述
查询汇率列表,支持分页查询和条件过滤。
#### 请求方式
GET
#### 请求路径
`/system/exchangeRate/list`
#### 权限要求
- `system:exchangeRate:list` - 汇率列表查询权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| pageNum | Integer | 否 | 页码(默认 1 |
| pageSize | Integer | 否 | 每页条数(默认 10 |
| fromCurrency | String | 否 | 源货币代码 |
| toCurrency | String | 否 | 目标货币代码 |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| rows | Array | 汇率列表 |
| rows[].id | Long | 汇率 ID |
| rows[].fromCurrency | String | 源货币代码 |
| rows[].toCurrency | String | 目标货币代码 |
| rows[].rate | BigDecimal | 汇率 |
| rows[].updateTime | String | 更新时间 |
| rows[].remark | String | 备注 |
| total | Integer | 总记录数 |
#### 成功示例
```json
{
"code": 200,
"msg": "查询成功",
"rows": [
{
"id": 1,
"fromCurrency": "USD",
"toCurrency": "CNY",
"rate": 7.2350,
"updateTime": "2026-01-25 10:00:00",
"remark": "美元兑人民币"
},
{
"id": 2,
"fromCurrency": "EUR",
"toCurrency": "CNY",
"rate": 7.8560,
"updateTime": "2026-01-25 10:00:00",
"remark": "欧元兑人民币"
}
],
"total": 2
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
---
### 接口 8获取汇率详情
#### 功能描述
根据汇率 ID 获取汇率详细信息。
#### 请求方式
GET
#### 请求路径
`/system/exchangeRate/{id}`
#### 权限要求
- `system:exchangeRate:query` - 汇率查询权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 汇率 ID路径参数 |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
| data | Object | 汇率详情 |
| data.id | Long | 汇率 ID |
| data.fromCurrency | String | 源货币代码 |
| data.toCurrency | String | 目标货币代码 |
| data.rate | BigDecimal | 汇率 |
| data.createBy | String | 创建者 |
| data.createTime | String | 创建时间 |
| data.updateBy | String | 更新者 |
| data.updateTime | String | 更新时间 |
| data.remark | String | 备注 |
#### 成功示例
```json
{
"code": 200,
"msg": "查询成功",
"data": {
"id": 1,
"fromCurrency": "USD",
"toCurrency": "CNY",
"rate": 7.2350,
"createBy": "admin",
"createTime": "2026-01-25 10:00:00",
"updateBy": "admin",
"updateTime": "2026-01-25 10:00:00",
"remark": "美元兑人民币"
}
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 404,
"msg": "汇率不存在"
}
```
---
### 接口 9新增汇率
#### 功能描述
新增汇率配置。新增操作会被记录到审计日志中。
#### 请求方式
POST
#### 请求路径
`/system/exchangeRate`
#### 权限要求
- `system:exchangeRate:add` - 汇率新增权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| fromCurrency | String | 是 | 源货币代码 |
| toCurrency | String | 是 | 目标货币代码 |
| rate | BigDecimal | 是 | 汇率 |
| remark | String | 否 | 备注 |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
#### 成功示例
```json
{
"code": 200,
"msg": "新增成功"
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "汇率已存在"
}
```
---
### 接口 10修改汇率
#### 功能描述
修改汇率配置。修改操作会被记录到审计日志中。
#### 请求方式
PUT
#### 请求路径
`/system/exchangeRate`
#### 权限要求
- `system:exchangeRate:edit` - 汇率修改权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| id | Long | 是 | 汇率 ID |
| fromCurrency | String | 否 | 源货币代码 |
| toCurrency | String | 否 | 目标货币代码 |
| rate | BigDecimal | 否 | 汇率 |
| remark | String | 否 | 备注 |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
#### 成功示例
```json
{
"code": 200,
"msg": "修改成功"
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "汇率不存在"
}
```
---
### 接口 11删除汇率
#### 功能描述
删除汇率配置。删除操作会被记录到审计日志中。
#### 请求方式
DELETE
#### 请求路径
`/system/exchangeRate/{ids}`
#### 权限要求
- `system:exchangeRate:remove` - 汇率删除权限
#### 请求参数
| 参数名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ids | String | 是 | 汇率 ID 列表(多个 ID 用逗号分隔,路径参数) |
#### 响应参数
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功,其他失败) |
| msg | String | 提示信息 |
#### 成功示例
```json
{
"code": 200,
"msg": "删除成功"
}
```
#### 失败示例
```json
{
"code": 403,
"msg": "没有权限访问"
}
```
```json
{
"code": 500,
"msg": "汇率不存在"
}
```
---
## 货币格式化注解使用说明
### @CurrencyFormat 注解
#### 功能描述
在 Service 方法上添加 `@CurrencyFormat` 注解AOP 切面会自动拦截该方法返回值,并将所有 `BigDecimal` 字段根据用户货币偏好进行格式化。
#### 使用示例
```java
@Service
public class OrderServiceImpl implements IOrderService {
@CurrencyFormat
public Order getOrderById(Long orderId) {
Order order = orderMapper.selectOrderById(orderId);
return order;
}
@CurrencyFormat
public List<Order> getOrderList(OrderQuery query) {
List<Order> list = orderMapper.selectOrderList(query);
return list;
}
}
```
#### 注意事项
1. 该注解仅适用于 Service 层方法
2. 该注解会递归格式化对象中的所有 `BigDecimal` 字段
3. 如果用户未设置货币偏好,会使用系统默认货币进行格式化
4. 该注解不会修改原始对象,而是返回格式化后的对象
5. 支持多货币格式化,可以在单个字段中显示多种货币
---
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 操作成功 |
| 401 | 未登录或登录已过期 |
| 403 | 没有权限访问 |
| 404 | 资源不存在 |
| 500 | 服务器内部错误 |
---
## 相关文档
- [需求文档](../requirements/2026-01-21-002-05-货币格式化需求.md)
- [设计文档](../design/2026-01-21-002-05-货币格式化设计.md)
- [决策记录](../decisions/adr/2026-01-25-002-05-ADR-货币格式化技术选型.md)
- [变更日志](../changelog/2026-01-25-002-05-currency-formatting.md)
- [复盘文档](../retros/2026-01-25-002-05-retro.md)