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 }