datai/docs/archive/api-docs/system/2026-01-21-002-04-api-时区国际化.md

718 lines
19 KiB
Markdown
Raw Permalink 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-04
- **创建时间**2026-01-26
- **创建人**SSOT 架构师
- **父需求**2026-01-21-002-项目国际化需求
## API 概述
时区国际化接口提供了时区设置、时区切换、时区查询等功能。支持用户设置时区偏好,根据用户时区显示时间,支持常用时区。所有时间字段存储为 UTC 时间,在 Service 层进行时区转换,使用 Redis 缓存时区配置,时区切换后立即刷新页面重新加载时间数据。
## 接口列表
---
### 接口 1获取时区列表
#### 功能描述
获取系统支持的时区列表时区列表固定存储在数据库中支持缓存。返回所有可用的时区信息包括时区ID、时区名称、时区偏移等。
#### 请求方式
GET
#### 请求路径
`/system/timezone/list`
#### 权限要求
- 无(通常公开或需登录)
#### 请求参数
| 参数名 | 类型 | 必选 | 说明 |
|--------|------|------|------|
| status | String | 否 | 状态0正常 1停用 |
| isDefault | String | 否 | 是否默认时区0否 1是 |
#### 请求示例
```bash
curl -X GET 'http://localhost:8080/system/timezone/list?status=0' \
-H 'Authorization: Bearer {token}'
```
#### 响应数据结构
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功500 失败) |
| msg | String | 提示信息 |
| data | Array | 时区列表 |
| data[].id | Long | 时区ID |
| data[].timezoneId | String | 时区ID如 Asia/Shanghai |
| data[].timezoneName | String | 时区名称(如 中国标准时间) |
| data[].timezoneOffset | String | 时区偏移(如 UTC+8 |
| data[].isDefault | Boolean | 是否默认时区 |
| data[].sortOrder | Integer | 排序 |
| data[].status | String | 状态0正常 1停用 |
| data[].remark | String | 备注 |
#### 响应示例
**成功响应:**
```json
{
"code": 200,
"msg": "操作成功",
"data": [
{
"id": 1,
"timezoneId": "UTC",
"timezoneName": "协调世界时",
"timezoneOffset": "UTC+0",
"isDefault": false,
"sortOrder": 1,
"status": "0",
"remark": "协调世界时"
},
{
"id": 2,
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": true,
"sortOrder": 2,
"status": "0",
"remark": "中国标准时间"
},
{
"id": 3,
"timezoneId": "America/New_York",
"timezoneName": "美国东部时间",
"timezoneOffset": "UTC-5",
"isDefault": false,
"sortOrder": 3,
"status": "0",
"remark": "美国东部时间(夏令时 UTC-4"
},
{
"id": 4,
"timezoneId": "America/Los_Angeles",
"timezoneName": "美国太平洋时间",
"timezoneOffset": "UTC-8",
"isDefault": false,
"sortOrder": 4,
"status": "0",
"remark": "美国太平洋时间(夏令时 UTC-7"
},
{
"id": 5,
"timezoneId": "Europe/London",
"timezoneName": "英国时间",
"timezoneOffset": "UTC+0",
"isDefault": false,
"sortOrder": 5,
"status": "0",
"remark": "英国时间(夏令时 UTC+1"
},
{
"id": 6,
"timezoneId": "Europe/Paris",
"timezoneName": "中欧时间",
"timezoneOffset": "UTC+1",
"isDefault": false,
"sortOrder": 6,
"status": "0",
"remark": "中欧时间(夏令时 UTC+2"
},
{
"id": 7,
"timezoneId": "Asia/Tokyo",
"timezoneName": "日本标准时间",
"timezoneOffset": "UTC+9",
"isDefault": false,
"sortOrder": 7,
"status": "0",
"remark": "日本标准时间"
},
{
"id": 8,
"timezoneId": "Australia/Sydney",
"timezoneName": "澳大利亚东部时间",
"timezoneOffset": "UTC+10",
"isDefault": false,
"sortOrder": 8,
"status": "0",
"remark": "澳大利亚东部时间(夏令时 UTC+11"
}
]
}
```
**失败响应:**
```json
{
"code": 500,
"msg": "获取时区列表失败",
"data": null
}
```
#### 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 获取成功 |
| 500 | 获取失败 |
#### 业务规则
1. 时区列表从数据库读取
2. 时区列表固定,后续不允许用户调整
3. 时区列表使用 Redis 缓存,缓存时间 24 小时
4. 返回的时区列表按排序字段排序
5. 只返回状态为正常0的时区
---
### 接口 2获取当前用户时区
#### 功能描述
获取当前登录用户的时区偏好返回用户的时区ID。如果用户未设置时区返回系统默认时区。
#### 请求方式
GET
#### 请求路径
`/system/timezone/current`
#### 权限要求
- 无(需要登录)
#### 请求参数
#### 请求示例
```bash
curl -X GET 'http://localhost:8080/system/timezone/current' \
-H 'Authorization: Bearer {token}'
```
#### 响应数据结构
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功500 失败) |
| msg | String | 提示信息 |
| data | Object | 时区信息 |
| data.timezoneId | String | 时区ID如 Asia/Shanghai |
| data.timezoneName | String | 时区名称(如 中国标准时间) |
| data.timezoneOffset | String | 时区偏移(如 UTC+8 |
| data.isDefault | Boolean | 是否系统默认时区 |
#### 响应示例
**成功响应(用户已设置时区):**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": false
}
}
```
**成功响应(用户未设置时区,返回系统默认时区):**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": true
}
}
```
**失败响应:**
```json
{
"code": 500,
"msg": "获取当前用户时区失败",
"data": null
}
```
#### 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 获取成功 |
| 500 | 获取失败或未找到用户信息 |
#### 业务规则
1. 优先级:用户时区 > 租户时区 > 系统时区
2. 如果用户未设置时区,返回系统默认时区
3. 用户时区使用 Redis 缓存,缓存时间 30 分钟
4. 需要用户登录才能获取时区信息
---
### 接口 3切换时区
#### 功能描述
切换当前登录用户的时区偏好,更新用户时区设置,清除相关缓存,返回切换结果。时区切换后,前端需要刷新页面重新加载时间数据。
#### 请求方式
POST
#### 请求路径
`/system/timezone/switch`
#### 权限要求
- 无(需要登录)
#### 请求参数
| 参数名 | 类型 | 必选 | 说明 |
|--------|------|------|------|
| timeZone | String | 是 | 时区ID如 Asia/Shanghai、America/New_York |
#### 请求示例
```bash
curl -X POST 'http://localhost:8080/system/timezone/switch' \
-H 'Authorization: Bearer {token}' \
-H 'Content-Type: application/json' \
-d '{
"timeZone": "America/New_York"
}'
```
#### 响应数据结构
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功400/500 失败) |
| msg | String | 提示信息 |
| data | Object | 数据对象(通常为 null |
#### 响应示例
**成功响应:**
```json
{
"code": 200,
"msg": "时区切换成功",
"data": null
}
```
**失败响应无效的时区ID**
```json
{
"code": 400,
"msg": "无效的时区ID",
"data": null
}
```
**失败响应(未找到用户信息):**
```json
{
"code": 500,
"msg": "未找到用户信息",
"data": null
}
```
#### 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 切换成功 |
| 400 | 无效的时区ID |
| 500 | 切换失败或未找到用户信息 |
#### 业务规则
1. 验证时区ID的有效性
2. 更新用户时区偏好到数据库
3. 清除用户时区缓存
4. 清除相关数据缓存(如字典缓存、配置缓存等)
5. 时区切换后,前端需要刷新页面重新加载时间数据
6. 时区切换记录审计日志
7. 时区切换响应时间 < 500ms
---
### 接口 4获取默认时区
#### 功能描述
获取系统默认时区配置返回系统默认时区的详细信息系统默认时区用于用户未设置时区时的回退时区
#### 请求方式
GET
#### 请求路径
`/system/timezone/default`
#### 权限要求
- 通常公开或需登录
#### 请求参数
#### 请求示例
```bash
curl -X GET 'http://localhost:8080/system/timezone/default' \
-H 'Authorization: Bearer {token}'
```
#### 响应数据结构
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功500 失败 |
| msg | String | 提示信息 |
| data | Object | 时区信息 |
| data.timezoneId | String | 时区ID Asia/Shanghai |
| data.timezoneName | String | 时区名称 中国标准时间 |
| data.timezoneOffset | String | 时区偏移 UTC+8 |
#### 响应示例
**成功响应:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8"
}
}
```
**失败响应:**
```json
{
"code": 500,
"msg": "获取默认时区失败",
"data": null
}
```
#### 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 获取成功 |
| 500 | 获取失败或未找到默认时区 |
#### 业务规则
1. 系统必须有默认时区配置
2. 默认时区从数据库读取
3. 默认时区使用 Redis 缓存缓存时间 24 小时
4. 默认时区用于用户未设置时区时的回退时区
---
### 接口 5获取时区详细信息
#### 功能描述
根据时区ID获取时区的详细信息包括时区ID时区名称时区偏移等
#### 请求方式
GET
#### 请求路径
`/system/timezone/{timezoneId}`
#### 权限要求
- 通常公开或需登录
#### 请求参数
| 参数名 | 类型 | 必选 | 说明 |
|--------|------|------|------|
| timezoneId | String | | 时区ID路径参数 |
#### 请求示例
```bash
curl -X GET 'http://localhost:8080/system/timezone/Asia/Shanghai' \
-H 'Authorization: Bearer {token}'
```
#### 响应数据结构
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功404/500 失败 |
| msg | String | 提示信息 |
| data | Object | 时区信息 |
| data.id | Long | 时区ID |
| data.timezoneId | String | 时区ID Asia/Shanghai |
| data.timezoneName | String | 时区名称 中国标准时间 |
| data.timezoneOffset | String | 时区偏移 UTC+8 |
| data.isDefault | Boolean | 是否默认时区 |
| data.sortOrder | Integer | 排序 |
| data.status | String | 状态0正常 1停用 |
| data.remark | String | 备注 |
#### 响应示例
**成功响应:**
```json
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 2,
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": true,
"sortOrder": 2,
"status": "0",
"remark": "中国标准时间"
}
}
```
**失败响应(时区不存在):**
```json
{
"code": 404,
"msg": "时区不存在",
"data": null
}
```
#### 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 获取成功 |
| 404 | 时区不存在 |
| 500 | 获取失败 |
---
### 接口 6刷新时区缓存
#### 功能描述
刷新时区列表缓存清除所有时区相关的缓存数据使最新的时区配置立即生效
#### 请求方式
DELETE
#### 请求路径
`/system/timezone/refreshCache`
#### 权限要求
- `system:timezone:refresh`
#### 请求参数
#### 请求示例
```bash
curl -X DELETE 'http://localhost:8080/system/timezone/refreshCache' \
-H 'Authorization: Bearer {token}'
```
#### 响应数据结构
| 参数名 | 类型 | 说明 |
|--------|------|------|
| code | Integer | 状态码200 成功500 失败 |
| msg | String | 提示信息 |
| data | Object | 数据对象通常为 null |
#### 响应示例
**成功响应:**
```json
{
"code": 200,
"msg": "时区缓存刷新成功",
"data": null
}
```
**失败响应:**
```json
{
"code": 500,
"msg": "时区缓存刷新失败",
"data": null
}
```
#### 错误码说明
| 错误码 | 说明 |
|--------|------|
| 200 | 刷新成功 |
| 500 | 刷新失败 |
#### 业务规则
1. 清除时区列表缓存sys:timezone:list
2. 清除所有用户时区缓存user:timezone:*
3. 清除相关数据缓存如字典缓存配置缓存等
4. 刷新后下次查询时重新加载数据
---
## 数据库表结构
### sys_timezone 表(时区配置表)
```sql
CREATE TABLE `sys_timezone` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '时区ID',
`timezone_id` varchar(50) NOT NULL COMMENT '时区IDAsia/Shanghai',
`timezone_name` varchar(100) NOT NULL COMMENT '时区名称(如:中国标准时间)',
`timezone_offset` varchar(10) NOT NULL COMMENT '时区偏移UTC+8',
`is_default` tinyint(1) DEFAULT '0' COMMENT '是否默认时区0否 1是',
`sort_order` int DEFAULT '0' COMMENT '排序',
`status` char(1) DEFAULT '0' COMMENT '状态0正常 1停用',
`create_by` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_timezone_id` (`timezone_id`),
KEY `idx_status` (`status`),
KEY `idx_sort_order` (`sort_order`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='时区配置表';
```
### sys_user 表修改(用户表)
```sql
ALTER TABLE `sys_user`
ADD COLUMN `time_zone` varchar(50) DEFAULT 'Asia/Shanghai' COMMENT '时区ID' AFTER `lang_code`;
```
---
## 常用时区列表
| 时区ID | 时区名称 | 时区偏移 | 是否默认 |
|--------|---------|---------|---------|
| UTC | 协调世界时 | UTC+0 | |
| Asia/Shanghai | 中国标准时间 | UTC+8 | |
| America/New_York | 美国东部时间 | UTC-5 | |
| America/Los_Angeles | 美国太平洋时间 | UTC-8 | |
| Europe/London | 英国时间 | UTC+0 | |
| Europe/Paris | 中欧时间 | UTC+1 | |
| Asia/Tokyo | 日本标准时间 | UTC+9 | |
| Australia/Sydney | 澳大利亚东部时间 | UTC+10 | |
---
## 时区转换说明
### 时区转换流程
```
数据查询
├─ 从数据库读取 UTC 时间
├─ 获取用户时区偏好(优先级:用户 > 租户 > 系统)
├─ 在 Service 层根据用户时区转换时间
└─ 返回转换后的时间
数据保存
├─ 接收用户时区时间
├─ 在 Service 层转换为 UTC 时间
└─ 保存 UTC 时间到数据库
时区切换
├─ 用户选择新时区
├─ 验证时区ID有效性
├─ 更新用户时区偏好
├─ 清除 Redis 缓存
├─ 刷新页面
└─ 重新加载时间数据
```
### 时区转换示例
```java
// 示例UTC 时间转换为用户时区时间
LocalDateTime utcTime = LocalDateTime.now(ZoneOffset.UTC);
ZoneId userZone = ZoneId.of("Asia/Shanghai");
LocalDateTime userTime = utcTime.atZone(ZoneOffset.UTC).withZoneSameInstant(userZone).toLocalDateTime();
// 示例:用户时区时间转换为 UTC 时间
LocalDateTime userTime = LocalDateTime.now();
ZoneId userZone = ZoneId.of("Asia/Shanghai");
LocalDateTime utcTime = userTime.atZone(userZone).withZoneSameInstant(ZoneOffset.UTC).toLocalDateTime();
```
---
## 缓存策略
### 缓存键格式
- 时区列表`sys:timezone:list`
- 用户时区`user:timezone:{userId}`
- 数据缓存在原有缓存键基础上添加时区后缀 `dict:data:zh_CN:Asia/Shanghai`
### 缓存时间
- 时区列表缓存24 小时
- 用户时区缓存30 分钟
### 缓存刷新规则
1. 时区列表更新时清除时区列表缓存
2. 时区切换时清除用户时区缓存
3. 时区切换时清除相关数据缓存如字典缓存配置缓存等
4. 手动刷新时区缓存时清除所有时区相关缓存
---
## 时区优先级
### 时区优先级规则
1. **用户时区**用户设置的时区偏好优先级最高
2. **租户时区**租户级别的时区配置优先级次之
3. **系统时区**系统默认时区优先级最低
### 时区获取流程
```
获取用户时区
├─ 检查用户是否设置了时区
│ ├─ 是:返回用户时区
│ └─ 否:继续检查
├─ 检查租户是否设置了时区
│ ├─ 是:返回租户时区
│ └─ 否:继续检查
└─ 返回系统默认时区
```
---
## 注意事项
1. **时区验证**切换时区时必须验证时区ID的有效性
2. **时区转换**时区转换在 Service 层进行确保数据一致性
3. **时间存储**所有时间字段存储为 UTC 时间
4. **缓存管理**时区配置需要缓存提高性能
5. **页面刷新**时区切换后立即刷新页面重新加载时间数据
6. **时区列表**时区列表固定存储在数据库中后续不允许用户调整
7. **夏令时处理**使用 Java TimeZone API 自动处理夏令时
8. **时区优先级**用户时区 > 租户时区 > 系统时区
9. **权限控制**:所有用户都可以设置和切换时区
10. **审计日志**:记录时区设置变更日志
---
## 性能要求
- **时区转换时间**< 10ms
- **时区切换响应时间**< 500ms
- **时区缓存命中率**:≥ 95%
- **并发支持**支持 1000+ 并发用户
---
## 相关文档
- [需求文档](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/requirements/2026-01-21-002-04-时区国际化需求.md)
- [设计文档](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/design/2026-01-21-002-04-时区国际化设计.md)
- [架构决策记录](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/decisions/adr/2026-01-25-002-04-ADR-时区国际化技术选型.md)
- [SQL 脚本](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/sql/2026-01-25-002-04-timezone-internationalization.sql)
- [提示词文档](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/prompts/2026-01-25-002-04-prompt-时区国际化功能.md)
- [参考代码](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/reference-code/2026-01-25-002-04-code-时区国际化功能实现.md)
- [实施方案](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/implementation/2026-01-25-002-04-implementation-时区国际化功能实现.md)
- [会话记录](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/sessions/2026-01-25-002-04-session.md)
- [变更日志](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/changelogs/2026-01-25-002-04-changelog.md)
- [复盘文档](file:///d:/idea_demo/datai/datai-scenes/datai-scene-salesforce/docs/retros/2026-01-25-002-04-retro.md)