package system import ( "context" "reflect" "github.com/perfect-panel/server/initialize" "github.com/perfect-panel/server/internal/config" "github.com/perfect-panel/server/internal/model/system" "github.com/perfect-panel/server/pkg/logger" "github.com/perfect-panel/server/pkg/tool" "github.com/perfect-panel/server/pkg/xerr" "github.com/pkg/errors" "gorm.io/gorm" "github.com/perfect-panel/server/internal/svc" "github.com/perfect-panel/server/internal/types" ) type UpdateInviteConfigLogic struct { logger.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewUpdateInviteConfigLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateInviteConfigLogic { return &UpdateInviteConfigLogic{ Logger: logger.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *UpdateInviteConfigLogic) UpdateInviteConfig(req *types.InviteConfig) error { v := reflect.ValueOf(*req) // Get the reflection type of the structure t := v.Type() err := l.svcCtx.SystemModel.Transaction(l.ctx, func(db *gorm.DB) error { var err error for i := 0; i < v.NumField(); i++ { // Get the field name fieldName := t.Field(i).Name // Get the field value to string fieldValue := tool.ConvertValueToString(v.Field(i)) // Update existing row; if missing (RowsAffected=0), create it to avoid silent config loss. updateResult := db.Model(&system.System{}). Where("`category` = 'invite' and `key` = ?", fieldName). Update("value", fieldValue) err = updateResult.Error if err != nil { break } if updateResult.RowsAffected == 0 { err = db.Create(&system.System{ Category: "invite", Key: fieldName, Value: fieldValue, Type: getSystemFieldType(v.Field(i)), Desc: "invite config: " + fieldName, }).Error if err != nil { break } } } if err != nil { return err } // clear cache return l.svcCtx.Redis.Del(l.ctx, config.InviteConfigKey, config.GlobalConfigKey).Err() }) if err != nil { l.Errorw("[UpdateInviteConfig] update invite config error", logger.Field("error", err.Error())) return errors.Wrapf(xerr.NewErrCode(xerr.DatabaseUpdateError), "update invite config error: %v", err) } initialize.Invite(l.svcCtx) return nil } func getSystemFieldType(field reflect.Value) string { kind := field.Kind() if kind == reflect.Ptr && !field.IsNil() { kind = field.Elem().Kind() } switch kind { case reflect.Bool: return "bool" case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: return "int" case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: return "uint" case reflect.Float32, reflect.Float64: return "float" case reflect.String: return "string" default: return "string" } }