You've already forked VptPassiveAdapter
feat(config): 更新配置文件并新增自定义时间类型
- 修改 config.yaml 中的 API 地址、存储配置及设备信息 - 新增 Viid 配置项支持新功能模块 - 在 go.mod 和 go.sum 中更新依赖包版本,引入新的第三方库 - 添加 model/custom_time.go 文件实现自定义时间类型的 JSON 序列化与反序列化 - 调整 DTO 结构体以适配新的配置项 - 升级 OTLP 导出器相关依赖并移除旧的标准输出导出器 - 引入 Gin 框架及相关中间件提升服务性能 - 更新 Protobuf 和 gRPC 相关依赖至最新版本 - 增加 zap 日志库和 lumberjack 日志轮转支持 - 添加 sonic、json-iterator 等高性能 JSON 处理库优化数据解析效率 - 引入 testify 断言库增强测试代码可读性 - 更新 sync 包版本提高并发安全性 - 添加 mock 工具支持单元测试模拟对象 - 引入 validator/v10 实现请求参数校验功能 - 更新 crypto、net、text 等标准库依赖确保安全性和兼容性 - 增加 mimetype 库用于文件类型识别 - 引入 quic-go 支持 HTTP/3 协议通信 - 添加 base64x
This commit is contained in:
104
model/custom_time.go
Normal file
104
model/custom_time.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CustomTime 自定义时间类型,用于JSON序列化为YYYY-MM-DD HH:mm:ss格式
|
||||
type CustomTime struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// MarshalJSON 自定义JSON序列化
|
||||
func (ct CustomTime) MarshalJSON() ([]byte, error) {
|
||||
if ct.Time.IsZero() {
|
||||
return json.Marshal("")
|
||||
}
|
||||
return json.Marshal(ct.Time.Format("2006-01-02 15:04:05"))
|
||||
}
|
||||
|
||||
// UnmarshalJSON 自定义JSON反序列化
|
||||
// 支持格式:
|
||||
// 1. 数字时间戳:10位秒级(1732435200)或13位毫秒级(1732435200000)
|
||||
// 2. 字符串格式:秒级(2024-11-24 12:00:00)或毫秒级(2024-11-24 12:00:00.000)
|
||||
// 3. 空字符串:转换为零值时间
|
||||
func (ct *CustomTime) UnmarshalJSON(data []byte) error {
|
||||
// 1. 尝试解析为数字时间戳
|
||||
var timestamp int64
|
||||
if err := json.Unmarshal(data, ×tamp); err == nil {
|
||||
if timestamp == 0 {
|
||||
ct.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
// 根据位数判断精度:13位为毫秒级,10位为秒级
|
||||
if timestamp > 9999999999 {
|
||||
ct.Time = time.UnixMilli(timestamp)
|
||||
} else {
|
||||
ct.Time = time.Unix(timestamp, 0)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 2. 解析字符串格式
|
||||
var str string
|
||||
if err := json.Unmarshal(data, &str); err != nil {
|
||||
return err
|
||||
}
|
||||
if str == "" {
|
||||
ct.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 3. 使用本地时区解析时间,避免时区问题
|
||||
// 尝试多种格式(按精度从高到低)
|
||||
formats := []string{
|
||||
"2006-01-02 15:04:05.000", // 毫秒格式
|
||||
"2006-01-02 15:04:05", // 秒格式(现有)
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for _, format := range formats {
|
||||
t, err := time.ParseInLocation(format, str, time.Local)
|
||||
if err == nil {
|
||||
ct.Time = t
|
||||
return nil
|
||||
}
|
||||
lastErr = err
|
||||
}
|
||||
|
||||
return lastErr
|
||||
}
|
||||
|
||||
// Value 实现driver.Valuer接口,用于写入数据库
|
||||
func (ct CustomTime) Value() (driver.Value, error) {
|
||||
if ct.Time.IsZero() {
|
||||
return nil, nil
|
||||
}
|
||||
return ct.Time, nil
|
||||
}
|
||||
|
||||
// Scan 实现sql.Scanner接口,用于从数据库读取
|
||||
func (ct *CustomTime) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
ct.Time = time.Time{}
|
||||
return nil
|
||||
}
|
||||
if t, ok := value.(time.Time); ok {
|
||||
ct.Time = t
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("无法扫描 %T 到 CustomTime", value)
|
||||
}
|
||||
|
||||
// NewCustomTime 创建一个新的 CustomTime 实例
|
||||
func NewCustomTime(t time.Time) CustomTime {
|
||||
return CustomTime{Time: t}
|
||||
}
|
||||
|
||||
// NowCustomTime 返回当前时间的 CustomTime 实例
|
||||
func NowCustomTime() CustomTime {
|
||||
return CustomTime{Time: time.Now()}
|
||||
}
|
||||
Reference in New Issue
Block a user