# API 文档:时区国际化功能 ## 元数据 - 需求编号:2026-01-21-002-04 - 创建时间:2026-01-25 - 创建人:SSOT 架构师 - 父需求:2026-01-21-002-项目国际化需求 ## API 概述 时区国际化功能 API 提供了时区管理、时区切换、时区查询等功能,支持用户设置时区偏好、切换时区、查询当前时区和系统默认时区。API 遵循 RESTful 规范,使用标准的 HTTP 方法(GET、POST、PUT、DELETE)进行数据交互。 ## 接口列表 ### 接口 1:获取当前用户时区 #### 功能描述 获取当前用户的时区偏好,包括时区 ID、时区名称、时区偏移量等信息。 #### 请求方式 GET #### 请求路径 `/system/timezone/current` #### 权限要求 - 无(需要登录) #### 请求参数 无 #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | | data | String | 时区 ID(例如:Asia/Shanghai) | #### 成功示例 ```json { "code": 200, "msg": "操作成功", "data": "Asia/Shanghai" } ``` #### 失败示例 ```json { "code": 401, "msg": "未登录或登录已过期" } ``` --- ### 接口 2:切换用户时区 #### 功能描述 切换当前用户的时区偏好,并清除相关缓存。切换操作会被记录到审计日志中。 #### 请求方式 POST #### 请求路径 `/system/timezone/switch` #### 权限要求 - 无(需要登录) #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | timeZone | String | 是 | 时区 ID(例如:Asia/Shanghai、America/New_York) | #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | #### 成功示例 ```json { "code": 200, "msg": "时区切换成功" } ``` #### 失败示例 ```json { "code": 401, "msg": "未登录或登录已过期" } ``` ```json { "code": 500, "msg": "未找到用户信息" } ``` --- ### 接口 3:获取系统默认时区 #### 功能描述 获取系统默认时区配置。系统默认时区是所有用户的默认时区,当用户未设置时区偏好时使用。 #### 请求方式 GET #### 请求路径 `/system/timezone/default` #### 权限要求 - `system:timezone:query` - 时区查询权限 #### 请求参数 无 #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | | data | String | 时区 ID(例如:Asia/Shanghai) | #### 成功示例 ```json { "code": 200, "msg": "操作成功", "data": "Asia/Shanghai" } ``` #### 失败示例 ```json { "code": 403, "msg": "没有权限访问" } ``` --- ### 接口 4:查询时区列表 #### 功能描述 查询时区列表,支持分页查询和条件过滤。 #### 请求方式 GET #### 请求路径 `/system/timezone/list` #### 权限要求 - `system:timezone:list` - 时区列表查询权限 #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | pageNum | Integer | 否 | 页码(默认 1) | | pageSize | Integer | 否 | 每页条数(默认 10) | | timezoneId | String | 否 | 时区 ID | | timezoneName | String | 否 | 时区名称(模糊查询) | | isActive | String | 否 | 是否激活(0 否,1 是) | | isDefault | String | 否 | 是否默认(0 否,1 是) | #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | | rows | Array | 时区列表 | | rows[].timezoneId | String | 时区 ID | | rows[].timezoneName | String | 时区名称 | | rows[].timezoneOffset | String | 时区偏移量 | | rows[].isActive | String | 是否激活(0 否,1 是) | | rows[].isDefault | String | 是否默认(0 否,1 是) | | rows[].createTime | String | 创建时间 | | rows[].updateTime | String | 更新时间 | | rows[].remark | String | 备注 | | total | Integer | 总记录数 | #### 成功示例 ```json { "code": 200, "msg": "查询成功", "rows": [ { "timezoneId": "Asia/Shanghai", "timezoneName": "上海", "timezoneOffset": "UTC+8", "isActive": "1", "isDefault": "1", "createTime": "2026-01-25 10:00:00", "updateTime": "2026-01-25 10:00:00", "remark": "中国标准时间" }, { "timezoneId": "America/New_York", "timezoneName": "纽约", "timezoneOffset": "UTC-5", "isActive": "1", "isDefault": "0", "createTime": "2026-01-25 10:00:00", "updateTime": "2026-01-25 10:00:00", "remark": "美国东部时间" } ], "total": 2 } ``` #### 失败示例 ```json { "code": 403, "msg": "没有权限访问" } ``` --- ### 接口 5:获取时区详情 #### 功能描述 根据时区 ID 获取时区详细信息。 #### 请求方式 GET #### 请求路径 `/system/timezone/{timezoneId}` #### 权限要求 - `system:timezone:query` - 时区查询权限 #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | timezoneId | String | 是 | 时区 ID(路径参数) | #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | | data | Object | 时区详情 | | data.timezoneId | String | 时区 ID | | data.timezoneName | String | 时区名称 | | data.timezoneOffset | String | 时区偏移量 | | data.isActive | String | 是否激活(0 否,1 是) | | data.isDefault | String | 是否默认(0 否,1 是) | | data.createBy | String | 创建者 | | data.createTime | String | 创建时间 | | data.updateBy | String | 更新者 | | data.updateTime | String | 更新时间 | | data.remark | String | 备注 | #### 成功示例 ```json { "code": 200, "msg": "查询成功", "data": { "timezoneId": "Asia/Shanghai", "timezoneName": "上海", "timezoneOffset": "UTC+8", "isActive": "1", "isDefault": "1", "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": "时区不存在" } ``` --- ### 接口 6:新增时区 #### 功能描述 新增时区配置。新增操作会被记录到审计日志中。 #### 请求方式 POST #### 请求路径 `/system/timezone` #### 权限要求 - `system:timezone:add` - 时区新增权限 #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | timezoneId | String | 是 | 时区 ID | | timezoneName | String | 是 | 时区名称 | | timezoneOffset | String | 是 | 时区偏移量 | | isActive | String | 否 | 是否激活(默认 1) | | isDefault | String | 否 | 是否默认(默认 0) | | remark | String | 否 | 备注 | #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | #### 成功示例 ```json { "code": 200, "msg": "新增成功" } ``` #### 失败示例 ```json { "code": 403, "msg": "没有权限访问" } ``` ```json { "code": 500, "msg": "时区 ID 已存在" } ``` --- ### 接口 7:修改时区 #### 功能描述 修改时区配置。修改操作会被记录到审计日志中。 #### 请求方式 PUT #### 请求路径 `/system/timezone` #### 权限要求 - `system:timezone:edit` - 时区修改权限 #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | timezoneId | String | 是 | 时区 ID | | timezoneName | String | 否 | 时区名称 | | timezoneOffset | String | 否 | 时区偏移量 | | isActive | String | 否 | 是否激活(0 否,1 是) | | isDefault | String | 否 | 是否默认(0 否,1 是) | | remark | String | 否 | 备注 | #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | #### 成功示例 ```json { "code": 200, "msg": "修改成功" } ``` #### 失败示例 ```json { "code": 403, "msg": "没有权限访问" } ``` ```json { "code": 500, "msg": "时区不存在" } ``` --- ### 接口 8:删除时区 #### 功能描述 删除时区配置。删除操作会被记录到审计日志中。 #### 请求方式 DELETE #### 请求路径 `/system/timezone/{timezoneIds}` #### 权限要求 - `system:timezone:remove` - 时区删除权限 #### 请求参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | timezoneIds | String | 是 | 时区 ID 列表(多个 ID 用逗号分隔,路径参数) | #### 响应参数 | 参数名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200 成功,其他失败) | | msg | String | 提示信息 | #### 成功示例 ```json { "code": 200, "msg": "删除成功" } ``` #### 失败示例 ```json { "code": 403, "msg": "没有权限访问" } ``` ```json { "code": 500, "msg": "时区不存在" } ``` --- ## 时区转换注解使用说明 ### @TimeZoneConvert 注解 #### 功能描述 在 Service 方法上添加 `@TimeZoneConvert` 注解,AOP 切面会自动拦截该方法返回值,并将所有 `LocalDateTime` 字段从 UTC 转换为当前用户的时区。 #### 使用示例 ```java @Service public class OrderServiceImpl implements IOrderService { @TimeZoneConvert public Order getOrderById(Long orderId) { Order order = orderMapper.selectOrderById(orderId); return order; } @TimeZoneConvert public List getOrderList(OrderQuery query) { List list = orderMapper.selectOrderList(query); return list; } } ``` #### 注意事项 1. 该注解仅适用于 Service 层方法 2. 该注解会递归转换对象中的所有 `LocalDateTime` 字段 3. 如果时区无效,会使用系统默认时区进行转换 4. 该注解不会修改原始对象,而是返回转换后的对象 --- ## 错误码说明 | 错误码 | 说明 | |--------|------| | 200 | 操作成功 | | 401 | 未登录或登录已过期 | | 403 | 没有权限访问 | | 404 | 资源不存在 | | 500 | 服务器内部错误 | --- ## 相关文档 - [需求文档](../requirements/2026-01-21-002-04-时区国际化需求.md) - [设计文档](../design/2026-01-21-002-04-时区国际化设计.md) - [决策记录](../decisions/adr/2026-01-25-002-04-ADR-时区国际化技术选型.md) - [变更日志](../changelog/2026-01-25-002-04-changelog.md) - [复盘文档](../retros/2026-01-25-002-04-retro.md)