fix(config): 统一历史记录与配置的数据库时间来源
- saveHistory 接收调用方传入的数据库时间,不再使用 time.Now() - 更新、删除、回滚先取 dao.Now(),避免取时间失败时产生无效历史 - 历史表 created_at 升级为 datetime(3),新增迁移脚本
This commit is contained in:
@@ -278,19 +278,20 @@ func (h *ConfigHandler) Update(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// save history
|
|
||||||
h.saveHistory(&config, userInfo.Name, "update")
|
|
||||||
|
|
||||||
originalContents := config.Contents
|
|
||||||
config.Contents = req.Contents
|
|
||||||
config.Version = req.Version
|
|
||||||
config.UpdatedBy = userInfo.Name
|
|
||||||
now, err := dao.Now()
|
now, err := dao.Now()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.SugaredLogger.Errorf("[ConfigHandler.Update] get database time error: %v", err)
|
logger.SugaredLogger.Errorf("[ConfigHandler.Update] get database time error: %v", err)
|
||||||
c.JSON(http.StatusInternalServerError, model.WrapperResponse{Code: 500, Msg: "保存失败"})
|
c.JSON(http.StatusInternalServerError, model.WrapperResponse{Code: 500, Msg: "保存失败"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save history
|
||||||
|
h.saveHistory(&config, userInfo.Name, "update", now)
|
||||||
|
|
||||||
|
originalContents := config.Contents
|
||||||
|
config.Contents = req.Contents
|
||||||
|
config.Version = req.Version
|
||||||
|
config.UpdatedBy = userInfo.Name
|
||||||
config.UpdatedAt = &now
|
config.UpdatedAt = &now
|
||||||
|
|
||||||
dao.Engine.ID(config.Id).Cols("contents", "version", "updated_by", "updated_at").Update(&config)
|
dao.Engine.ID(config.Id).Cols("contents", "version", "updated_by", "updated_at").Update(&config)
|
||||||
@@ -316,17 +317,18 @@ func (h *ConfigHandler) Delete(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录删除前的配置内容
|
|
||||||
h.saveHistory(&config, userInfo.Name, "delete")
|
|
||||||
|
|
||||||
config.Enabled = false
|
|
||||||
config.UpdatedBy = userInfo.Name
|
|
||||||
now, err := dao.Now()
|
now, err := dao.Now()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.SugaredLogger.Errorf("[ConfigHandler.Delete] get database time error: %v", err)
|
logger.SugaredLogger.Errorf("[ConfigHandler.Delete] get database time error: %v", err)
|
||||||
c.JSON(http.StatusInternalServerError, model.WrapperResponse{Code: 500, Msg: "删除失败"})
|
c.JSON(http.StatusInternalServerError, model.WrapperResponse{Code: 500, Msg: "删除失败"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 记录删除前的配置内容
|
||||||
|
h.saveHistory(&config, userInfo.Name, "delete", now)
|
||||||
|
|
||||||
|
config.Enabled = false
|
||||||
|
config.UpdatedBy = userInfo.Name
|
||||||
config.UpdatedAt = &now
|
config.UpdatedAt = &now
|
||||||
dao.Engine.ID(config.Id).Cols("enabled", "updated_by", "updated_at").Update(&config)
|
dao.Engine.ID(config.Id).Cols("enabled", "updated_by", "updated_at").Update(&config)
|
||||||
|
|
||||||
@@ -431,17 +433,18 @@ func (h *ConfigHandler) Rollback(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 记录回滚前的配置内容
|
|
||||||
h.saveHistory(&config, userInfo.Name, "rollback")
|
|
||||||
|
|
||||||
config.Contents = history.Contents
|
|
||||||
config.UpdatedBy = userInfo.Name
|
|
||||||
now, err := dao.Now()
|
now, err := dao.Now()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.SugaredLogger.Errorf("[ConfigHandler.Rollback] get database time error: %v", err)
|
logger.SugaredLogger.Errorf("[ConfigHandler.Rollback] get database time error: %v", err)
|
||||||
c.JSON(http.StatusInternalServerError, model.WrapperResponse{Code: 500, Msg: "回滚失败"})
|
c.JSON(http.StatusInternalServerError, model.WrapperResponse{Code: 500, Msg: "回滚失败"})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 记录回滚前的配置内容
|
||||||
|
h.saveHistory(&config, userInfo.Name, "rollback", now)
|
||||||
|
|
||||||
|
config.Contents = history.Contents
|
||||||
|
config.UpdatedBy = userInfo.Name
|
||||||
config.UpdatedAt = &now
|
config.UpdatedAt = &now
|
||||||
dao.Engine.ID(config.Id).Cols("contents", "updated_by", "updated_at").Update(&config)
|
dao.Engine.ID(config.Id).Cols("contents", "updated_by", "updated_at").Update(&config)
|
||||||
}
|
}
|
||||||
@@ -460,7 +463,7 @@ func (h *ConfigHandler) buildAppNames(config *model.AppConfig) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *ConfigHandler) saveHistory(config *model.AppConfig, operator, operate string) {
|
func (h *ConfigHandler) saveHistory(config *model.AppConfig, operator, operate string, createdAt time.Time) {
|
||||||
history := model.AppConfigHistory{
|
history := model.AppConfigHistory{
|
||||||
OriginId: config.Id,
|
OriginId: config.Id,
|
||||||
AppId: config.AppId,
|
AppId: config.AppId,
|
||||||
@@ -471,7 +474,7 @@ func (h *ConfigHandler) saveHistory(config *model.AppConfig, operator, operate s
|
|||||||
Type: config.Type,
|
Type: config.Type,
|
||||||
Operate: operate,
|
Operate: operate,
|
||||||
Contents: config.Contents,
|
Contents: config.Contents,
|
||||||
CreatedAt: func() *time.Time { t := time.Now(); return &t }(),
|
CreatedAt: &createdAt,
|
||||||
CreatedBy: operator,
|
CreatedBy: operator,
|
||||||
}
|
}
|
||||||
dao.Engine.Insert(&history)
|
dao.Engine.Insert(&history)
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type AppConfigHistory struct {
|
|||||||
Operate string `xorm:"varchar(16)" json:"operate"` // update, delete, rollback
|
Operate string `xorm:"varchar(16)" json:"operate"` // update, delete, rollback
|
||||||
Contents string `xorm:"text" json:"contents"`
|
Contents string `xorm:"text" json:"contents"`
|
||||||
ActiveContents string `xorm:"-" json:"activeContents,omitempty"`
|
ActiveContents string `xorm:"-" json:"activeContents,omitempty"`
|
||||||
CreatedAt *time.Time `xorm:"datetime" json:"createdAt"`
|
CreatedAt *time.Time `xorm:"datetime(3)" json:"createdAt"`
|
||||||
CreatedBy string `xorm:"varchar(32)" json:"createdBy"`
|
CreatedBy string `xorm:"varchar(32)" json:"createdBy"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ CREATE TABLE `app_config_history` (
|
|||||||
`type` smallint DEFAULT NULL,
|
`type` smallint DEFAULT NULL,
|
||||||
`operate` varchar(16) DEFAULT NULL,
|
`operate` varchar(16) DEFAULT NULL,
|
||||||
`contents` text,
|
`contents` text,
|
||||||
`created_at` datetime DEFAULT NULL,
|
`created_at` datetime(3) DEFAULT NULL,
|
||||||
`created_by` varchar(32) DEFAULT NULL,
|
`created_by` varchar(32) DEFAULT NULL,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8mb3;
|
) ENGINE=InnoDB AUTO_INCREMENT=39 DEFAULT CHARSET=utf8mb3;
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
-- 将配置历史时间字段升级为毫秒精度,与 app_config 保持一致。
|
||||||
|
-- 新库由 xorm Sync2 按模型定义建表,已有环境执行本脚本升级。
|
||||||
|
|
||||||
|
ALTER TABLE `app_config_history`
|
||||||
|
MODIFY COLUMN `created_at` DATETIME(3) NULL DEFAULT NULL;
|
||||||
Reference in New Issue
Block a user