github.com/SupenBysz/gf-admin-community@v0.7.4/internal/logic/sys_invite/sys_invite.go (about)

     1  package sys_invite
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"fmt"
     7  	"github.com/SupenBysz/gf-admin-community/sys_consts"
     8  	"github.com/SupenBysz/gf-admin-community/sys_model"
     9  	"github.com/SupenBysz/gf-admin-community/sys_model/sys_dao"
    10  	"github.com/SupenBysz/gf-admin-community/sys_model/sys_do"
    11  	"github.com/SupenBysz/gf-admin-community/sys_model/sys_enum"
    12  	"github.com/SupenBysz/gf-admin-community/sys_model/sys_hook"
    13  	"github.com/SupenBysz/gf-admin-community/sys_service"
    14  	"github.com/SupenBysz/gf-admin-community/utility/invite_id"
    15  	"github.com/gogf/gf/v2/database/gdb"
    16  	"github.com/gogf/gf/v2/frame/g"
    17  	"github.com/gogf/gf/v2/os/gtime"
    18  	"github.com/gogf/gf/v2/util/gconv"
    19  	"github.com/kysion/base-library/base_hook"
    20  	"github.com/kysion/base-library/base_model"
    21  	"github.com/kysion/base-library/utility/daoctl"
    22  	"github.com/yitter/idgenerator-go/idgen"
    23  )
    24  
    25  // 邀约
    26  
    27  type sSysInvite struct {
    28  
    29  	// 关注邀约状态的Hook订阅
    30  	InviteStateHook base_hook.BaseHook[sys_enum.InviteState, sys_hook.InviteStateHookFunc]
    31  }
    32  
    33  func init() {
    34  	sys_service.RegisterSysInvite(New())
    35  }
    36  
    37  func New() sys_service.ISysInvite {
    38  	return &sSysInvite{}
    39  }
    40  
    41  func (s *sSysInvite) InstallInviteStateHook(actionType sys_enum.InviteState, hookFunc sys_hook.InviteStateHookFunc) {
    42  	s.InviteStateHook.InstallHook(actionType, hookFunc)
    43  }
    44  
    45  // GetInviteById 根据id获取邀约
    46  func (s *sSysInvite) GetInviteById(ctx context.Context, id int64) (*sys_model.InviteRes, error) {
    47  
    48  	result, err := daoctl.GetByIdWithError[sys_model.InviteRes](sys_dao.SysInvite.Ctx(ctx), id)
    49  
    50  	if err != nil {
    51  		return nil, sys_service.SysLogs().ErrorSimple(ctx, err, "根据id查询邀约信息失败", sys_dao.SysInvite.Table())
    52  	}
    53  
    54  	fmt.Println("渲染前:", result.Value)
    55  
    56  	// 业务层  Hook处理渲染,如果没有Hook的话,那就直接格式化成默认的邀约信息
    57  	//for _, hook := range s.hookArr {
    58  	//	// 判断注入的Hook业务类型是否一致
    59  	//	if (hook.Value.Category & result.Category) == result.Category { // 如果业务层没有订阅数据处理,那么就默认渲染成基础骨架里面的邀约信息
    60  	//		//if hook.Key == sys_enum.Invite.Event.GetInviteData {}
    61  	//		// 业务类型一致则调用注入的Hook函数
    62  	//		err = hook.Value.Value(ctx, sys_enum.Invite.Event.GetInviteData, result)
    63  	//	}
    64  	//
    65  	//	gerror.NewCode(gcode.CodeInvalidConfiguration, "")
    66  	//	if err != nil {
    67  	//		return nil
    68  	//	}
    69  	//}
    70  	//fmt.Println("渲染后:", result.Value)
    71  
    72  	result.Code = invite_id.InviteIdToCode(result.Id)
    73  
    74  	return result, nil
    75  }
    76  
    77  // QueryInviteList 查询邀约|列表
    78  func (s *sSysInvite) QueryInviteList(ctx context.Context, filter *base_model.SearchParams) (*sys_model.InviteListRes, error) {
    79  
    80  	filter.Filter = append(filter.Filter, base_model.FilterInfo{
    81  		Field:       sys_dao.SysInvite.Columns().Id,
    82  		Where:       ">",
    83  		IsOrWhere:   false,
    84  		Value:       0,
    85  		IsNullValue: false,
    86  	})
    87  
    88  	result, err := daoctl.Query[sys_model.InviteRes](sys_dao.SysInvite.Ctx(ctx), filter, true)
    89  
    90  	newList := make([]sys_model.InviteRes, 0)
    91  	for _, item := range result.Records {
    92  		item.Code = invite_id.InviteIdToCode(item.Id)
    93  
    94  		newList = append(newList, item)
    95  	}
    96  
    97  	if len(newList) > 0 {
    98  		result.Records = newList
    99  	}
   100  
   101  	return (*sys_model.InviteListRes)(result), err
   102  }
   103  
   104  // CreateInvite 创建邀约信息
   105  func (s *sSysInvite) CreateInvite(ctx context.Context, info *sys_model.Invite) (*sys_model.InviteRes, error) {
   106  	// 判断userId是否存在
   107  	_, err := sys_service.SysUser().GetSysUserById(ctx, info.UserId)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  
   112  	// 判断该类型&该用户,是否已存在邀约码
   113  	invite, err := daoctl.ScanWithError[sys_model.InviteRes](sys_dao.SysInvite.Ctx(ctx).Where(sys_do.SysInvite{UserId: info.UserId, Type: info.Type}))
   114  	if invite != nil && invite.Id != 0 {
   115  		return invite, nil
   116  	}
   117  
   118  	data := sys_do.SysInvite{}
   119  	gconv.Struct(info, &data)
   120  	// 过期时间和激活上限次数从配置加载
   121  	data.ExpireAt = gtime.Now().AddDate(0, 0, sys_consts.Global.InviteCodeExpireDay) // 过期时间
   122  	data.ActivateNumber = sys_consts.Global.InviteCodeMaxActivateNumber              //
   123  
   124  	id := idgen.NextId()
   125  
   126  	if sys_consts.Global.InviteCodeExpireDay == 0 {
   127  		data.ExpireAt = nil
   128  	}
   129  	if info.Value == "" {
   130  		data.Value = nil
   131  	}
   132  
   133  	err = sys_dao.SysInvite.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
   134  		data.Id = id
   135  
   136  		data.CreatedAt = gtime.Now()
   137  		affected, err := daoctl.InsertWithError(sys_dao.SysInvite.Ctx(ctx).OmitNilData().Data(data))
   138  		if err != nil || affected <= 0 {
   139  			return sys_service.SysLogs().ErrorSimple(ctx, err, "创建邀约信息失败", sys_dao.SysInvite.Table())
   140  		}
   141  
   142  		return nil
   143  	})
   144  
   145  	if err != nil {
   146  		return nil, err
   147  	}
   148  
   149  	return s.GetInviteById(ctx, gconv.Int64(data.Id))
   150  }
   151  
   152  // DeleteInvite 删除邀约信息
   153  func (s *sSysInvite) DeleteInvite(ctx context.Context, inviteId int64) (bool, error) {
   154  	info, err := s.GetInviteById(ctx, inviteId)
   155  	if err != nil {
   156  		return false, err
   157  	}
   158  
   159  	if info != nil {
   160  		_, err := daoctl.DeleteWithError(sys_dao.SysInvite.Ctx(ctx).Where(sys_do.SysInvite{
   161  			Id: info.Id,
   162  		}))
   163  
   164  		if err != nil {
   165  			return false, sys_service.SysLogs().ErrorSimple(ctx, err, "删除邀约信息失败", sys_dao.SysInvite.Table())
   166  		}
   167  	}
   168  
   169  	return true, nil
   170  }
   171  
   172  // SetInviteState 修改邀约信息状态
   173  func (s *sSysInvite) SetInviteState(ctx context.Context, id int64, state int) (bool, error) {
   174  
   175  	info, _ := s.GetInviteById(ctx, id)
   176  	if info == nil {
   177  		return false, sys_service.SysLogs().ErrorSimple(ctx, nil, "ID参数错误", sys_dao.SysInvite.Table())
   178  	}
   179  
   180  	// 需要排除无上限次数和过期时间的情况
   181  	if sys_consts.Global.InviteCodeExpireDay == 0 && sys_consts.Global.InviteCodeMaxActivateNumber == 0 {
   182  		return true, nil
   183  	}
   184  
   185  	err := sys_dao.SysInvite.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
   186  		_, err := sys_dao.SysInvite.Ctx(ctx).OmitNilData().Data(sys_do.SysInvite{
   187  			State: state,
   188  		}).Where(sys_do.SysInvite{
   189  			Id: info.Id,
   190  		}).Update()
   191  
   192  		if err != nil {
   193  			return sys_service.SysLogs().ErrorSimple(ctx, nil, "邀约信息状态修改失败", sys_dao.SysInvite.Table())
   194  		}
   195  
   196  		newData, _ := s.GetInviteById(ctx, info.Id)
   197  		if newData == nil {
   198  			return sys_service.SysLogs().ErrorSimple(ctx, nil, "获取邀约信息失败", sys_dao.SysInvite.Table())
   199  		}
   200  
   201  		// TODO 业务层订阅 , Hook
   202  		s.InviteStateHook.Iterator(func(key sys_enum.InviteState, value sys_hook.InviteStateHookFunc) {
   203  			// 判断注入的Hook业务类型是否一致
   204  			if key.Code()&newData.State == newData.State {
   205  				// 业务类型一致则调用注入的Hook函数
   206  				g.Try(ctx, func(ctx context.Context) {
   207  					err = value(ctx, sys_enum.Invite.State.New(newData.State, ""), newData)
   208  				})
   209  			}
   210  		})
   211  
   212  		return nil
   213  	})
   214  
   215  	return err == nil, err
   216  }
   217  
   218  // SetInviteNumber 修改邀约剩余次数
   219  func (s *sSysInvite) SetInviteNumber(ctx context.Context, id int64, num int, isAdd bool) (res bool, err error) {
   220  
   221  	info, _ := s.GetInviteById(ctx, id)
   222  	if info == nil {
   223  		return false, sys_service.SysLogs().ErrorSimple(ctx, nil, "ID参数错误", sys_dao.SysInvite.Table())
   224  	}
   225  
   226  	// 需要排除无上限次数的情况
   227  	if sys_consts.Global.InviteCodeMaxActivateNumber == 0 && info.ActivateNumber == 0 {
   228  		return true, nil
   229  	}
   230  
   231  	err = sys_dao.SysInvite.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
   232  		var result sql.Result
   233  		daoModel := sys_dao.SysInvite.Ctx(ctx).Where(sys_do.SysInvite{Id: id})
   234  
   235  		if !isAdd {
   236  			result, err = daoModel.Decrement(sys_dao.SysInvite.Columns().ActivateNumber, num)
   237  		} else if isAdd {
   238  			result, err = daoModel.Increment(sys_dao.SysInvite.Columns().ActivateNumber, num)
   239  		}
   240  
   241  		affected, _ := result.RowsAffected()
   242  		if err != nil || affected <= 0 {
   243  			return sys_service.SysLogs().ErrorSimple(ctx, nil, "修改邀约剩余次数失败", sys_dao.SysInvite.Table())
   244  		}
   245  
   246  		// 改变邀约次数为0的情况
   247  		newInviteInfo, _ := s.GetInviteById(ctx, id)
   248  		if newInviteInfo != nil && newInviteInfo.ActivateNumber <= 0 {
   249  			if sys_consts.Global.InviteCodeMaxActivateNumber != 0 { // 非无上限
   250  				_, err = s.SetInviteState(ctx, id, sys_enum.Invite.State.Invalid.Code())
   251  				if err != nil {
   252  					return sys_service.SysLogs().ErrorSimple(ctx, nil, "剩余邀约次数为0时,修改邀约状态失败", sys_dao.SysInvite.Table())
   253  				}
   254  			}
   255  		}
   256  
   257  		return nil
   258  	})
   259  
   260  	return err == nil, err
   261  }