package value_object_crud 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/value_object" "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-framework/baize/framework/core/tag/sql/sql_mapping" "github.com/pkg/errors" "reflect" ) func Create(tableName string, callbacks *CreateCallbacks) 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() valueObject, ok := objects[0].(value_object.ValueObject) if !ok { return nil, errors.New("需要传递领域对象应该为值对象") } prepared, err := callbackPrepareCreate(callbacks, c, params, valueObject, i) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = domain.CheckFieldsForCreate(valueObject, valueObject.GetFieldMap()) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = callbackBeforeCreate(callbacks, c, params, valueObject, prepared, i, nil) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, prepared, err, i) } err = database.InsertEntity(dbExecutor, tableName, valueObject) if err != nil { if database.IsErrorDBRecordHasExist(err) { err = errors.New(valueObject.DomainCNName() + "已存在") } return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, prepared, err, i) } err = callbackAfterCreate(callbacks, c, params, valueObject, prepared, i, nil) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, prepared, err, i) } return nil, callbackOnCreateSuccessReturn(callbacks, c, params, valueObject, prepared, i) } } func Delete(tableName string, callbacks *DeleteCallbacks) 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() valueObject, ok := objects[0].(value_object.ValueObject) if !ok { return nil, errors.New("需要传递领域对象应该为值对象") } prepared, err := callbackPrepareDelete(callbacks, c, params, valueObject, i) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = domain.CheckFieldsForDelete(valueObject, valueObject.GetFieldMap()) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = callbackBeforeDelete(callbacks, c, params, valueObject, prepared, i, nil) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = database.DeleteEntity(dbExecutor, tableName, valueObject) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = callbackAfterDelete(callbacks, c, params, valueObject, prepared, i, nil) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } return nil, callbackOnDeleteSuccessReturn(callbacks, c, params, valueObject, prepared, i) } } type ConditionFieldCallback func(conditions *sql.Conditions, fieldName string, columnName string, value any) (hasDeal bool, err error) type CustomCondition struct { Conditions *sql.Conditions OrderBy string } type FormCustomConditionFunc func(c *api.Context, params request.Params, valueObject value_object.ValueObject) (*CustomCondition, error) func Query[O any](tableName string, orderBy string, callbacks *QueryCallbacks[O], conditionFieldCallback ConditionFieldCallback, formCustomConditionFunc FormCustomConditionFunc) binding.ServiceFunc[response.InfosData[O]] { return func(c *api.Context, params request.Params, objects []domain.Object, i *infrastructure.Infrastructure) (response.InfosData[O], error) { errResponse := response.InfosData[O]{ Infos: make([]O, 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.QueryRequestParams) if !ok { return errResponse, errors.New("请求参数不是Query接口") } valueObject, ok := objects[0].(value_object.ValueObject) if !ok { return errResponse, errors.New("需要传递领域对象应该为值对象") } conditions := sql.NewConditions() fields, err := sql_mapping.DefaultUsage(valueObject) if err != nil { return errResponse, err } if formCustomConditionFunc == nil { for _, field := range fields { hasDeal := false if conditionFieldCallback != nil { hasDeal, err = conditionFieldCallback(conditions, field.FieldName, field.ColumnName, field.Value) if err != nil { return errResponse, err } } if !hasDeal { fieldValue := reflect.ValueOf(field.Value) if !fieldValue.IsZero() { conditions.Equal(field.ColumnName, field.Value) } } } } else { customCondition, err := formCustomConditionFunc(c, queryParams, valueObject) if err != nil { return errResponse, err } conditions = customCondition.Conditions orderBy = customCondition.OrderBy } err = callbackBeforeQuery(callbacks, c, params, valueObject, i) if err != nil { return callbackOnQueryErrorReturn(callbacks, c, params, valueObject, err, i) } results, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{ TableName: tableName, Conditions: conditions, OrderBy: orderBy, PageNo: queryParams.GetPageNo(), PageSize: queryParams.GetPageSize(), }) if err != nil { return callbackOnQueryErrorReturn(callbacks, c, params, valueObject, err, i) } err = callbackAfterQuery(callbacks, c, params, valueObject, i) if err != nil { return callbackOnQueryErrorReturn(callbacks, c, params, valueObject, err, i) } infos := make([]O, 0) err = sql.ParseSqlResult(results, &infos) if err != nil { return callbackOnQueryErrorReturn(callbacks, c, params, valueObject, err, i) } output := response.InfosData[O]{ Infos: infos, TotalCount: totalCount, PageNo: queryParams.GetPageNo(), } return callbackOnQuerySuccessReturn(callbacks, c, params, valueObject, i, output) } } func CreateTx(tableName string, callbacks *CreateCallbacks) 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() valueObject, ok := objects[0].(value_object.ValueObject) if !ok { return nil, errors.New("需要传递领域对象应该为值对象") } prepared, err := callbackPrepareCreate(callbacks, c, params, valueObject, i) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = domain.CheckFieldsForCreate(valueObject, valueObject.GetFieldMap()) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = database.Transaction(dbExecutor, func(tx database.Executor) error { err := callbackBeforeCreate(callbacks, c, params, valueObject, prepared, i, tx) if err != nil { return err } err = database.InsertEntity(tx, tableName, valueObject) if err != nil { if database.IsErrorDBRecordHasExist(err) { err = errors.New(valueObject.DomainCNName() + "已存在") } return err } err = callbackAfterCreate(callbacks, c, params, valueObject, prepared, i, tx) if err != nil { return err } return nil }) if err != nil { return nil, callbackOnCreateErrorReturn(callbacks, c, params, valueObject, prepared, err, i) } return nil, callbackOnCreateSuccessReturn(callbacks, c, params, valueObject, prepared, i) } } func DeleteTx(tableName string, callbacks *DeleteCallbacks) 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() valueObject, ok := objects[0].(value_object.ValueObject) if !ok { return nil, errors.New("需要传递领域对象应该为值对象") } prepared, err := callbackPrepareDelete(callbacks, c, params, valueObject, i) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = domain.CheckFieldsForDelete(valueObject, valueObject.GetFieldMap()) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, make(map[string]any), err, i) } err = database.Transaction(dbExecutor, func(tx database.Executor) error { err = callbackBeforeDelete(callbacks, c, params, valueObject, prepared, i, tx) if err != nil { return err } err = database.DeleteEntity(tx, tableName, valueObject) if err != nil { return err } err = callbackAfterDelete(callbacks, c, params, valueObject, prepared, i, tx) if err != nil { return err } return nil }) if err != nil { return nil, callbackOnDeleteErrorReturn(callbacks, c, params, valueObject, prepared, err, i) } return nil, callbackOnDeleteSuccessReturn(callbacks, c, params, valueObject, prepared, i) } }