model_v2.go 6.0 KB
package getuiV2

import (
	"openapi/pkg/infrastructure/push"
	"reflect"
	"strings"
)

const (
	splitChar       = "."
	contentTemplate = "点击查看详情"
)

type MapData struct {
	Data map[string]interface{}
}

func NewMapData() *MapData {
	return &MapData{
		Data: make(map[string]interface{}),
	}
}
func (m *MapData) AddFiled(field string, value interface{}) *MapData {
	fields := strings.Split(field, splitChar)
	var cur map[string]interface{}
	cur = m.Data
	for index, f := range fields {
		if index != (len(fields) - 1) {
			if _, ok := cur[f]; !ok {
				cur[f] = make(map[string]interface{})
			}
			cur = cur[f].(map[string]interface{})
			continue
		}
		if _, ok := cur[f]; !ok {
			cur[f] = value
		}
	}
	return m
}
func (m *MapData) GetFiledMap(field string) map[string]interface{} {
	fields := strings.Split(field, splitChar)
	cur := m.Data
	for _, f := range fields {
		if _, ok := cur[f]; !ok {
			cur[f] = make(map[string]interface{})
		}
		cur = cur[f].(map[string]interface{})
	}
	return cur
}
func (m *MapData) SetFieldMap(fieldMap map[string]interface{}, field string, value interface{}) *MapData {
	if value == nil {
		return m
	}
	v := reflect.ValueOf(value)
	if !v.IsValid() {
		return m
	}
	if v.IsZero() {
		return m
	}
	fieldMap[field] = value
	return m
}

// 推送消息
func NewPushMessage(option *push.Options) map[string]interface{} {
	m := NewMapData()
	// request_id
	m.AddFiled("request_id", genRequestId())

	// setting
	m.AddFiled("settings.ttl", 3600*24)
	/*
		默认所有通道的策略选择1-4
		1: 表示该消息在用户在线时推送个推通道,用户离线时推送厂商通道;
		2: 表示该消息只通过厂商通道策略下发,不考虑用户是否在线;
		3: 表示该消息只通过个推通道下发,不考虑用户是否在线;
		4: 表示该消息优先从厂商通道下发,若消息内容在厂商通道代发失败后会从个推通道下发。
		其中名称可填写: ios、st、hw、xm、vv、mz、op
	*/
	m.AddFiled("settings.strategy.default", 1)
	m.AddFiled("settings.strategy.ios", 4)

	// audience
	m.AddFiled("audience.cid", []string{option.ClientId})
	if len(option.ClientIds) > 0 {
		m.AddFiled("audience.cid", option.ClientIds)
	}

	// push_message
	if option.MsgType == push.Notification {
		pushMessageNotification(m, option)
	} else if option.MsgType == push.SystemTransmission {
		pushMessageTransmission(m, option)
	}

	// push_channel
	channelAndroid(m, option)
	channelIOS(m, option)

	return m.Data
}

/*push_message*/
func pushMessageNotification(m *MapData, option *push.Options) {
	notification := m.GetFiledMap("push_message.notification")

	m.SetFieldMap(notification, "title", option.Title)
	m.SetFieldMap(notification, "body", option.Content)

	m.SetFieldMap(notification, "click_type", "payload")
	m.SetFieldMap(notification, "payload", option.TransmissionContent)
	if len(option.Intent) > 0 {
		m.SetFieldMap(notification, "click_type", "intent")
		m.SetFieldMap(notification, "intent", option.Intent)
	}
	//if v, ok := option.GetExt("sound"); ok && len(v.(string)) > 0 {
	//	filename:=filepath.Base(v.(string))
	//	m.SetFieldMap(notification, "ring_name",filename)
	//}
}
func pushMessageTransmission(m *MapData, option *push.Options) {
	m.AddFiled("push_message.transmission", option.TransmissionContent)
}

/*channel*/
/*
		"android":{
	            "ups":{
	                "notification":{
	                    "title":"请填写android标题",
	                    "body":"请填写android内容",
	                    "click_type":"url",
	                    "url":"https://xxx"
	                }
	            }
	        },
*/
func channelAndroid(m *MapData, option *push.Options) {
	notification := m.GetFiledMap("push_channel.android.ups.notification")
	m.SetFieldMap(notification, "title", option.Title).
		SetFieldMap(notification, "body", contentTemplate) //TODO:配置控制body是否展示
	if len(option.Intent) > 0 {
		m.SetFieldMap(notification, "intent", option.FormatTranDataToIntent()).
			SetFieldMap(notification, "click_type", "intent")
	} else {
		m.SetFieldMap(notification, "click_type", "payload")
		m.SetFieldMap(notification, "payload", option.TransmissionContent)
	}

	optionsMap := make(map[string]map[string]interface{})
	optionsMap["VV"] = map[string]interface{}{
		"classification": 1,
	}
	if v, ok := option.GetExt(push.SoundHW); ok && len(v.(string)) > 0 {
		channel, _ := option.GetExt(push.SoundChannelHW)
		optionsMap["HW"] = map[string]interface{}{
			"/message/android/notification/default_sound": false,
			"/message/android/notification/channel_id":    channel,    //需要申请
			"/message/android/notification/sound":         v.(string), //自定义消息通知铃声
			"/message/android/notification/importance":    "NORMAL",
		}
	}
	if v, ok := option.GetExt(push.SoundXM); ok && len(v.(string)) > 0 {
		channel, _ := option.GetExt(push.SoundChannelXM)
		optionsMap["XM"] = map[string]interface{}{
			"sound_uri": v.(string), //需要申请 自定义消息通知铃声
			"channel":   channel,    //需要申请
		}
	}
	m.AddFiled("push_channel.android.ups.options", optionsMap)
}

/*
			"ios":{
	            "type":"notify",
	            "payload":"自定义消息",
	            "aps":{
	                "alert":{
	                    "title":"请填写ios标题",
	                    "body":"请填写ios内容"
	                },
	                "content-available":0
	            },
	            "auto_badge":"+1"
	        }
*/
func channelIOS(m *MapData, option *push.Options) {
	m.AddFiled("push_channel.ios.type", "notify")
	m.AddFiled("push_channel.ios.payload", option.TransmissionContent)

	alert := m.GetFiledMap("push_channel.ios.aps.alert")
	//TODO:去掉这个ios通知栏只有内容行,没有标题行,如果后期需要显示这个 需要ext里面扩展字段用来控制是否显示标题
	m.SetFieldMap(alert, "title", option.Title)
	//m.SetFieldMap(alert, "body", option.Content)
	m.AddFiled("push_channel.ios.aps.content-available", 0)

	if v, ok := option.GetExt(push.Sound); ok && len(v.(string)) > 0 {
		m.AddFiled("push_channel.ios.aps.sound", v)
	}
	m.AddFiled("push_channel.ios.auto_badge", "+1")
}