first commit
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
// Package app1svc 是小程序 app1 的业务逻辑。
|
||||
// 其余小程序(app2..app10)按相同目录结构各自建包,互不耦合。
|
||||
package app1svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"time"
|
||||
|
||||
"portal-mini-go/internal/model"
|
||||
"portal-mini-go/internal/pkg/errors"
|
||||
"portal-mini-go/internal/pkg/session"
|
||||
"portal-mini-go/internal/pkg/wechat"
|
||||
"portal-mini-go/internal/repository/miniapp"
|
||||
"portal-mini-go/internal/repository/user"
|
||||
)
|
||||
|
||||
const sessionKeyPrefix = "ma:session:"
|
||||
|
||||
// Service app1 业务服务,依赖用户仓储、小程序仓储、微信客户端与会话存储。
|
||||
type Service struct {
|
||||
userRepo *user.Repository
|
||||
miniRepo *miniapp.Repository
|
||||
wx *wechat.Client
|
||||
store session.Store
|
||||
}
|
||||
|
||||
func New(userRepo *user.Repository, miniRepo *miniapp.Repository, wx *wechat.Client, store session.Store) *Service {
|
||||
return &Service{userRepo: userRepo, miniRepo: miniRepo, wx: wx, store: store}
|
||||
}
|
||||
|
||||
// Login 完成小程序登录:按 app_id 取凭证 -> code2session -> 落库用户 -> 签发会话 token。
|
||||
// app_id 由接入层(MiniAppAuth 中间件)校验过为已启用小程序,此处用于查出 secret 与小程序主键。
|
||||
func (s *Service) Login(ctx context.Context, appID, code string) (string, *model.User, error) {
|
||||
mp, err := s.miniRepo.GetActiveByAppID(ctx, appID)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
info, err := s.wx.Code2Session(ctx, appID, mp.AppSecret, code)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
u, err := s.userRepo.UpsertByOpenID(ctx, mp.ID, info.OpenID, info.UnionID, "", "")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
token, err := newSessionToken()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
if err := s.store.Set(ctx, sessionKeyPrefix+token, u.ID, 7*24*time.Hour); err != nil {
|
||||
return "", nil, errors.Wrap(50000, "save session", err)
|
||||
}
|
||||
return token, u, nil
|
||||
}
|
||||
|
||||
func newSessionToken() (string, error) {
|
||||
b := make([]byte, 24)
|
||||
if _, err := rand.Read(b); err != nil {
|
||||
return "", errors.Wrap(50000, "gen token", err)
|
||||
}
|
||||
return hex.EncodeToString(b), nil
|
||||
}
|
||||
Reference in New Issue
Block a user