Initialize LineUp app server
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/lineup/app-server/internal/wkapi"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// UserModule 用户模块: 登录 / 注册
|
||||
type UserModule struct {
|
||||
vp *viper.Viper
|
||||
wk *wkapi.Client
|
||||
}
|
||||
|
||||
// RegisterRoutes 注册路由
|
||||
func (m *UserModule) RegisterRoutes(r *gin.Engine) {
|
||||
r.POST("/login", m.handleLogin)
|
||||
}
|
||||
|
||||
// LoginRequest 登录请求
|
||||
type LoginRequest struct {
|
||||
Phone string `json:"phone" binding:"required"`
|
||||
Code string `json:"code" binding:"required"`
|
||||
}
|
||||
|
||||
// LoginResponse 登录响应
|
||||
type LoginResponse struct {
|
||||
UID string `json:"uid"`
|
||||
Token string `json:"token"`
|
||||
IMAddr string `json:"im_addr"` // WuKongIM WS地址
|
||||
AgentUID string `json:"agent_uid"` // Agent的UID
|
||||
ChannelID string `json:"channel_id"` // Agent频道ID
|
||||
ChannelType uint8 `json:"channel_type"` // Agent频道类型
|
||||
}
|
||||
|
||||
// handleLogin 处理登录请求
|
||||
func (m *UserModule) handleLogin(c *gin.Context) {
|
||||
var req LoginRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "参数错误: phone和code必填"})
|
||||
return
|
||||
}
|
||||
|
||||
// 生成用户 UID
|
||||
uid := fmt.Sprintf("user_%s", req.Phone)
|
||||
|
||||
// 生成 Token (随机32字节)
|
||||
token := generateToken()
|
||||
|
||||
// 注册 Token 到 WuKongIM
|
||||
if err := m.wk.RegisterToken(uid, token); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("注册Token失败: %v", err)})
|
||||
return
|
||||
}
|
||||
|
||||
// 确保 Agent 频道存在并将用户加入订阅者
|
||||
agentChannelID := m.vp.GetString("agent.channelID")
|
||||
agentUID := m.vp.GetString("agent.uid")
|
||||
agentChannelType := uint8(m.vp.GetInt("agent.channelType"))
|
||||
if agentChannelType == 0 {
|
||||
agentChannelType = 2
|
||||
}
|
||||
// 创建/更新频道,确保 Agent 和用户都是订阅者
|
||||
m.wk.UpsertChannel(agentChannelID, agentChannelType, []string{agentUID})
|
||||
// 将用户加入频道订阅者
|
||||
m.wk.SubscriberAdd(agentChannelID, agentChannelType, []string{uid})
|
||||
|
||||
// 获取 WebSocket 地址
|
||||
route, err := m.wk.GetRoute()
|
||||
wsAddr := m.vp.GetString("wukongim.wsAddr")
|
||||
if err == nil && route.WSAddr != "" {
|
||||
wsAddr = route.WSAddr
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, LoginResponse{
|
||||
UID: uid,
|
||||
Token: token,
|
||||
IMAddr: wsAddr,
|
||||
AgentUID: m.vp.GetString("agent.uid"),
|
||||
ChannelID: m.vp.GetString("agent.channelID"),
|
||||
ChannelType: uint8(m.vp.GetInt("agent.channelType")),
|
||||
})
|
||||
}
|
||||
|
||||
// generateToken 生成32字节随机Token
|
||||
func generateToken() string {
|
||||
b := make([]byte, 32)
|
||||
rand.Read(b)
|
||||
return hex.EncodeToString(b)
|
||||
}
|
||||
Reference in New Issue
Block a user