132 lines
4.0 KiB
Go
132 lines
4.0 KiB
Go
package http
|
||
|
||
import (
|
||
"hyapp/services/gateway-service/internal/transport/http/httpkit"
|
||
"net/http"
|
||
"strings"
|
||
|
||
userv1 "hyapp.local/api/proto/user/v1"
|
||
"hyapp/services/gateway-service/internal/auth"
|
||
)
|
||
|
||
// handlePushToken 分发 push token 绑定和失效。
|
||
// 设备 token 属于 user-service 主数据扩展,gateway 只做鉴权、字段透传和 HTTP method 约束。
|
||
func (h *Handler) handlePushToken(writer http.ResponseWriter, request *http.Request) {
|
||
switch request.Method {
|
||
case http.MethodPost:
|
||
h.bindPushToken(writer, request)
|
||
case http.MethodDelete:
|
||
h.deletePushToken(writer, request)
|
||
default:
|
||
httpkit.WriteError(writer, request, http.StatusMethodNotAllowed, httpkit.CodeInvalidArgument, "invalid argument")
|
||
}
|
||
}
|
||
|
||
func (h *Handler) bindPushToken(writer http.ResponseWriter, request *http.Request) {
|
||
if h.userDeviceClient == nil {
|
||
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
||
return
|
||
}
|
||
|
||
var body struct {
|
||
DeviceID string `json:"device_id"`
|
||
PushToken string `json:"push_token"`
|
||
Provider string `json:"provider"`
|
||
Platform string `json:"platform"`
|
||
AppVersion string `json:"app_version"`
|
||
Language string `json:"language"`
|
||
Timezone string `json:"timezone"`
|
||
}
|
||
if !decode(writer, request, &body) {
|
||
return
|
||
}
|
||
body.DeviceID = pushDeviceID(request, body.DeviceID)
|
||
body.Platform = pushPlatform(request, body.Platform)
|
||
|
||
resp, err := h.userDeviceClient.BindPushToken(request.Context(), &userv1.BindPushTokenRequest{
|
||
Meta: authRequestMeta(request, body.DeviceID),
|
||
UserId: auth.UserIDFromContext(request.Context()),
|
||
DeviceId: body.DeviceID,
|
||
PushToken: strings.TrimSpace(body.PushToken),
|
||
Provider: body.Provider,
|
||
Platform: body.Platform,
|
||
AppVersion: body.AppVersion,
|
||
Language: body.Language,
|
||
Timezone: body.Timezone,
|
||
})
|
||
if err != nil {
|
||
httpkit.WriteRPCError(writer, request, err)
|
||
return
|
||
}
|
||
httpkit.WriteOK(writer, request, bindPushTokenDataFromProto(resp))
|
||
}
|
||
|
||
func (h *Handler) deletePushToken(writer http.ResponseWriter, request *http.Request) {
|
||
if h.userDeviceClient == nil {
|
||
httpkit.WriteError(writer, request, http.StatusBadGateway, httpkit.CodeUpstreamError, "upstream service error")
|
||
return
|
||
}
|
||
|
||
var body struct {
|
||
DeviceID string `json:"device_id"`
|
||
PushToken string `json:"push_token"`
|
||
}
|
||
if !decode(writer, request, &body) {
|
||
return
|
||
}
|
||
body.DeviceID = pushDeviceID(request, body.DeviceID)
|
||
|
||
resp, err := h.userDeviceClient.DeletePushToken(request.Context(), &userv1.DeletePushTokenRequest{
|
||
Meta: authRequestMeta(request, body.DeviceID),
|
||
UserId: auth.UserIDFromContext(request.Context()),
|
||
DeviceId: body.DeviceID,
|
||
PushToken: strings.TrimSpace(body.PushToken),
|
||
})
|
||
if err != nil {
|
||
httpkit.WriteRPCError(writer, request, err)
|
||
return
|
||
}
|
||
httpkit.WriteOK(writer, request, deletePushTokenDataFromProto(resp))
|
||
}
|
||
|
||
// bindPushTokenData/deletePushTokenData 固定外部 JSON 字段,避免 proto3 false 被省略。
|
||
type bindPushTokenData struct {
|
||
Bound bool `json:"bound"`
|
||
UpdatedAtMS int64 `json:"updated_at_ms"`
|
||
}
|
||
|
||
type deletePushTokenData struct {
|
||
Deleted bool `json:"deleted"`
|
||
UpdatedAtMS int64 `json:"updated_at_ms"`
|
||
}
|
||
|
||
func bindPushTokenDataFromProto(resp *userv1.BindPushTokenResponse) bindPushTokenData {
|
||
if resp == nil {
|
||
return bindPushTokenData{}
|
||
}
|
||
|
||
return bindPushTokenData{Bound: resp.GetBound(), UpdatedAtMS: resp.GetUpdatedAtMs()}
|
||
}
|
||
|
||
func deletePushTokenDataFromProto(resp *userv1.DeletePushTokenResponse) deletePushTokenData {
|
||
if resp == nil {
|
||
return deletePushTokenData{}
|
||
}
|
||
|
||
return deletePushTokenData{Deleted: resp.GetDeleted(), UpdatedAtMS: resp.GetUpdatedAtMs()}
|
||
}
|
||
|
||
func pushDeviceID(request *http.Request, bodyValue string) string {
|
||
if value := strings.TrimSpace(bodyValue); value != "" {
|
||
return value
|
||
}
|
||
return firstHeader(request, "X-Device-ID", "X-HY-Device-ID")
|
||
}
|
||
|
||
func pushPlatform(request *http.Request, bodyValue string) string {
|
||
if value := strings.TrimSpace(bodyValue); value != "" {
|
||
return value
|
||
}
|
||
return firstHeader(request, "X-App-Platform", "X-Platform")
|
||
}
|