package many2many import ( "git.sxidc.com/go-framework/baize/framework/binding" "git.sxidc.com/go-framework/baize/framework/core/api" "git.sxidc.com/go-framework/baize/framework/core/api/request" "git.sxidc.com/go-framework/baize/framework/core/api/response" "git.sxidc.com/go-framework/baize/framework/core/domain" "git.sxidc.com/go-framework/baize/framework/core/domain/entity" "git.sxidc.com/go-framework/baize/framework/core/infrastructure" "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database" "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql" "git.sxidc.com/go-tools/utils/slice" "github.com/pkg/errors" ) func Update(middleTableName string, fromTableName string, fromDomainCNName string, fromRelationFieldName string, fromRelationColumnName string, toTableName 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, errors.New("领域实体为空") } dbExecutor := i.DBExecutor() fromEntity, ok := object.(entity.Entity) if !ok { return nil, errors.New("领域对象不是实体") } // 字段校验 err := domain.CheckField(fromEntity, entity.FieldID, fromEntity.GetFieldMap()) if err != nil { return nil, err } // from存在性校验 fromExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{ TableName: fromTableName, Conditions: sql.NewConditions().Equal(entity.ColumnID, fromEntity.GetID()), }) if err != nil { return nil, err } if !fromExist { return nil, errors.New(fromEntity.DomainCNName() + "不存在") } if !domain.HasField(object, fromRelationFieldName) { return nil, errors.New("关联字段" + fromRelationFieldName + "不存在") } toIDs, err := domain.Field[[]string](object, fromRelationFieldName) if err != nil { return nil, err } if toIDs != nil && len(toIDs) != 0 { for _, toID := range toIDs { err := entity.CheckIDTypeValue(fromDomainCNName, fromRelationFieldName, toID) if err != nil { return nil, err } } toIDs = slice.RemoveRepeatElement(toIDs) } err = database.Transaction(dbExecutor, func(tx database.Executor) error { err := database.Delete(tx, &sql.DeleteExecuteParams{ TableName: middleTableName, Conditions: sql.NewConditions().Equal(fromRelationColumnName, fromEntity.GetID()), }) if err != nil { return err } if toIDs == nil || len(toIDs) == 0 { return nil } toCount, err := database.Count(dbExecutor, &sql.CountExecuteParams{ TableName: toTableName, Conditions: sql.NewConditions().In(entity.ColumnID, toIDs), }) if err != nil { return err } if int(toCount) != len(toIDs) { return errors.New("部分{{ $toCNName }}不存在") } tableRows := make([]sql.TableRow, len(toIDs)) for index, toID := range toIDs { tableRows[index] = *(sql.NewTableRow(). Add(fromRelationColumnName, fromEntity.GetID()). Add(toRelationColumnName, toID)) } err = database.InsertBatch(tx, &sql.InsertBatchExecuteParams{ TableName: middleTableName, TableRowBatch: tableRows, }) if err != nil { if database.IsErrorDBRecordHasExist(err) { return errors.New("关联项已存在") } return err } return nil }) if err != nil { return nil, err } return nil, nil } } func Query[TI any](middleTableName string, fromTableName string, fromRelationColumnName string, toTableName string, toRelationColumnName string) binding.ServiceFunc[response.InfosData[TI]] { return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[TI], error) { errResponse := response.InfosData[TI]{ Infos: make([]TI, 0), } if params == nil { return errResponse, errors.New("请求参数为空") } object := objects[0] if object == nil { return errResponse, errors.New("领域实体为空") } dbExecutor := i.DBExecutor() queryParams, ok := params.(request.QueryWithIDRequestParams) if !ok { return errResponse, errors.New("请求参数不是Query接口") } fromEntity, ok := object.(entity.Entity) if !ok { return errResponse, errors.New("领域对象不是实体") } // from存在性校验 fromExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{ TableName: fromTableName, Conditions: sql.NewConditions().Equal(entity.ColumnID, fromEntity.GetID()), }) if err != nil { return errResponse, err } if !fromExist { return errResponse, errors.New(fromEntity.DomainCNName() + "不存在") } toIDResults, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{ TableName: middleTableName, SelectClauses: []string{toRelationColumnName}, Conditions: sql.NewConditions().Equal(fromRelationColumnName, fromEntity.GetID()), PageNo: queryParams.GetPageNo(), PageSize: queryParams.GetPageSize(), }) if err != nil { return errResponse, err } if toIDResults == nil || len(toIDResults) == 0 { return response.InfosData[TI]{ Infos: make([]TI, 0), TotalCount: 0, PageNo: queryParams.GetPageNo(), }, nil } toIDs := make([]string, 0) err = sql.ParseSqlResult(toIDResults, &toIDs) if err != nil { return errResponse, err } toResults, _, err := database.Query(dbExecutor, &sql.QueryExecuteParams{ TableName: toTableName, Conditions: sql.NewConditions().In(entity.ColumnID, toIDs), }) if err != nil { return errResponse, err } infos := make([]TI, 0) err = sql.ParseSqlResult(toResults, &infos) if err != nil { return errResponse, err } return response.InfosData[TI]{ Infos: infos, TotalCount: totalCount, PageNo: queryParams.GetPageNo(), }, nil } }