数据格式说明
本文档详细说明了源丰后端API系统中使用的各种数据格式、字段规范和验证规则。
📋 概述
API使用JSON格式进行数据交换,所有日期时间、文件、数值等都有统一的格式规范。遵循这些规范可以确保数据的正确性和一致性。
🎯 通用数据格式
JSON 响应结构
所有API响应都遵循统一的JSON结构:
json
{
"success": true, // 请求是否成功
"message": "操作成功", // 响应消息
"data": { // 响应数据(可选)
// 具体的业务数据
},
"errors": [ // 错误详情(可选)
{
"field": "字段名",
"tag": "验证标签",
"value": "当前值",
"message": "错误消息",
"param": "验证参数"
}
]
}分页响应格式
json
{
"success": true,
"message": "获取成功",
"data": { // 数据列表
"items": [
{
"id": 1,
"name": "张三"
}
]
},
"pagination": { // 分页信息
"page": 1, // 当前页码
"page_size": 20, // 每页数量
"total": 100, // 总记录数
"total_pages": 5 // 总页数
}
}错误响应格式
json
{
"success": false,
"message": "参数验证失败",
"errors": [ // 字段验证错误详情
{
"field": "用户名",
"tag": "min",
"value": "ab",
"message": "字段 '用户名' 长度不能小于 3 位",
"param": "3"
},
{
"field": "邮箱",
"tag": "email",
"value": "invalid-email",
"message": "字段 '邮箱' 邮箱格式不正确",
"param": ""
}
]
}简单错误响应
json
{
"success": false,
"message": "资源不存在"
}📅 日期时间格式
标准格式
所有日期时间字段都使用 ISO 8601 格式:
json
{
"created_at": "2024-01-15T10:30:00Z", // UTC时间
"updated_at": "2024-01-15T18:30:00+08:00", // 带时区的时间
"report_date": "2024-01-15", // 仅日期
"clock_in_time": "2024-01-15T09:00:00+08:00" // 具体时间
}日期格式说明
| 格式 | 示例 | 说明 | 使用场景 |
|---|---|---|---|
YYYY-MM-DD | 2024-01-15 | 仅日期 | 生日、入职日期、报告日期 |
YYYY-MM-DDTHH:mm:ssZ | 2024-01-15T10:30:00Z | UTC时间 | 创建时间、更新时间 |
YYYY-MM-DDTHH:mm:ss±HH:mm | 2024-01-15T18:30:00+08:00 | 带时区时间 | 打卡时间、具体操作时间 |
HH:mm:ss | 09:30:00 | 仅时间 | 营业时间、工作时间 |
时区处理
- 服务器存储: 所有时间在数据库中以UTC时间存储
- API响应: 根据用户时区返回相应的时间格式
- 客户端处理: 建议在前端根据用户时区进行显示转换
🔢 数值格式
整数类型
json
{
"id": 1, // 用户ID、员工ID等
"age": 25, // 年龄
"page": 1, // 页码
"page_size": 20, // 每页数量
"total": 100 // 总数
}浮点数类型
json
{
"latitude": 39.908823, // 纬度(6位小数)
"longitude": 116.397470, // 经度(6位小数)
"salary": 8500.50, // 薪资(2位小数)
"attendance_rate": 0.95 // 出勤率(2-3位小数)
}金额格式
- 精度: 金额字段保留2位小数
- 货币单位: 默认为人民币(CNY)
- 存储格式: 以分为单位存储整数,API返回时转换为元
json
{
"base_salary": 8500.50, // 基本工资
"bonus": 1200.00, // 奖金
"deduction": 350.25, // 扣款
"total_salary": 9350.25 // 总薪资
}📝 字符串格式
文本字段
json
{
"name": "张三", // 姓名:2-50字符
"email": "user@example.com", // 邮箱:标准邮箱格式
"phone": "13800138000", // 手机号:11位数字
"id_card": "110101199001011234", // 身份证:18位字符
"description": "这是描述信息" // 描述:最大1000字符
}枚举值
json
{
"status": "active", // 状态:active/inactive/pending
"priority": "high", // 优先级:low/medium/high/urgent
"gender": "male", // 性别:male/female/other
"employee_type": "full_time" // 员工类型:full_time/part_time/intern
}常用枚举值
用户状态
active: 活跃inactive: 非活跃pending: 待激活disabled: 已禁用
员工状态
active: 在职inactive: 离职probation: 试用期suspended: 停职
考勤状态
normal: 正常late: 迟到early_leave: 早退absent: 缺勤leave: 请假
待办事项状态
pending: 待处理in_progress: 进行中completed: 已完成cancelled: 已取消
待办事项优先级
low: 低优先级medium: 中等优先级high: 高优先级urgent: 紧急
📁 文件格式
文件上传
json
{
"file": "binary_data", // 文件二进制数据
"filename": "document.pdf", // 原始文件名
"content_type": "application/pdf", // MIME类型
"size": 1024000, // 文件大小(字节)
"folder": "documents" // 存储文件夹
}文件信息响应
json
{
"id": "file_123456789", // 文件ID
"filename": "document.pdf", // 文件名
"url": "https://example.com/files/document.pdf", // 访问URL
"size": 1024000, // 文件大小
"content_type": "application/pdf", // 文件类型
"created_at": "2024-01-15T10:30:00Z"
}支持的文件类型
| 类型 | MIME类型 | 扩展名 | 最大大小 |
|---|---|---|---|
| 图片 | image/jpeg, image/png | .jpg, .jpeg, .png | 5MB |
| 文档 | application/pdf | 10MB | |
| 文档 | application/msword | .doc | 5MB |
| 文档 | application/vnd.openxmlformats-officedocument.wordprocessingml.document | .docx | 10MB |
| 表格 | application/vnd.ms-excel | .xls | 5MB |
| 表格 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | .xlsx | 10MB |
| 压缩包 | application/zip | .zip | 20MB |
📋 分页格式
分页请求参数
json
{
"page": 1, // 页码,从1开始,默认1
"page_size": 20, // 每页数量,默认10,最大100
"sort": "id", // 排序字段,默认id
"order": "desc", // 排序方向:asc/desc,默认desc
"search": "关键词", // 搜索关键词(扩展分页)
"status": 1, // 状态过滤(扩展分页)
"sort_by": "created_at", // 排序字段(扩展分页)
"sort_order": "desc" // 排序方向(扩展分页)
}URL查询参数示例:
GET /api/v1/users?page=1&page_size=20&sort=created_at&order=desc&search=张三分页响应结构
json
{
"success": true,
"data": {
"items": [ // 数据列表
{
"id": 1,
"name": "张三"
}
]
},
"pagination": {
"page": 1, // 当前页码
"page_size": 20, // 每页数量
"total": 100, // 总记录数
"pages": 5, // 总页数
"has_prev": false, // 是否有上一页
"has_next": true // 是否有下一页
}
}🏷️ 标签和分类格式
标签格式
json
{
"tags": ["开发", "API", "文档"], // 标签数组
"categories": ["技术", "文档"] // 分类数组
}标签规范
- 长度: 每个标签1-20个字符
- 字符: 支持中文、英文、数字、下划线
- 数量: 每个资源最多10个标签
- 去重: 自动去除重复标签
🌐 多语言格式
多语言字段
json
{
"name": {
"zh-CN": "员工管理", // 中文
"en-US": "Employee Management", // 英文
"default": "zh-CN" // 默认语言
},
"description": {
"zh-CN": "员工信息管理模块",
"en-US": "Employee information management module"
}
}语言代码
zh-CN: 简体中文en-US: 美式英语zh-TW: 繁体中文ja-JP: 日语
🔍 搜索格式
搜索请求
json
{
"query": "张三", // 搜索关键词
"fields": ["name", "email"], // 搜索字段
"filters": { // 筛选条件
"status": "active",
"department_id": 1
},
"sort": { // 排序
"field": "created_at",
"order": "desc"
},
"page": 1,
"page_size": 20
}搜索响应
json
{
"success": true,
"data": {
"results": [ // 搜索结果
{
"id": 1,
"name": "张三",
"email": "zhangsan@example.com",
"score": 0.95, // 匹配分数
"highlights": { // 高亮片段
"name": "<em>张三</em>"
}
}
],
"total": 1,
"took": 15 // 搜索耗时(毫秒)
}
}✅ 数据验证规则
字段验证
| 字段类型 | 验证规则 | 示例 |
|---|---|---|
| 邮箱 | 标准邮箱格式 | user@example.com |
| 手机号 | 11位数字,1开头 | 13800138000 |
| 身份证 | 18位字符,最后一位可能是X | 110101199001011234 |
| 密码 | 8-20位,包含字母和数字 | password123 |
| URL | 标准URL格式 | https://example.com |
| IP地址 | IPv4或IPv6格式 | 192.168.1.1 |
字符串长度限制
| 字段类型 | 最小长度 | 最大长度 |
|---|---|---|
| 姓名 | 2 | 50 |
| 密码 | 8 | 20 |
| 标题 | 1 | 100 |
| 描述 | 0 | 1000 |
| 备注 | 0 | 500 |
数值范围限制
| 字段类型 | 最小值 | 最大值 |
|---|---|---|
| 年龄 | 18 | 65 |
| 页码 | 1 | 1000 |
| 每页数量 | 1 | 100 |
| 金额 | 0 | 999999.99 |
| 出勤率 | 0 | 1 |
🔄 数据转换示例
前端JavaScript示例
javascript
// 日期时间格式化
function formatDateTime(dateString) {
const date = new Date(dateString);
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
}
// 金额格式化
function formatCurrency(amount) {
return new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(amount);
}
// 文件大小格式化
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
// 使用示例
console.log(formatDateTime('2024-01-15T10:30:00Z')); // 2024/01/15 18:30
console.log(formatCurrency(8500.50)); // ¥8,500.50
console.log(formatFileSize(1024000)); // 1.00 MBPython示例
python
from datetime import datetime
import locale
# 设置本地化
locale.setlocale(locale.LC_ALL, 'zh_CN.UTF-8')
def format_datetime(date_string):
"""格式化日期时间"""
dt = datetime.fromisoformat(date_string.replace('Z', '+00:00'))
return dt.strftime('%Y年%m月%d日 %H:%M:%S')
def format_currency(amount):
"""格式化金额"""
return f"¥{amount:,.2f}"
def format_file_size(bytes_size):
"""格式化文件大小"""
if bytes_size == 0:
return "0 B"
k = 1024
sizes = ['B', 'KB', 'MB', 'GB']
i = int(math.floor(math.log(bytes_size) / math.log(k)))
return f"{bytes_size / math.pow(k, i):.2f} {sizes[i]}"
# 使用示例
print(format_datetime('2024-01-15T10:30:00Z')) # 2024年01月15日 18:30:00
print(format_currency(8500.50)) # ¥8,500.50
print(format_file_size(1024000)) # 1.00 MB📞 数据格式支持
如果您对数据格式有疑问或需要支持其他格式:
- 查看API文档: 详细字段说明请参考各模块API文档
- 联系技术支持: 提供具体的数据格式需求
- 提交反馈: 在GitHub Issues中提交格式改进建议
最后更新: 2024-01-24 文档版本: v1.0 维护团队: 源丰后端开发团队