diff --git a/marketing-api/model/creative/image_material.go b/marketing-api/model/creative/image_material.go index 972c7796..bcd3ac81 100644 --- a/marketing-api/model/creative/image_material.go +++ b/marketing-api/model/creative/image_material.go @@ -1,17 +1,66 @@ package creative -import "github.com/bububa/oceanengine/marketing-api/enum" +import ( + "encoding/json" + + "github.com/bububa/oceanengine/marketing-api/enum" +) // ImageMaterial 创意图片素材 type ImageMaterial struct { // ImageMode 素材类型,必填,注意:程序化创意不支持组图 CREATIVE_IMAGE_MODE_GROUP,其他类型图片都支持,如横版/竖版大图、小图。详见【附录-素材类型】 ImageMode enum.ImageMode `json:"image_mode,omitempty"` // ImageInfo 图片素材信息 - ImageInfo *ImageInfo `json:"image_info,omitempty"` + ImageInfo *ImageInfoWrapper `json:"image_info,omitempty"` // TemplateImage 图片模版信息,创建DPA创意时可传入,选择模板后image_info传入内容无效 TemplateImage *TemplateImage `json:"template_imate,omitempty"` } +// ImageInfoWrapper image_info wrapper +// image_info 可能为slice也可能为object +type ImageInfoWrapper struct { + Object *ImageInfo + List []ImageInfo +} + +func (i *ImageInfoWrapper) IsObject() bool { + return i.Object != nil +} + +// UnmarshalJSON implement json Unmarshal interface +func (i *ImageInfoWrapper) UnmarshalJSON(b []byte) (err error) { + var ret ImageInfoWrapper + if b[0] == '[' && b[len(b)-1] == ']' { + if err := json.Unmarshal(b, &ret.List); err != nil { + return err + } + } else if b[0] == '{' && b[len(b)-1] == '}' { + ret.Object = new(ImageInfo) + if err := json.Unmarshal(b, ret.Object); err != nil { + return err + } + } + if ret.Object == nil && len(ret.List) == 0 { + i = nil + } else { + *i = ret + } + return nil +} + +// MmarshalJSON implement json Marshal interface +func (i *ImageInfoWrapper) MarshalJSON() ([]byte, error) { + if i.Object != nil { + return json.Marshal(i.Object) + } else if len(i.List) == 0 { + return []byte("null"), nil + } + return json.Marshal(i.List) +} + +var _ json.Unmarshaler = (*ImageInfoWrapper)(nil) +var _ json.Marshaler = (*ImageInfoWrapper)(nil) + // ImageInfo 图片素材信息 type ImageInfo struct { // ImageMode 素材类型,必填,注意:程序化创意不支持组图 CREATIVE_IMAGE_MODE_GROUP,其他类型图片都支持,如横版/竖版大图、小图。详见【附录-素材类型】 diff --git a/marketing-api/model/creative/image_material_test.go b/marketing-api/model/creative/image_material_test.go new file mode 100644 index 00000000..d36042aa --- /dev/null +++ b/marketing-api/model/creative/image_material_test.go @@ -0,0 +1,46 @@ +package creative + +import ( + "encoding/json" + "testing" +) + +func TestImageMaterialMarshaler(t *testing.T) { + encs := []string{`{"image_info":[{"image_id":"test"}]}`, `{"image_info":{"image_id":"test"}}`, `{}`} + objs := []ImageMaterial{ + { + ImageInfo: &ImageInfoWrapper{ + List: []ImageInfo{ + { + ImageID: "test", + }, + }, + }, + }, + { + ImageInfo: &ImageInfoWrapper{ + Object: &ImageInfo{ + ImageID: "test", + }, + }, + }, + { + ImageInfo: nil, + }, + } + for idx, enc := range encs { + if bs, err := json.Marshal(objs[idx]); err != nil { + t.Error(err) + } else if string(bs) != enc { + t.Errorf("expect:%s, got:%s", enc, string(bs)) + } + var obj ImageMaterial + if err := json.Unmarshal([]byte(enc), &obj); err != nil { + t.Error(err) + } else if objs[idx].ImageInfo != nil && obj.ImageInfo == nil || objs[idx].ImageInfo == nil && obj.ImageInfo != nil { + t.Errorf("case:%s, expect: %+v, got: %+v\n", enc, objs[idx], obj) + } else if objs[idx].ImageInfo != nil && obj.ImageInfo != nil && objs[idx].ImageInfo.IsObject() != obj.ImageInfo.IsObject() { + t.Errorf("case: %s, expect: %+v, got: %+v\n", enc, objs[idx].ImageInfo, obj.ImageInfo) + } + } +}