2026-05-12 09:53:20 +08:00

132 lines
4.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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")
}