package user import ( "context" "tydata-server/app/user/model" "tydata-server/common/ctxdata" "tydata-server/common/xerr" "github.com/zeromicro/go-zero/core/mr" "github.com/pkg/errors" "github.com/zeromicro/go-zero/core/stores/sqlx" "tydata-server/app/user/cmd/api/internal/svc" "github.com/zeromicro/go-zero/core/logx" ) type CancelOutLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewCancelOutLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CancelOutLogic { return &CancelOutLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } func (l *CancelOutLogic) CancelOut() error { userID, getUserIdErr := ctxdata.GetUidFromCtx(l.ctx) if getUserIdErr != nil { return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", getUserIdErr) } // 1. 先检查用户是否是代理 agentModel, err := l.svcCtx.AgentModel.FindOneByUserId(l.ctx, userID) if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询代理信息失败, userId: %d", userID) } // 如果用户是代理,进行额外检查 if agentModel != nil { // 1.1 检查代理等级是否为VIP或SVIP if agentModel.LevelName == model.AgentLeveNameVIP || agentModel.LevelName == model.AgentLeveNameSVIP { return errors.Wrapf(xerr.NewErrMsg("您是"+agentModel.LevelName+"会员,请联系客服进行注销"), "用户是代理会员,不能注销") } // 1.2 检查代理钱包是否有余额或冻结金额 wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(l.ctx, agentModel.Id) if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查询代理钱包失败, agentId: %d", agentModel.Id) } if wallet != nil && (wallet.Balance > 0 || wallet.FrozenBalance > 0) { if wallet.Balance > 0 { return errors.Wrapf(xerr.NewErrMsg("您的钱包还有余额%.2f元,请先提现后再注销账号"), "用户钱包有余额,不能注销", wallet.Balance) } if wallet.FrozenBalance > 0 { return errors.Wrapf(xerr.NewErrMsg("您的钱包还有冻结金额%.2f元,请等待解冻后再注销账号"), "用户钱包有冻结金额,不能注销", wallet.FrozenBalance) } } } // 在事务中处理用户注销相关操作 err = l.svcCtx.UserModel.Trans(l.ctx, func(tranCtx context.Context, session sqlx.Session) error { // 1. 删除用户基本信息 if err := l.svcCtx.UserModel.Delete(tranCtx, session, userID); err != nil { return errors.Wrapf(err, "删除用户基本信息失败, userId: %d", userID) } // 2. 查询并删除用户授权信息 UserAuthModelBuilder := l.svcCtx.UserAuthModel.SelectBuilder().Where("user_id = ?", userID) userAuths, err := l.svcCtx.UserAuthModel.FindAll(tranCtx, UserAuthModelBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询用户授权信息失败, userId: %d", userID) } // 并发删除用户授权信息 if len(userAuths) > 0 { funcs := make([]func() error, len(userAuths)) for i, userAuth := range userAuths { authID := userAuth.Id funcs[i] = func() error { return l.svcCtx.UserAuthModel.Delete(tranCtx, session, authID) } } if err := mr.Finish(funcs...); err != nil { return errors.Wrapf(err, "删除用户授权信息失败") } } // 3. 处理代理相关信息 if agentModel != nil { // 3.1 删除代理信息 if err := l.svcCtx.AgentModel.Delete(tranCtx, session, agentModel.Id); err != nil { return errors.Wrapf(err, "删除代理信息失败, agentId: %d", agentModel.Id) } // 3.2 查询并删除代理会员配置 configBuilder := l.svcCtx.AgentMembershipUserConfigModel.SelectBuilder().Where("agent_id = ?", agentModel.Id) configs, err := l.svcCtx.AgentMembershipUserConfigModel.FindAll(tranCtx, configBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询代理会员配置失败, agentId: %d", agentModel.Id) } // 并发删除代理会员配置 if len(configs) > 0 { configFuncs := make([]func() error, len(configs)) for i, config := range configs { configId := config.Id configFuncs[i] = func() error { return l.svcCtx.AgentMembershipUserConfigModel.Delete(tranCtx, session, configId) } } if err := mr.Finish(configFuncs...); err != nil { return errors.Wrapf(err, "删除代理会员配置失败") } } // 3.3 删除代理钱包信息 wallet, err := l.svcCtx.AgentWalletModel.FindOneByAgentId(tranCtx, agentModel.Id) if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询代理钱包信息失败, agentId: %d", agentModel.Id) } if wallet != nil { if err := l.svcCtx.AgentWalletModel.Delete(tranCtx, session, wallet.Id); err != nil { return errors.Wrapf(err, "删除代理钱包信息失败, walletId: %d", wallet.Id) } } // 3.4 删除代理关系信息 closureBuilder := l.svcCtx.AgentClosureModel.SelectBuilder().Where("ancestor_id = ? AND depth = ?", agentModel.Id, 1) closures, err := l.svcCtx.AgentClosureModel.FindAll(tranCtx, closureBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询代理关系信息失败, agentId: %d", agentModel.Id) } if len(closures) > 0 { closureFuncs := make([]func() error, len(closures)) for i, closure := range closures { closureId := closure.Id closureFuncs[i] = func() error { return l.svcCtx.AgentClosureModel.Delete(tranCtx, session, closureId) } } if err := mr.Finish(closureFuncs...); err != nil { return errors.Wrapf(err, "删除代理关系信息失败") } } } // 4. 查询并删除代理审核信息 auditBuilder := l.svcCtx.AgentAuditModel.SelectBuilder().Where("user_id = ?", userID) audits, err := l.svcCtx.AgentAuditModel.FindAll(tranCtx, auditBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询代理审核信息失败, userId: %d", userID) } // 并发删除代理审核信息 if len(audits) > 0 { auditFuncs := make([]func() error, len(audits)) for i, audit := range audits { auditId := audit.Id auditFuncs[i] = func() error { return l.svcCtx.AgentAuditModel.Delete(tranCtx, session, auditId) } } if err := mr.Finish(auditFuncs...); err != nil { return errors.Wrapf(err, "删除代理审核信息失败") } } // 5. 删除用户查询记录 queryBuilder := l.svcCtx.QueryModel.SelectBuilder().Where("user_id = ?", userID) queries, err := l.svcCtx.QueryModel.FindAll(tranCtx, queryBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询用户查询记录失败, userId: %d", userID) } if len(queries) > 0 { queryFuncs := make([]func() error, len(queries)) for i, query := range queries { queryId := query.Id queryFuncs[i] = func() error { return l.svcCtx.QueryModel.Delete(tranCtx, session, queryId) } } if err := mr.Finish(queryFuncs...); err != nil { return errors.Wrapf(err, "删除用户查询记录失败") } } // 6. 删除用户订单记录 orderBuilder := l.svcCtx.OrderModel.SelectBuilder().Where("user_id = ?", userID) orders, err := l.svcCtx.OrderModel.FindAll(tranCtx, orderBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询用户订单记录失败, userId: %d", userID) } if len(orders) > 0 { orderFuncs := make([]func() error, len(orders)) for i, order := range orders { orderId := order.Id orderFuncs[i] = func() error { return l.svcCtx.OrderModel.Delete(tranCtx, session, orderId) } } if err := mr.Finish(orderFuncs...); err != nil { return errors.Wrapf(err, "删除用户订单记录失败") } } // 7. 删除代理订单信息 agentOrderBuilder := l.svcCtx.AgentOrderModel.SelectBuilder().Where("agent_id = ?", agentModel.Id) agentOrders, err := l.svcCtx.AgentOrderModel.FindAll(tranCtx, agentOrderBuilder, "") if err != nil && !errors.Is(err, model.ErrNotFound) { return errors.Wrapf(err, "查询代理订单信息失败, agentId: %d, err: %v", agentModel.Id, err) } if len(agentOrders) > 0 { agentOrderFuncs := make([]func() error, len(agentOrders)) for i, agentOrder := range agentOrders { agentOrderId := agentOrder.Id agentOrderFuncs[i] = func() error { return l.svcCtx.AgentOrderModel.Delete(tranCtx, session, agentOrderId) } } if err := mr.Finish(agentOrderFuncs...); err != nil { return errors.Wrapf(err, "删除代理订单信息失败") } } return nil }) if err != nil { return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "用户注销失败%v", err) } return nil }