mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
refactor: 数据同步优化, base.App、base.Repo新增Save方法
This commit is contained in:
@@ -4,13 +4,9 @@
|
||||
<template #header>
|
||||
<span class="mr10">任务执行日志</span>
|
||||
<el-switch v-model="realTime" @change="watchPolling" inline-prompt active-text="实时" inactive-text="非实时" />
|
||||
<span v-if="realTime" v-loading="true"></span>
|
||||
<el-button @click="search" icon="Refresh" circle size="small" :loading="realTime" class="ml10"></el-button>
|
||||
</template>
|
||||
<page-table ref="logTableRef" :page-api="dbApi.datasyncLogs" v-model:query-form="query" :tool-button="false" :columns="columns" size="small">
|
||||
<template #status="{ data }">
|
||||
<el-tag v-if="data.status == 1" class="ml-2" type="success">成功</el-tag>
|
||||
<el-tag v-else-if="data.status == -1" class="ml-2" type="danger">失败</el-tag>
|
||||
</template>
|
||||
</page-table>
|
||||
</el-dialog>
|
||||
</div>
|
||||
@@ -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<boolean>('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(),
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,则不适用事务
|
||||
|
||||
@@ -56,6 +56,7 @@ const (
|
||||
DataSyncTaskStatusDisable int8 = -1 // 禁用状态
|
||||
|
||||
DataSyncTaskStateSuccess int8 = 1 // 执行成功状态
|
||||
DataSyncTaskStateRunning int8 = 2 // 执行成功状态
|
||||
DataSyncTaskStateFail int8 = -1 // 执行失败状态
|
||||
|
||||
DataSyncTaskRunStateRunning int8 = 1 // 运行中状态
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
// 关联机器
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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实例密码,由于数据库是加密存储,故提供该接口展示原文密码
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user