package one2one import ( "git.sxidc.com/go-framework/baize/convenient/binding" "git.sxidc.com/go-framework/baize/convenient/binding/request" "git.sxidc.com/go-framework/baize/framwork/api" "git.sxidc.com/go-framework/baize/framwork/domain" "git.sxidc.com/go-framework/baize/framwork/infrastructure" "git.sxidc.com/go-framework/baize/framwork/infrastructure/database" "git.sxidc.com/go-framework/baize/framwork/infrastructure/database/sql" "git.sxidc.com/go-tools/utils/strutils" "git.sxidc.com/service-supports/fserr" "reflect" ) func Update(fromTableName string, fromRelationFieldName string, fromRelationColumnName string, toTableName string, toDomainCNName string, toRelationColumnName string) binding.ServiceFunc[any] { return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (any, error) { object := objects[0] if object == nil { return nil, fserr.New("领域实体为空") } dbExecutor := i.DBExecutor() fromEntity, ok := object.(domain.Entity) if !ok { return nil, fserr.New("领域对象不是实体") } // 字段校验 err := fromEntity.CheckFieldID(fromEntity.DomainCNName()) if err != nil { return nil, err } if !domain.HasField(object, fromRelationFieldName) { return nil, fserr.New("关联字段" + fromRelationFieldName + "不存在") } // from存在性校验 fromResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: fromTableName, Conditions: sql.NewConditions().Equal(domain.ColumnID, fromEntity.GetID()), }) if err != nil { if database.IsErrorDBRecordNotExist(err) { return nil, fserr.New(fromEntity.DomainCNName() + "不存在") } return nil, err } existFrom := reflect.New(reflect.TypeOf(object).Elem()).Interface() err = sql.ParseSqlResult(fromResult, existFrom) if err != nil { return nil, err } currentToID, err := domain.Field[string](existFrom, fromRelationFieldName) if err != nil { return nil, err } newToID, err := domain.Field[string](object, fromRelationFieldName) if err != nil { return nil, err } if strutils.IsStringNotEmpty(newToID) { // to存在性校验 toExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{ TableName: toTableName, Conditions: sql.NewConditions().Equal(domain.ColumnID, newToID), }) if err != nil { return nil, err } if !toExist { return nil, fserr.New(fromEntity.DomainCNName() + "关联的" + toDomainCNName + "不存在") } } err = database.Transaction(dbExecutor, func(tx database.Executor) error { if strutils.IsStringNotEmpty(fromTableName) { err := database.Update(tx, &sql.UpdateExecuteParams{ TableName: fromTableName, TableRow: sql.NewTableRow().Add(fromRelationColumnName, newToID), Conditions: sql.NewConditions().Equal(domain.ColumnID, fromEntity.GetID()), }) if err != nil { return err } } if strutils.IsStringNotEmpty(toTableName) && (strutils.IsStringNotEmpty(currentToID) || strutils.IsStringNotEmpty(newToID)) { familyID := fromEntity.GetID() if strutils.IsStringEmpty(newToID) { familyID = "" } updateToID := currentToID if strutils.IsStringEmpty(currentToID) { updateToID = newToID } err := database.Update(tx, &sql.UpdateExecuteParams{ TableName: toTableName, TableRow: sql.NewTableRow().Add(toRelationColumnName, familyID), Conditions: sql.NewConditions().Equal(domain.ColumnID, updateToID), }) if err != nil { return err } } return nil }) if err != nil { return nil, err } return nil, nil } } func Query[TI any](fromTableName string, toTableName string, toRelationColumnName string) binding.ServiceFunc[TI] { return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (TI, error) { var outputZero TI outputZeroValue := reflect.New(reflect.TypeOf(outputZero)).Elem() if outputZeroValue.Kind() == reflect.Pointer { outputZeroValue.Set(reflect.New(outputZeroValue.Type().Elem())) } outputZero = outputZeroValue.Interface().(TI) dbExecutor := i.DBExecutor() object := objects[0] if object == nil { return outputZero, fserr.New("领域实体为空") } fromEntity, ok := object.(domain.Entity) if !ok { return outputZero, fserr.New("领域对象不是实体") } // from存在性校验 fromResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: fromTableName, Conditions: sql.NewConditions().Equal(domain.ColumnID, fromEntity.GetID()), }) if err != nil { if database.IsErrorDBRecordNotExist(err) { return outputZero, fserr.New(fromEntity.DomainCNName() + "不存在") } return outputZero, err } existFrom := reflect.New(reflect.TypeOf(object).Elem()).Interface() err = sql.ParseSqlResult(fromResult, existFrom) if err != nil { return outputZero, err } existFromEntity := existFrom.(domain.Entity) toResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: toTableName, Conditions: sql.NewConditions().Equal(toRelationColumnName, existFromEntity.GetID()), }) if err != nil { return outputZero, err } var info TI var infoPointer any infoPointer = &info if outputZeroValue.Kind() == reflect.Pointer { infoPointer = info } err = sql.ParseSqlResult(toResult, infoPointer) if err != nil { return outputZero, err } return info, nil } } func QueryWithOtherInfo[FI any, TI any](fromTableName string, toTableName string, toRelationColumnName string) binding.ServiceFunc[map[string]any] { return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (map[string]any, error) { var outputFromZero FI var outputToZero TI outputFromZeroValue := reflect.New(reflect.TypeOf(outputFromZero)).Elem() if outputFromZeroValue.Kind() == reflect.Pointer { outputFromZeroValue.Set(reflect.New(outputFromZeroValue.Type().Elem())) } outputFromZero = outputFromZeroValue.Interface().(FI) outputToZeroValue := reflect.New(reflect.TypeOf(outputToZero)).Elem() if outputToZeroValue.Kind() == reflect.Pointer { outputToZeroValue.Set(reflect.New(outputToZeroValue.Type().Elem())) } outputToZero = outputToZeroValue.Interface().(TI) zeroRetMap := map[string]any{ "self": outputFromZero, "with": outputToZero, } dbExecutor := i.DBExecutor() object := objects[0] if object == nil { return zeroRetMap, fserr.New("领域实体为空") } fromEntity, ok := object.(domain.Entity) if !ok { return zeroRetMap, fserr.New("领域对象不是实体") } // from存在性校验 fromResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: fromTableName, Conditions: sql.NewConditions().Equal(domain.ColumnID, fromEntity.GetID()), }) if err != nil { if database.IsErrorDBRecordNotExist(err) { return zeroRetMap, fserr.New(fromEntity.DomainCNName() + "不存在") } return zeroRetMap, err } existFrom := reflect.New(reflect.TypeOf(object).Elem()).Interface() err = sql.ParseSqlResult(fromResult, existFrom) if err != nil { return zeroRetMap, err } existFromEntity := existFrom.(domain.Entity) toResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: toTableName, Conditions: sql.NewConditions().Equal(toRelationColumnName, existFromEntity.GetID()), }) if err != nil { return zeroRetMap, err } var fromInfo FI var fromInfoPointer any fromInfoPointer = &fromInfo if outputFromZeroValue.Kind() == reflect.Pointer { fromInfoPointer = fromInfo } err = sql.ParseSqlResult(fromResult, fromInfoPointer) if err != nil { return zeroRetMap, err } var toInfo TI var toInfoPointer any toInfoPointer = &toInfo if outputToZeroValue.Kind() == reflect.Pointer { toInfoPointer = toInfo } err = sql.ParseSqlResult(toResult, toInfoPointer) if err != nil { return zeroRetMap, err } return map[string]any{ "self": fromInfo, "with": toInfo, }, nil } }