feat: 迁移plant
This commit is contained in:
@@ -16,6 +16,13 @@ SystemRpc:
|
||||
- 192.168.100.127:2379
|
||||
Key: system.rpc
|
||||
|
||||
# 各业务 RPC(新增小程序时在此追加)
|
||||
PlantRpc:
|
||||
Etcd:
|
||||
Hosts:
|
||||
- 192.168.100.127:2379
|
||||
Key: plant.rpc
|
||||
|
||||
# Redis(验证码存储,DB2)
|
||||
Redis:
|
||||
Host: 192.168.100.127:6379
|
||||
|
||||
@@ -12,7 +12,10 @@ type Config struct {
|
||||
AccessExpire int64
|
||||
}
|
||||
SystemRpc zrpc.RpcClientConf
|
||||
Redis struct {
|
||||
// 各业务 RPC(可选,新增小程序时在此追加)
|
||||
PlantRpc zrpc.RpcClientConf `json:",optional"`
|
||||
// RadioRpc zrpc.RpcClientConf `json:",optional"` // 待接入
|
||||
Redis struct {
|
||||
Host string
|
||||
Pass string
|
||||
DB int `json:",optional"`
|
||||
|
||||
@@ -22,6 +22,12 @@ func MiniLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
// 从请求头读取 clientId,优先级高于 body
|
||||
// 前端统一在请求头设置 X-Client-Id: plant_mini / radio_mini 等
|
||||
if clientId := r.Header.Get("X-Client-Id"); clientId != "" {
|
||||
req.ClientId = clientId
|
||||
}
|
||||
|
||||
l := auth.NewMiniLoginLogic(r.Context(), svcCtx)
|
||||
resp, err := l.MiniLogin(&req)
|
||||
if err != nil {
|
||||
|
||||
@@ -13,11 +13,24 @@ import (
|
||||
|
||||
"sundynix-micro-go/app/auth/api/internal/svc"
|
||||
"sundynix-micro-go/app/auth/api/internal/types"
|
||||
plantPb "sundynix-micro-go/app/plant/rpc/plant"
|
||||
sysPb "sundynix-micro-go/app/system/rpc/system"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
// clientId 常量 — 新增小程序时在此添加
|
||||
const (
|
||||
ClientIdPlant = "sundynix-plant" // 植物小程序
|
||||
// ClientIdRadio = "radio_mini" // 电台小程序(待接入)
|
||||
)
|
||||
|
||||
// MiniAppAdditionalInfo 小程序客户端扩展信息(存储在 additional_info JSON 字段中)
|
||||
type MiniAppAdditionalInfo struct {
|
||||
AppId string `json:"appId"`
|
||||
AppSecret string `json:"appSecret"`
|
||||
}
|
||||
|
||||
type MiniLoginLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
@@ -43,14 +56,30 @@ type WxCode2SessionResp struct {
|
||||
}
|
||||
|
||||
func (l *MiniLoginLogic) MiniLogin(req *types.MiniLoginReq) (resp *types.LoginResp, err error) {
|
||||
// 1. 调用微信接口获取openid和session_key
|
||||
// TODO: 从配置中获取AppId和AppSecret,当前先用固定值
|
||||
appID := "wxb463820bf36dd5d6"
|
||||
appSecret := "731784a74c76c6d31fa00bb847af2c7d"
|
||||
// 1. 根据 clientId 查询客户端配置,从 additional_info 中动态读取 appId/appSecret
|
||||
clientResp, err := l.svcCtx.SystemRpc.GetClientById(l.ctx, &sysPb.GetClientByIdReq{
|
||||
ClientId: req.ClientId,
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorf("[MiniLogin] 查询客户端失败: clientId=%s, err=%v", req.ClientId, err)
|
||||
return nil, fmt.Errorf("无效的客户端: %s", req.ClientId)
|
||||
}
|
||||
|
||||
// 2. 解析 additional_info 获取微信凭证
|
||||
var miniInfo MiniAppAdditionalInfo
|
||||
if err = json.Unmarshal([]byte(clientResp.Client.AdditionalInfo), &miniInfo); err != nil {
|
||||
l.Errorf("[MiniLogin] 解析客户端 additional_info 失败: clientId=%s, info=%s, err=%v",
|
||||
req.ClientId, clientResp.Client.AdditionalInfo, err)
|
||||
return nil, fmt.Errorf("客户端配置格式错误,请检查 additional_info")
|
||||
}
|
||||
if miniInfo.AppId == "" || miniInfo.AppSecret == "" {
|
||||
return nil, fmt.Errorf("客户端 %s 未配置 appId 或 appSecret", req.ClientId)
|
||||
}
|
||||
|
||||
// 3. 调用微信 code2session 接口
|
||||
params := url.Values{}
|
||||
params.Set("appid", appID)
|
||||
params.Set("secret", appSecret)
|
||||
params.Set("appid", miniInfo.AppId)
|
||||
params.Set("secret", miniInfo.AppSecret)
|
||||
params.Set("js_code", req.Code)
|
||||
params.Set("grant_type", "authorization_code")
|
||||
fullURL := "https://api.weixin.qq.com/sns/jscode2session?" + params.Encode()
|
||||
@@ -83,7 +112,7 @@ func (l *MiniLoginLogic) MiniLogin(req *types.MiniLoginReq) (resp *types.LoginRe
|
||||
return nil, fmt.Errorf("openid为空")
|
||||
}
|
||||
|
||||
// 2. 通过 user-rpc 创建或获取用户
|
||||
// 4. 通过 system-rpc 创建或获取基础用户
|
||||
createResp, err := l.svcCtx.SystemRpc.CreateUser(l.ctx, &sysPb.CreateUserReq{
|
||||
Name: "",
|
||||
OpenId: wxResp.Openid,
|
||||
@@ -95,7 +124,33 @@ func (l *MiniLoginLogic) MiniLogin(req *types.MiniLoginReq) (resp *types.LoginRe
|
||||
return nil, fmt.Errorf("登录失败")
|
||||
}
|
||||
|
||||
// 3. 生成JWT Token(复用统一的 generateToken 函数)
|
||||
userId := createResp.User.Id
|
||||
|
||||
// 5. 异步初始化各业务服务的用户扩展表
|
||||
// 新增小程序:在 switch 里加一个 case 即可
|
||||
go func(uid, clientId string) {
|
||||
bgCtx := context.Background()
|
||||
switch clientId {
|
||||
case ClientIdPlant:
|
||||
if l.svcCtx.PlantRpc == nil {
|
||||
l.Errorf("[MiniLogin] PlantRpc 未配置,跳过 plant profile 初始化")
|
||||
return
|
||||
}
|
||||
if _, err := l.svcCtx.PlantRpc.GetUserProfile(bgCtx, &plantPb.GetProfileReq{
|
||||
UserId: uid,
|
||||
}); err != nil {
|
||||
l.Errorf("[MiniLogin] 初始化 plant profile 失败: userId=%s, err=%v", uid, err)
|
||||
} else {
|
||||
l.Infof("[MiniLogin] plant profile 初始化成功: userId=%s", uid)
|
||||
}
|
||||
// case ClientIdRadio:
|
||||
// l.svcCtx.RadioRpc.GetUserProfile(bgCtx, &radioPb.GetProfileReq{UserId: uid})
|
||||
default:
|
||||
// 未知 clientId 或无需扩展表的场景,跳过
|
||||
}
|
||||
}(userId, req.ClientId)
|
||||
|
||||
// 6. 生成JWT Token
|
||||
token, err := generateToken(l.svcCtx.Config.Auth.AccessSecret, l.svcCtx.Config.Auth.AccessExpire, createResp.User)
|
||||
if err != nil {
|
||||
l.Errorf("生成Token失败: %v", err)
|
||||
|
||||
@@ -2,6 +2,7 @@ package svc
|
||||
|
||||
import (
|
||||
"sundynix-micro-go/app/auth/api/internal/config"
|
||||
"sundynix-micro-go/app/plant/rpc/plantservice"
|
||||
"sundynix-micro-go/app/system/rpc/systemservice"
|
||||
"sundynix-micro-go/common/utils/captcha"
|
||||
|
||||
@@ -13,6 +14,9 @@ import (
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
SystemRpc systemservice.SystemService
|
||||
// 各业务 RPC(可选,新增小程序时在此追加)
|
||||
PlantRpc plantservice.PlantService
|
||||
// RadioRpc radioservice.RadioService
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
@@ -25,8 +29,16 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
captcha.InitWithRedis(rdb)
|
||||
logx.Infof("验证码存储已切换至 Redis (DB%d)", c.Redis.DB)
|
||||
|
||||
return &ServiceContext{
|
||||
svc := &ServiceContext{
|
||||
Config: c,
|
||||
SystemRpc: systemservice.NewSystemService(zrpc.MustNewClient(c.SystemRpc)),
|
||||
}
|
||||
|
||||
// 可选: PlantRpc(配置了才连接,避免强依赖)
|
||||
if c.PlantRpc.Etcd.Key != "" || len(c.PlantRpc.Endpoints) > 0 {
|
||||
svc.PlantRpc = plantservice.NewPlantService(zrpc.MustNewClient(c.PlantRpc))
|
||||
logx.Info("PlantRpc 已连接")
|
||||
}
|
||||
|
||||
return svc
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user