- 更新 environment.js 中 initSlaveDatasource 函数参数从 environmentCode 改为 environmentId - 更新 SourceEnvironmentTab.vue 中的初始化从库功能以使用 environmentId - 在 TargetEnvironmentTab.vue 中添加完整的初始化从库功能 - 初始化项目单一真源(SSOT)文档结构,包括: - 创建主 index.md 作为项目单一真源 - 创建 Authentication.canvas 可视化文件 - 创建所有必需的文档目录和 README.md 文件 - 建立完整的双向索引关系
19 KiB
19 KiB
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是) |
请求示例
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 | 备注 |
响应示例
成功响应:
{
"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)"
}
]
}
失败响应:
{
"code": 500,
"msg": "获取时区列表失败",
"data": null
}
错误码说明
| 错误码 | 说明 |
|---|---|
| 200 | 获取成功 |
| 500 | 获取失败 |
业务规则
- 时区列表从数据库读取
- 时区列表固定,后续不允许用户调整
- 时区列表使用 Redis 缓存,缓存时间 24 小时
- 返回的时区列表按排序字段排序
- 只返回状态为正常(0)的时区
接口 2:获取当前用户时区
功能描述
获取当前登录用户的时区偏好,返回用户的时区ID。如果用户未设置时区,返回系统默认时区。
请求方式
GET
请求路径
/system/timezone/current
权限要求
- 无(需要登录)
请求参数
无
请求示例
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 | 是否系统默认时区 |
响应示例
成功响应(用户已设置时区):
{
"code": 200,
"msg": "操作成功",
"data": {
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": false
}
}
成功响应(用户未设置时区,返回系统默认时区):
{
"code": 200,
"msg": "操作成功",
"data": {
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": true
}
}
失败响应:
{
"code": 500,
"msg": "获取当前用户时区失败",
"data": null
}
错误码说明
| 错误码 | 说明 |
|---|---|
| 200 | 获取成功 |
| 500 | 获取失败或未找到用户信息 |
业务规则
- 优先级:用户时区 > 租户时区 > 系统时区
- 如果用户未设置时区,返回系统默认时区
- 用户时区使用 Redis 缓存,缓存时间 30 分钟
- 需要用户登录才能获取时区信息
接口 3:切换时区
功能描述
切换当前登录用户的时区偏好,更新用户时区设置,清除相关缓存,返回切换结果。时区切换后,前端需要刷新页面重新加载时间数据。
请求方式
POST
请求路径
/system/timezone/switch
权限要求
- 无(需要登录)
请求参数
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
| timeZone | String | 是 | 时区ID(如 Asia/Shanghai、America/New_York) |
请求示例
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) |
响应示例
成功响应:
{
"code": 200,
"msg": "时区切换成功",
"data": null
}
失败响应(无效的时区ID):
{
"code": 400,
"msg": "无效的时区ID",
"data": null
}
失败响应(未找到用户信息):
{
"code": 500,
"msg": "未找到用户信息",
"data": null
}
错误码说明
| 错误码 | 说明 |
|---|---|
| 200 | 切换成功 |
| 400 | 无效的时区ID |
| 500 | 切换失败或未找到用户信息 |
业务规则
- 验证时区ID的有效性
- 更新用户时区偏好到数据库
- 清除用户时区缓存
- 清除相关数据缓存(如字典缓存、配置缓存等)
- 时区切换后,前端需要刷新页面重新加载时间数据
- 时区切换记录审计日志
- 时区切换响应时间 < 500ms
接口 4:获取默认时区
功能描述
获取系统默认时区配置,返回系统默认时区的详细信息。系统默认时区用于用户未设置时区时的回退时区。
请求方式
GET
请求路径
/system/timezone/default
权限要求
- 无(通常公开或需登录)
请求参数
无
请求示例
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) |
响应示例
成功响应:
{
"code": 200,
"msg": "操作成功",
"data": {
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8"
}
}
失败响应:
{
"code": 500,
"msg": "获取默认时区失败",
"data": null
}
错误码说明
| 错误码 | 说明 |
|---|---|
| 200 | 获取成功 |
| 500 | 获取失败或未找到默认时区 |
业务规则
- 系统必须有默认时区配置
- 默认时区从数据库读取
- 默认时区使用 Redis 缓存,缓存时间 24 小时
- 默认时区用于用户未设置时区时的回退时区
接口 5:获取时区详细信息
功能描述
根据时区ID获取时区的详细信息,包括时区ID、时区名称、时区偏移等。
请求方式
GET
请求路径
/system/timezone/{timezoneId}
权限要求
- 无(通常公开或需登录)
请求参数
| 参数名 | 类型 | 必选 | 说明 |
|---|---|---|---|
| timezoneId | String | 是 | 时区ID(路径参数) |
请求示例
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 | 备注 |
响应示例
成功响应:
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 2,
"timezoneId": "Asia/Shanghai",
"timezoneName": "中国标准时间",
"timezoneOffset": "UTC+8",
"isDefault": true,
"sortOrder": 2,
"status": "0",
"remark": "中国标准时间"
}
}
失败响应(时区不存在):
{
"code": 404,
"msg": "时区不存在",
"data": null
}
错误码说明
| 错误码 | 说明 |
|---|---|
| 200 | 获取成功 |
| 404 | 时区不存在 |
| 500 | 获取失败 |
接口 6:刷新时区缓存
功能描述
刷新时区列表缓存,清除所有时区相关的缓存数据,使最新的时区配置立即生效。
请求方式
DELETE
请求路径
/system/timezone/refreshCache
权限要求
system:timezone:refresh
请求参数
无
请求示例
curl -X DELETE 'http://localhost:8080/system/timezone/refreshCache' \
-H 'Authorization: Bearer {token}'
响应数据结构
| 参数名 | 类型 | 说明 |
|---|---|---|
| code | Integer | 状态码(200 成功,500 失败) |
| msg | String | 提示信息 |
| data | Object | 数据对象(通常为 null) |
响应示例
成功响应:
{
"code": 200,
"msg": "时区缓存刷新成功",
"data": null
}
失败响应:
{
"code": 500,
"msg": "时区缓存刷新失败",
"data": null
}
错误码说明
| 错误码 | 说明 |
|---|---|
| 200 | 刷新成功 |
| 500 | 刷新失败 |
业务规则
- 清除时区列表缓存(sys:timezone:list)
- 清除所有用户时区缓存(user:timezone:*)
- 清除相关数据缓存(如字典缓存、配置缓存等)
- 刷新后,下次查询时重新加载数据
数据库表结构
sys_timezone 表(时区配置表)
CREATE TABLE `sys_timezone` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '时区ID',
`timezone_id` varchar(50) NOT NULL COMMENT '时区ID(如:Asia/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 表修改(用户表)
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 缓存
├─ 刷新页面
└─ 重新加载时间数据
时区转换示例
// 示例: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 分钟
缓存刷新规则
- 时区列表更新时,清除时区列表缓存
- 时区切换时,清除用户时区缓存
- 时区切换时,清除相关数据缓存(如字典缓存、配置缓存等)
- 手动刷新时区缓存时,清除所有时区相关缓存
时区优先级
时区优先级规则
- 用户时区:用户设置的时区偏好(优先级最高)
- 租户时区:租户级别的时区配置(优先级次之)
- 系统时区:系统默认时区(优先级最低)
时区获取流程
获取用户时区
├─ 检查用户是否设置了时区
│ ├─ 是:返回用户时区
│ └─ 否:继续检查
├─ 检查租户是否设置了时区
│ ├─ 是:返回租户时区
│ └─ 否:继续检查
└─ 返回系统默认时区
注意事项
- 时区验证:切换时区时,必须验证时区ID的有效性
- 时区转换:时区转换在 Service 层进行,确保数据一致性
- 时间存储:所有时间字段存储为 UTC 时间
- 缓存管理:时区配置需要缓存,提高性能
- 页面刷新:时区切换后立即刷新页面,重新加载时间数据
- 时区列表:时区列表固定存储在数据库中,后续不允许用户调整
- 夏令时处理:使用 Java TimeZone API 自动处理夏令时
- 时区优先级:用户时区 > 租户时区 > 系统时区
- 权限控制:所有用户都可以设置和切换时区
- 审计日志:记录时区设置变更日志
性能要求
- 时区转换时间:< 10ms
- 时区切换响应时间:< 500ms
- 时区缓存命中率:≥ 95%
- 并发支持:支持 1000+ 并发用户