Files
backend/internal/pkg/jpush/vendor/params.go
lafay 755392e999
All checks were successful
Build Backend / build (push) Successful in 2m20s
Build Backend / build-docker (push) Successful in 1m15s
refactor(jpush): move vendor field handling into ThirdPartyChannel struct
Move the vendor switch logic into the ThirdPartyChannel struct as Set/IsEmpty/Normalize
methods to improve encapsulation and eliminate code duplication in the vendor params
builder. Also simplify messageToParams to reuse buildMessagePayload results and remove
unused notification_type extras from push notifications.
2026-06-18 00:02:00 +08:00

131 lines
4.5 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 vendor 提供厂商无关的消息参数抽象与各厂商推送字段转换。
//
// 设计要点:
// - 调用方只需提供厂商无关的 MessageParams不感知厂商差异。
// - 由于无法预知目标设备的具体厂商JPush 要求所有厂商私有配置全数下发,
// 由 JPush 服务端按目标设备厂商路由。
// - 双层架构TextRenderer基础层产出 Android/iOS 通用通知)+
// PrivateConverter附加层产出各厂商 third_party_channel 私有字段)。
package vendor
import (
"with_you/internal/config"
"with_you/internal/pkg/jpush"
)
// 场景常量
const (
// SceneSystem 系统消息/通知场景
SceneSystem = "system"
// SceneChat 私聊/群聊消息场景
SceneChat = "chat"
)
// MessageParams 厂商无关的统一消息参数(超集,用不上的字段厂商可忽略)
type MessageParams struct {
// Scene 决定使用哪类 channel/模板SceneSystem 或 SceneChat
Scene string
// Title 通知标题(如发送者昵称、群名:发送者)
Title string
// Body 通知正文(消息内容预览)
Body string
// SenderName 发送者昵称
SenderName string
// SenderID 发送者 ID
SenderID string
// ConversationName 会话名称(群聊为群名)
ConversationName string
// ConversationID 会话 ID
ConversationID string
// MessageType 消息类型标识chat_message / 系统通知类型),填充到 extras.notification_type
MessageType string
// ActionTime 操作时间RFC3339
ActionTime string
// LargeIcon 大图标 URL群头像/发送者头像)
LargeIcon string
// Extra 兜底扩展字段,合并进 android/ios 的 extras
Extra map[string]any
}
// PushPayload 工厂统一产物client 据此组装最终推送 payload
type PushPayload struct {
// Notification 含 android + ios由 TextRenderer 产出
Notification *jpush.Notification
// TPC 各厂商私有字段options.third_party_channel由 PrivateConverter 产出
TPC *jpush.ThirdPartyChannel
}
// TextRenderer 通用文本渲染器(基础层)
// 产出所有厂商共享的通用通知Android 通用通知 + iOS 通用通知
type TextRenderer interface {
// RenderAndroid 渲染 Android 通用通知(所有 Android 厂商共享)
RenderAndroid(params MessageParams, cfg config.ChannelConfig) *jpush.AndroidNotif
// RenderIOS 渲染 iOS 通用通知(按场景设置 thread-id 分组)
RenderIOS(params MessageParams, cfg config.ChannelConfig) *jpush.IOSNotif
}
// PrivateConverter 厂商私有转换器(附加层)
// 产出 third_party_channel.{vendor} 的私有字段channel_id、模板等
type PrivateConverter interface {
// VendorName 返回厂商标识,对应 third_party_channel 的 keyxiaomi/oppo/huawei/...
VendorName() string
// Convert 根据消息参数 + 全局配置产出该厂商私有字段 map
// 厂商专属 channel_id 为空时回退到全局 cfg.System/Chat
// 返回 nil 表示该厂商无需下发(如最终 channel_id 与模板均未配置)
Convert(params MessageParams, cfg config.ChannelConfig) map[string]any
}
// Factory 持有通用渲染器与全部厂商私有转换器
type Factory struct {
renderer TextRenderer
privateConverters []PrivateConverter
}
// NewFactory 创建工厂,注册默认渲染器与全部厂商转换器
func NewFactory() *Factory {
return &Factory{
renderer: newDefaultRenderer(),
privateConverters: []PrivateConverter{
xiaomiConverter{},
huaweiConverter{},
oppoConverter{},
vivoConverter{},
meizuConverter{},
honorConverter{},
fcmConverter{},
},
}
}
// NewFactoryWith 自定义渲染器与转换器创建工厂(便于测试)
func NewFactoryWith(renderer TextRenderer, converters []PrivateConverter) *Factory {
return &Factory{renderer: renderer, privateConverters: converters}
}
// Build 根据统一参数与配置,组装完整的 PushPayload
// 调用通用渲染器产出 Notification调用各私有转换器产出 ThirdPartyChannel
func (f *Factory) Build(params MessageParams, cfg config.ChannelConfig) *PushPayload {
android := f.renderer.RenderAndroid(params, cfg)
ios := f.renderer.RenderIOS(params, cfg)
notification := &jpush.Notification{
Alert: params.Body,
Android: android,
IOS: ios,
}
tpc := &jpush.ThirdPartyChannel{}
for _, c := range f.privateConverters {
m := c.Convert(params, cfg)
if m == nil {
continue
}
tpc.Set(c.VendorName(), m)
}
return &PushPayload{
Notification: notification,
TPC: tpc.Normalize(),
}
}