diff --git a/mayfly_go_web/src/views/ops/db/SyncTaskLog.vue b/mayfly_go_web/src/views/ops/db/SyncTaskLog.vue
index e35984aa..ebb931a3 100644
--- a/mayfly_go_web/src/views/ops/db/SyncTaskLog.vue
+++ b/mayfly_go_web/src/views/ops/db/SyncTaskLog.vue
@@ -4,13 +4,9 @@
             
                 任务执行日志
                 
-                
+                
             
             
-                
-                    成功
-                    失败
-                
             
         
     
@@ -21,6 +17,7 @@ import { reactive, Ref, ref, toRefs, watch } from 'vue';
 import { dbApi } from '@/views/ops/db/api';
 import PageTable from '@/components/pagetable/PageTable.vue';
 import { TableColumn } from '@/components/pagetable';
+import { DbDataSyncLogStatusEnum } from './enums';
 
 const props = defineProps({
     taskId: {
@@ -36,7 +33,7 @@ const dialogVisible = defineModel('visible', { default: false });
 
 const columns = ref([
     // 状态:1.成功  -1.失败
-    TableColumn.new('status', '状态').alignCenter().isSlot(),
+    TableColumn.new('status', '状态').alignCenter().typeTag(DbDataSyncLogStatusEnum),
     TableColumn.new('createTime', '时间').alignCenter().isTime(),
     TableColumn.new('errText', '日志'),
     TableColumn.new('dataSqlFull', 'SQL').alignCenter(),
diff --git a/mayfly_go_web/src/views/ops/db/enums.ts b/mayfly_go_web/src/views/ops/db/enums.ts
index 4e77b289..0f63c988 100644
--- a/mayfly_go_web/src/views/ops/db/enums.ts
+++ b/mayfly_go_web/src/views/ops/db/enums.ts
@@ -14,6 +14,12 @@ export const DbDataSyncRecentStateEnum = {
     Fail: EnumValue.of(-1, '失败').setTagType('danger'),
 };
 
+export const DbDataSyncLogStatusEnum = {
+    Success: EnumValue.of(1, '成功').setTagType('success'),
+    Wait: EnumValue.of(2, '同步中').setTagType('primary'),
+    Fail: EnumValue.of(-1, '失败').setTagType('danger'),
+};
+
 export const DbDataSyncRunningStateEnum = {
     Success: EnumValue.of(1, '运行中').setTagType('success'),
     Wait: EnumValue.of(2, '待运行').setTagType('primary'),
diff --git a/server/internal/db/api/db.go b/server/internal/db/api/db.go
index 95f69a83..9b2509b9 100644
--- a/server/internal/db/api/db.go
+++ b/server/internal/db/api/db.go
@@ -62,7 +62,7 @@ func (d *Db) Save(rc *req.Ctx) {
 
 	rc.ReqParam = form
 
-	biz.ErrIsNil(d.DbApp.Save(rc.MetaCtx, db, form.TagId...))
+	biz.ErrIsNil(d.DbApp.SaveDb(rc.MetaCtx, db, form.TagId...))
 }
 
 func (d *Db) DeleteDb(rc *req.Ctx) {
diff --git a/server/internal/db/api/db_data_sync.go b/server/internal/db/api/db_data_sync.go
index 80219287..8e178b74 100644
--- a/server/internal/db/api/db_data_sync.go
+++ b/server/internal/db/api/db_data_sync.go
@@ -66,9 +66,7 @@ func (d *DataSyncTask) DeleteTask(rc *req.Ctx) {
 	for _, v := range ids {
 		value, err := strconv.Atoi(v)
 		biz.ErrIsNilAppendErr(err, "string类型转换为int异常: %s")
-		id := uint64(value)
-		_ = d.DataSyncTaskApp.Delete(rc.MetaCtx, id)
-		_ = d.DataSyncTaskApp.RemoveCronJobById(id)
+		biz.ErrIsNil(d.DataSyncTaskApp.Delete(rc.MetaCtx, uint64(value)))
 	}
 }
 
@@ -76,10 +74,13 @@ func (d *DataSyncTask) ChangeStatus(rc *req.Ctx) {
 	form := &form.DataSyncTaskStatusForm{}
 	task := ginx.BindJsonAndCopyTo[*entity.DataSyncTask](rc.GinCtx, form, new(entity.DataSyncTask))
 	_ = d.DataSyncTaskApp.UpdateById(context.Background(), task)
+
 	if task.Status == entity.DataSyncTaskStatusEnable {
-		_ = d.DataSyncTaskApp.AddCronJobById(task.Id)
+		task, err := d.DataSyncTaskApp.GetById(new(entity.DataSyncTask), task.Id)
+		biz.ErrIsNil(err, "该任务不存在")
+		d.DataSyncTaskApp.AddCronJob(task)
 	} else {
-		_ = d.DataSyncTaskApp.RemoveCronJobById(task.Id)
+		d.DataSyncTaskApp.RemoveCronJobById(task.Id)
 	}
 	// 记录请求日志
 	rc.ReqParam = form
diff --git a/server/internal/db/application/db.go b/server/internal/db/application/db.go
index cd4074bd..53995309 100644
--- a/server/internal/db/application/db.go
+++ b/server/internal/db/application/db.go
@@ -24,7 +24,7 @@ type Db interface {
 
 	Count(condition *entity.DbQuery) int64
 
-	Save(ctx context.Context, entity *entity.Db, tagIds ...uint64) error
+	SaveDb(ctx context.Context, entity *entity.Db, tagIds ...uint64) error
 
 	// 删除数据库信息
 	Delete(ctx context.Context, id uint64) error
@@ -66,7 +66,7 @@ func (d *dbAppImpl) Count(condition *entity.DbQuery) int64 {
 	return d.GetRepo().Count(condition)
 }
 
-func (d *dbAppImpl) Save(ctx context.Context, dbEntity *entity.Db, tagIds ...uint64) error {
+func (d *dbAppImpl) SaveDb(ctx context.Context, dbEntity *entity.Db, tagIds ...uint64) error {
 	// 查找是否存在
 	oldDb := &entity.Db{Name: dbEntity.Name, InstanceId: dbEntity.InstanceId}
 	err := d.GetBy(oldDb)
diff --git a/server/internal/db/application/db_data_sync.go b/server/internal/db/application/db_data_sync.go
index 5fa5345f..a53606a4 100644
--- a/server/internal/db/application/db_data_sync.go
+++ b/server/internal/db/application/db_data_sync.go
@@ -31,13 +31,7 @@ type DataSyncTask interface {
 
 	AddCronJob(taskEntity *entity.DataSyncTask)
 
-	AddCronJobById(id uint64) error
-
-	RemoveCronJob(taskEntity *entity.DataSyncTask)
-
-	RemoveCronJobById(id uint64) error
-
-	RemoveCronJobByKey(taskKey string)
+	RemoveCronJobById(taskId uint64)
 
 	RunCronJob(id uint64) error
 
@@ -62,15 +56,26 @@ func (app *dataSyncAppImpl) GetPageList(condition *entity.DataSyncTaskQuery, pag
 }
 
 func (app *dataSyncAppImpl) Save(ctx context.Context, taskEntity *entity.DataSyncTask) error {
-	app.AddCronJob(taskEntity)
+	var err error
 	if taskEntity.Id == 0 {
-		return app.Insert(ctx, taskEntity)
+		err = app.Insert(ctx, taskEntity)
+	} else {
+		err = app.UpdateById(ctx, taskEntity)
 	}
-	return app.UpdateById(ctx, taskEntity)
+	if err != nil {
+		return err
+	}
+
+	app.AddCronJob(taskEntity)
+	return nil
 }
 
 func (app *dataSyncAppImpl) Delete(ctx context.Context, id uint64) error {
-	return app.DeleteById(ctx, id)
+	if err := app.DeleteById(ctx, id); err != nil {
+		return err
+	}
+	app.RemoveCronJobById(id)
+	return nil
 }
 
 func (app *dataSyncAppImpl) AddCronJob(taskEntity *entity.DataSyncTask) {
@@ -88,31 +93,10 @@ func (app *dataSyncAppImpl) AddCronJob(taskEntity *entity.DataSyncTask) {
 	}
 }
 
-func (app *dataSyncAppImpl) AddCronJobById(id uint64) error {
-	task, err := app.GetById(new(entity.DataSyncTask), id)
-	if err != nil {
-		return err
-	}
-	app.AddCronJob(task)
-	return nil
-}
-
-func (app *dataSyncAppImpl) RemoveCronJob(taskEntity *entity.DataSyncTask) {
-	app.RemoveCronJobByKey(taskEntity.TaskKey)
-}
-
-func (app *dataSyncAppImpl) RemoveCronJobById(id uint64) error {
-	task, err := app.GetById(new(entity.DataSyncTask), id)
-	if err != nil {
-		return err
-	}
-	app.RemoveCronJob(task)
-	return nil
-}
-
-func (app *dataSyncAppImpl) RemoveCronJobByKey(taskKey string) {
-	if taskKey != "" {
-		scheduler.RemoveByKey(taskKey)
+func (app *dataSyncAppImpl) RemoveCronJobById(taskId uint64) {
+	task, err := app.GetById(new(entity.DataSyncTask), taskId)
+	if err == nil {
+		scheduler.RemoveByKey(task.TaskKey)
 	}
 }
 
@@ -148,30 +132,40 @@ func (app *dataSyncAppImpl) RunCronJob(id uint64) error {
 		// 组装查询sql
 		sql := fmt.Sprintf("select * from (%s) t where 1 = 1 %s %s", task.DataSql, updSql, orderSql)
 
-		err = app.doDataSync(sql, task)
+		log, err := app.doDataSync(sql, task)
 		if err != nil {
-			app.endRunning(task, entity.DataSyncTaskStateFail, fmt.Sprintf("执行失败: %s", err.Error()), sql, 0)
+			log.ErrText = fmt.Sprintf("执行失败: %s", err.Error())
+			log.Status = entity.DataSyncTaskStateFail
+			app.endRunning(task, log)
 		}
 	}()
 
 	return nil
 }
 
-func (app *dataSyncAppImpl) doDataSync(sql string, task *entity.DataSyncTask) error {
+func (app *dataSyncAppImpl) doDataSync(sql string, task *entity.DataSyncTask) (*entity.DataSyncLog, error) {
+	now := time.Now()
+	syncLog := &entity.DataSyncLog{
+		TaskId:      task.Id,
+		CreateTime:  &now,
+		DataSqlFull: sql,
+		Status:      entity.DataSyncTaskStateRunning,
+	}
+
 	// 获取源数据库连接
 	srcConn, err := GetDbApp().GetDbConn(uint64(task.SrcDbId), task.SrcDbName)
 	if err != nil {
-		return errorx.NewBiz("连接源数据库失败: %s", err.Error())
+		return syncLog, errorx.NewBiz("连接源数据库失败: %s", err.Error())
 	}
 
 	// 获取目标数据库连接
 	targetConn, err := GetDbApp().GetDbConn(uint64(task.TargetDbId), task.TargetDbName)
 	if err != nil {
-		return errorx.NewBiz("连接目标数据库失败: %s", err.Error())
+		return syncLog, errorx.NewBiz("连接目标数据库失败: %s", err.Error())
 	}
 	targetDbTx, err := targetConn.Begin()
 	if err != nil {
-		return errorx.NewBiz("开启目标数据库事务失败: %s", err.Error())
+		return syncLog, errorx.NewBiz("开启目标数据库事务失败: %s", err.Error())
 	}
 	defer func() {
 		if r := recover(); r != nil {
@@ -188,7 +182,7 @@ func (app *dataSyncAppImpl) doDataSync(sql string, task *entity.DataSyncTask) er
 	var fieldMap []map[string]string
 	err = json.Unmarshal([]byte(task.FieldMap), &fieldMap)
 	if err != nil {
-		return errorx.NewBiz("解析字段映射json出错: %s", err.Error())
+		return syncLog, errorx.NewBiz("解析字段映射json出错: %s", err.Error())
 	}
 	var updFieldType dbm.DataType
 
@@ -218,6 +212,12 @@ func (app *dataSyncAppImpl) doDataSync(sql string, task *entity.DataSyncTask) er
 			if err := app.srcData2TargetDb(result, fieldMap, updFieldType, task, srcDialect, targetDialect, targetDbTx); err != nil {
 				return err
 			}
+
+			// 记录当前已同步的数据量
+			syncLog.ErrText = fmt.Sprintf("本次任务执行中,已同步:%d条", total)
+			syncLog.ResNum = total
+			app.saveLog(syncLog)
+
 			result = result[:0]
 		}
 
@@ -226,25 +226,29 @@ func (app *dataSyncAppImpl) doDataSync(sql string, task *entity.DataSyncTask) er
 
 	if err != nil {
 		targetDbTx.Rollback()
-		return err
+		return syncLog, err
 	}
 
 	// 处理剩余的数据
 	if len(result) > 0 {
 		if err := app.srcData2TargetDb(result, fieldMap, updFieldType, task, srcDialect, targetDialect, targetDbTx); err != nil {
 			targetDbTx.Rollback()
-			return err
+			return syncLog, err
 		}
 	}
 
 	if err := targetDbTx.Commit(); err != nil {
-		return errorx.NewBiz("数据同步-目标数据库事务提交失败: %s", err.Error())
+		return syncLog, errorx.NewBiz("数据同步-目标数据库事务提交失败: %s", err.Error())
 	}
 	logx.Infof("同步任务:[%s],执行完毕,保存记录成功:[%d]条", task.TaskName, total)
 
 	// 保存执行成功日志
-	app.endRunning(task, entity.DataSyncTaskStateSuccess, fmt.Sprintf("本次任务执行成功,新数据:%d 条", total), "", total)
-	return nil
+	syncLog.ErrText = fmt.Sprintf("本次任务执行成功,新数据:%d 条", total)
+	syncLog.Status = entity.DataSyncTaskStateSuccess
+	syncLog.ResNum = total
+	app.endRunning(task, syncLog)
+
+	return syncLog, nil
 }
 
 func (app *dataSyncAppImpl) srcData2TargetDb(srcRes []map[string]any, fieldMap []map[string]string, updFieldType dbm.DataType, task *entity.DataSyncTask, srcDialect dbm.DbDialect, targetDialect dbm.DbDialect, targetDbTx *sql.Tx) error {
@@ -304,9 +308,10 @@ func (app *dataSyncAppImpl) srcData2TargetDb(srcRes []map[string]any, fieldMap [
 	return nil
 }
 
-func (app *dataSyncAppImpl) endRunning(taskEntity *entity.DataSyncTask, state int8, msg string, sql string, resNum int) {
-	logx.Info(msg)
+func (app *dataSyncAppImpl) endRunning(taskEntity *entity.DataSyncTask, log *entity.DataSyncLog) {
+	logx.Info(log.ErrText)
 
+	state := log.Status
 	task := new(entity.DataSyncTask)
 	task.Id = taskEntity.Id
 	task.RecentState = state
@@ -321,19 +326,11 @@ func (app *dataSyncAppImpl) endRunning(taskEntity *entity.DataSyncTask, state in
 	//}
 	_ = app.UpdateById(context.Background(), task)
 	// 保存执行日志
-	app.saveLog(taskEntity.Id, state, msg, sql, resNum)
+	app.saveLog(log)
 }
 
-func (app *dataSyncAppImpl) saveLog(taskId uint64, state int8, msg string, sql string, resNum int) {
-	now := time.Now()
-	_ = app.dataSyncLogRepo.Insert(context.Background(), &entity.DataSyncLog{
-		TaskId:      taskId,
-		CreateTime:  &now,
-		DataSqlFull: sql,
-		ResNum:      resNum,
-		ErrText:     msg,
-		Status:      state,
-	})
+func (app *dataSyncAppImpl) saveLog(log *entity.DataSyncLog) {
+	app.dataSyncLogRepo.Save(context.Background(), log)
 }
 
 func (app *dataSyncAppImpl) InitCronJob() {
diff --git a/server/internal/db/dbm/conn.go b/server/internal/db/dbm/conn.go
index 0b95cb41..ee3b7333 100644
--- a/server/internal/db/dbm/conn.go
+++ b/server/internal/db/dbm/conn.go
@@ -92,11 +92,7 @@ func (d *DbConn) TxExec(tx *sql.Tx, execSql string, args ...any) (int64, error)
 // 执行 update, insert, delete,建表等sql
 // 返回影响条数和错误
 func (d *DbConn) ExecContext(ctx context.Context, execSql string, args ...any) (int64, error) {
-	res, err := d.db.ExecContext(ctx, execSql, args...)
-	if err != nil {
-		return 0, wrapSqlError(err)
-	}
-	return res.RowsAffected()
+	return d.TxExecContext(ctx, nil, execSql, args...)
 }
 
 // 事务执行 update, insert, delete,建表等sql,若tx == nil,则不适用事务
diff --git a/server/internal/db/domain/entity/db_data_sync.go b/server/internal/db/domain/entity/db_data_sync.go
index 3324f731..586bcdfd 100644
--- a/server/internal/db/domain/entity/db_data_sync.go
+++ b/server/internal/db/domain/entity/db_data_sync.go
@@ -56,6 +56,7 @@ const (
 	DataSyncTaskStatusDisable int8 = -1 // 禁用状态
 
 	DataSyncTaskStateSuccess int8 = 1  // 执行成功状态
+	DataSyncTaskStateRunning int8 = 2  // 执行成功状态
 	DataSyncTaskStateFail    int8 = -1 // 执行失败状态
 
 	DataSyncTaskRunStateRunning int8 = 1 // 运行中状态
diff --git a/server/internal/machine/api/machine.go b/server/internal/machine/api/machine.go
index f53721e6..74cc1860 100644
--- a/server/internal/machine/api/machine.go
+++ b/server/internal/machine/api/machine.go
@@ -80,7 +80,7 @@ func (m *Machine) SaveMachine(rc *req.Ctx) {
 	machineForm.Password = "******"
 	rc.ReqParam = machineForm
 
-	biz.ErrIsNil(m.MachineApp.Save(rc.MetaCtx, me, machineForm.TagId...))
+	biz.ErrIsNil(m.MachineApp.SaveMachine(rc.MetaCtx, me, machineForm.TagId...))
 }
 
 func (m *Machine) TestConn(rc *req.Ctx) {
diff --git a/server/internal/machine/api/machine_cronjob.go b/server/internal/machine/api/machine_cronjob.go
index a9080c13..a77cefbc 100644
--- a/server/internal/machine/api/machine_cronjob.go
+++ b/server/internal/machine/api/machine_cronjob.go
@@ -36,7 +36,7 @@ func (m *MachineCronJob) Save(rc *req.Ctx) {
 	mcj := ginx.BindJsonAndCopyTo[*entity.MachineCronJob](rc.GinCtx, jobForm, new(entity.MachineCronJob))
 	rc.ReqParam = jobForm
 
-	cronJobId, err := m.MachineCronJobApp.Save(rc.MetaCtx, mcj)
+	cronJobId, err := m.MachineCronJobApp.SaveMachineCronJob(rc.MetaCtx, mcj)
 	biz.ErrIsNil(err)
 
 	// 关联机器
diff --git a/server/internal/machine/application/machine.go b/server/internal/machine/application/machine.go
index e1c7b716..739d20f2 100644
--- a/server/internal/machine/application/machine.go
+++ b/server/internal/machine/application/machine.go
@@ -23,7 +23,7 @@ import (
 type Machine interface {
 	base.App[*entity.Machine]
 
-	Save(ctx context.Context, m *entity.Machine, tagIds ...uint64) error
+	SaveMachine(ctx context.Context, m *entity.Machine, tagIds ...uint64) error
 
 	// 测试机器连接
 	TestConn(me *entity.Machine) error
@@ -74,7 +74,7 @@ func (m *machineAppImpl) GetMachineList(condition *entity.MachineQuery, pagePara
 	return m.GetRepo().GetMachineList(condition, pageParam, toEntity, orderBy...)
 }
 
-func (m *machineAppImpl) Save(ctx context.Context, me *entity.Machine, tagIds ...uint64) error {
+func (m *machineAppImpl) SaveMachine(ctx context.Context, me *entity.Machine, tagIds ...uint64) error {
 	oldMachine := &entity.Machine{
 		Ip:                 me.Ip,
 		Port:               me.Port,
diff --git a/server/internal/machine/application/machine_cronjob.go b/server/internal/machine/application/machine_cronjob.go
index 50f03af6..d13109dc 100644
--- a/server/internal/machine/application/machine_cronjob.go
+++ b/server/internal/machine/application/machine_cronjob.go
@@ -26,7 +26,7 @@ type MachineCronJob interface {
 	// 获取分页执行结果列表
 	GetExecPageList(condition *entity.MachineCronJobExec, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
 
-	Save(ctx context.Context, entity *entity.MachineCronJob) (uint64, error)
+	SaveMachineCronJob(ctx context.Context, entity *entity.MachineCronJob) (uint64, error)
 
 	Delete(ctx context.Context, id uint64)
 
@@ -84,7 +84,7 @@ func (m *machineCropJobAppImpl) GetExecPageList(condition *entity.MachineCronJob
 }
 
 // 保存机器任务信息
-func (m *machineCropJobAppImpl) Save(ctx context.Context, mcj *entity.MachineCronJob) (uint64, error) {
+func (m *machineCropJobAppImpl) SaveMachineCronJob(ctx context.Context, mcj *entity.MachineCronJob) (uint64, error) {
 	// 更新操作
 	if mcj.Id != 0 {
 		m.UpdateById(ctx, mcj)
diff --git a/server/internal/mongo/api/mongo.go b/server/internal/mongo/api/mongo.go
index da0ccc21..e8311725 100644
--- a/server/internal/mongo/api/mongo.go
+++ b/server/internal/mongo/api/mongo.go
@@ -60,7 +60,7 @@ func (m *Mongo) Save(rc *req.Ctx) {
 	}(form.Uri)
 	rc.ReqParam = form
 
-	biz.ErrIsNil(m.MongoApp.Save(rc.MetaCtx, mongo, form.TagId...))
+	biz.ErrIsNil(m.MongoApp.SaveMongo(rc.MetaCtx, mongo, form.TagId...))
 }
 
 func (m *Mongo) DeleteMongo(rc *req.Ctx) {
diff --git a/server/internal/mongo/application/mongo.go b/server/internal/mongo/application/mongo.go
index f4367537..8c934185 100644
--- a/server/internal/mongo/application/mongo.go
+++ b/server/internal/mongo/application/mongo.go
@@ -21,7 +21,7 @@ type Mongo interface {
 
 	TestConn(entity *entity.Mongo) error
 
-	Save(ctx context.Context, entity *entity.Mongo, tagIds ...uint64) error
+	SaveMongo(ctx context.Context, entity *entity.Mongo, tagIds ...uint64) error
 
 	// 删除数据库信息
 	Delete(ctx context.Context, id uint64) error
@@ -76,7 +76,7 @@ func (d *mongoAppImpl) TestConn(me *entity.Mongo) error {
 	return nil
 }
 
-func (d *mongoAppImpl) Save(ctx context.Context, m *entity.Mongo, tagIds ...uint64) error {
+func (d *mongoAppImpl) SaveMongo(ctx context.Context, m *entity.Mongo, tagIds ...uint64) error {
 	oldMongo := &entity.Mongo{Name: m.Name, SshTunnelMachineId: m.SshTunnelMachineId}
 	err := d.GetBy(oldMongo)
 
diff --git a/server/internal/redis/api/redis.go b/server/internal/redis/api/redis.go
index 84295670..fbd381a0 100644
--- a/server/internal/redis/api/redis.go
+++ b/server/internal/redis/api/redis.go
@@ -69,7 +69,7 @@ func (r *Redis) Save(rc *req.Ctx) {
 	form.Password = "****"
 	rc.ReqParam = form
 
-	biz.ErrIsNil(r.RedisApp.Save(rc.MetaCtx, redis, form.TagId...))
+	biz.ErrIsNil(r.RedisApp.SaveRedis(rc.MetaCtx, redis, form.TagId...))
 }
 
 // 获取redis实例密码,由于数据库是加密存储,故提供该接口展示原文密码
diff --git a/server/internal/redis/application/redis.go b/server/internal/redis/application/redis.go
index c1403a35..3334e501 100644
--- a/server/internal/redis/application/redis.go
+++ b/server/internal/redis/application/redis.go
@@ -24,7 +24,7 @@ type Redis interface {
 	// 测试连接
 	TestConn(re *entity.Redis) error
 
-	Save(ctx context.Context, re *entity.Redis, tagIds ...uint64) error
+	SaveRedis(ctx context.Context, re *entity.Redis, tagIds ...uint64) error
 
 	// 删除数据库信息
 	Delete(ctx context.Context, id uint64) error
@@ -68,7 +68,7 @@ func (r *redisAppImpl) TestConn(re *entity.Redis) error {
 	return nil
 }
 
-func (r *redisAppImpl) Save(ctx context.Context, re *entity.Redis, tagIds ...uint64) error {
+func (r *redisAppImpl) SaveRedis(ctx context.Context, re *entity.Redis, tagIds ...uint64) error {
 	// 查找是否存在该库
 	oldRedis := &entity.Redis{
 		Host:               re.Host,
diff --git a/server/pkg/base/app.go b/server/pkg/base/app.go
index cca4e607..b4305976 100644
--- a/server/pkg/base/app.go
+++ b/server/pkg/base/app.go
@@ -40,6 +40,13 @@ type App[T model.ModelI] interface {
 	// 根据实体条件,更新参数udpateFields指定字段
 	Updates(ctx context.Context, cond any, udpateFields map[string]any) error
 
+	// 保存实体,实体IsCreate返回true则新增,否则更新
+	Save(ctx context.Context, e T) error
+
+	// 保存实体,实体IsCreate返回true则新增,否则更新。
+	// 使用指定gorm db执行,主要用于事务执行
+	SaveWithDb(ctx context.Context, db *gorm.DB, e T) error
+
 	// 根据实体条件删除实体
 	DeleteByCond(ctx context.Context, cond any) error
 
@@ -115,6 +122,17 @@ func (ai *AppImpl[T, R]) Updates(ctx context.Context, cond any, udpateFields map
 	return ai.GetRepo().Updates(cond, udpateFields)
 }
 
+// 保存实体,实体IsCreate返回true则新增,否则更新
+func (ai *AppImpl[T, R]) Save(ctx context.Context, e T) error {
+	return ai.GetRepo().Save(ctx, e)
+}
+
+// 保存实体,实体IsCreate返回true则新增,否则更新。
+// 使用指定gorm db执行,主要用于事务执行
+func (ai *AppImpl[T, R]) SaveWithDb(ctx context.Context, db *gorm.DB, e T) error {
+	return ai.GetRepo().SaveWithDb(ctx, db, e)
+}
+
 // 根据实体主键删除实体 (单纯删除实体,不做其他业务逻辑处理)
 func (ai *AppImpl[T, R]) DeleteById(ctx context.Context, id uint64) error {
 	return ai.GetRepo().DeleteById(ctx, id)
diff --git a/server/pkg/base/repo.go b/server/pkg/base/repo.go
index 81c956f5..3e839269 100644
--- a/server/pkg/base/repo.go
+++ b/server/pkg/base/repo.go
@@ -33,6 +33,13 @@ type Repo[T model.ModelI] interface {
 	// 使用指定gorm db执行,主要用于事务执行
 	UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T, columns ...string) error
 
+	// 保存实体,实体IsCreate返回true则新增,否则更新
+	Save(ctx context.Context, e T) error
+
+	// 保存实体,实体IsCreate返回true则新增,否则更新。
+	// 使用指定gorm db执行,主要用于事务执行
+	SaveWithDb(ctx context.Context, db *gorm.DB, e T) error
+
 	// 根据实体主键删除实体
 	DeleteById(ctx context.Context, id uint64) error
 
@@ -121,11 +128,25 @@ func (br *RepoImpl[T]) Updates(cond any, udpateFields map[string]any) error {
 	return gormx.Updates(br.GetModel(), cond, udpateFields)
 }
 
+func (br *RepoImpl[T]) Save(ctx context.Context, e T) error {
+	if e.IsCreate() {
+		return br.Insert(ctx, e)
+	}
+	return br.UpdateById(ctx, e)
+}
+
+func (br *RepoImpl[T]) SaveWithDb(ctx context.Context, db *gorm.DB, e T) error {
+	if e.IsCreate() {
+		return br.InsertWithDb(ctx, db, e)
+	}
+	return br.UpdateByIdWithDb(ctx, db, e)
+}
+
 func (br *RepoImpl[T]) DeleteById(ctx context.Context, id uint64) error {
 	if db := contextx.GetDb(ctx); db != nil {
 		return br.DeleteByIdWithDb(ctx, db, id)
 	}
-	return gormx.DeleteById(br.getModel(), id)
+	return gormx.DeleteById(br.GetModel(), id)
 }
 
 func (br *RepoImpl[T]) DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error {
@@ -136,7 +157,7 @@ func (br *RepoImpl[T]) DeleteByCond(ctx context.Context, cond any) error {
 	if db := contextx.GetDb(ctx); db != nil {
 		return br.DeleteByCondWithDb(ctx, db, cond)
 	}
-	return gormx.DeleteByCond(br.getModel(), cond)
+	return gormx.DeleteByCond(br.GetModel(), cond)
 }
 
 func (br *RepoImpl[T]) DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error {
@@ -170,19 +191,15 @@ func (br *RepoImpl[T]) CountByCond(cond any) int64 {
 	return gormx.CountByCond(br.GetModel(), cond)
 }
 
-// getModel 获取表的模型实例
-func (br *RepoImpl[T]) getModel() T {
-	return br.M
-}
-
 // GetModel 获取表的模型实例
 func (br *RepoImpl[T]) GetModel() T {
-	return br.getModel()
+	return br.M
 }
 
 // 从上下文获取登录账号信息,并赋值至实体
 func (br *RepoImpl[T]) setBaseInfo(ctx context.Context, e T) T {
 	if la := contextx.GetLoginAccount(ctx); la != nil {
+		// 默认使用数据库id策略, 若要改变则实体结构体自行覆盖SetBaseInfo方法。可参考 sys/entity.Resource
 		e.SetBaseInfo(model.IdGenTypeNone, la)
 	}
 	return e
diff --git a/server/pkg/model/model.go b/server/pkg/model/model.go
index 4cbfdfdf..fc933808 100644
--- a/server/pkg/model/model.go
+++ b/server/pkg/model/model.go
@@ -21,8 +21,8 @@ const (
 // 实体接口
 type ModelI interface {
 
-	// id生成策略
-	// IdGenType() IdGenType
+	// 是否为新建该实体模型, 默认 id == 0 为新建
+	IsCreate() bool
 
 	// 使用当前登录账号信息设置实体结构体的基础信息
 	//
@@ -34,14 +34,13 @@ type IdModel struct {
 	Id uint64 `json:"id"`
 }
 
-// func (m *IdModel) IdGenType() IdGenType {
-// 	// 默认由数据库自行生成
-// 	return IdGenTypeNone
-// }
+func (m *IdModel) IsCreate() bool {
+	return m.Id == 0
+}
 
 func (m *IdModel) SetBaseInfo(idGenType IdGenType, account *LoginAccount) {
 	// 存在id,则赋值
-	if m.Id != 0 {
+	if !m.IsCreate() {
 		return
 	}
 	m.Id = GetIdByGenType(idGenType)
@@ -70,7 +69,7 @@ type CreateModel struct {
 }
 
 func (m *CreateModel) SetBaseInfo(idGenType IdGenType, account *LoginAccount) {
-	if m.Id != 0 {
+	if !m.IsCreate() {
 		return
 	}
 
@@ -98,7 +97,7 @@ type Model struct {
 // 设置基础信息. 如创建时间,修改时间,创建者,修改者信息
 func (m *Model) SetBaseInfo(idGenType IdGenType, account *LoginAccount) {
 	nowTime := time.Now()
-	isCreate := m.Id == 0
+	isCreate := m.IsCreate()
 	if isCreate {
 		m.IsDeleted = ModelUndeleted
 		m.CreateTime = &nowTime