接口文档SDK业务专题开发者工具

快速构建创意UI

本章节介绍了 Marketing UI 中创意模块的安装、使用方法及步骤。

支持的创意元素类型

IMAGE (jpg, png格式), VIDEO (mp4, mov, avi格式), REFERENCE, TEXT, URL, ID, ENUM (下拉框、checkbox形式), STRUCT (corporate, element_story字段)。 不同 adcreative_template_id 要求的元素不尽相同,具体情况可通过 创意形式查询工具 进行查询。

使用步骤

step 1. 加载 Marketing UI 组件包

参考 如何安装组件包

step 2. 加载组件

组件需要的创意配置数据 props.template ,为 Marketing API 获取创意形式信息接口 /adcreative_templates/get 返回中data.list数组的一项,这个值决定了表单中含有哪些创意元素。 为方便调试,我们为您准备了一份该接口返回数据示例,可将其保存为 mktui_adcreative_template.js,点此获取。 注意,实际使用组件时,请使用接口 /adcreative_templates/get 实时拉取。

import React, { Component } from 'react';
import { render } from 'react-dom';

import { AdCreative } from '@tencent/mktui';
const { AdCreativeForm, AdCreativeUtils } = AdCreative;
const { validator, utils } = AdCreativeUtils;
const { validateField, validateCreative } = validator;
const { genDefaultData } = utils;

// 注意,实际使用组件时,请使用接口 /adcreative_templates/get 实时拉取
import { adcreative_templates_get } from './mktui_adcreative_template.js';
const template = adcreative_templates_get.data.list[0]

// Demo中我们用到了lodash库
import _ from 'lodash';

step 3. 初始化创意表单

在Demo代码中初始化创意表单,并传入必须的属性,包括template, data, onChange, onSubmit 等等, 具体可参考 AdcreativeForm 组件文档。注意,为确保样式正确,需要用一个class含tsaui的div包含表单组件。

// mock API接口 /images/get 返回
const images_get_resp = {
    'data': {
        'list':
            [{
                'image_id': '4152626:9e77ffd034e06de52a032664b4616b28',
                'signature': '9e77ffd034e06de52a032664b4616b28',
                'type': 'IMAGE_TYPE_JPG',
                'height': 560,
                'width': 1000,
                'file_size': 75643,
                'preview_url': 'https://i.gtimg.cn/qzone/biz/gdt/portal/styles/images/logo@2x.png'
            }],
        'page_info':
        {
            'page': 1,
            'page_size': 10,
            'total_number': 1,
            'total_page': 1
        }
    },
    'code': 0,
    'message': ''
};

class Example extends Component {
    constructor(props) {
        super(props);

        this.state = {
            // data: Object.assign(genDefaultData(template), { image: '415xxxx:9e77ffd034e06xxxxxxxxxxxx6b28' }),
            data: genDefaultData(template),
            errorTips: {},
            showError: false
        }

        this.config = {
            imageUploadUrl: '/images/add',
            videoUploadUrl: '/videos/add',
            getImagePreviewUrl: '/images/get',
            getVideoPreviewUrl: '/videos/get'
        }

        this.handleChange = this.handleChange.bind(this)
        this.handleErrorTipsChange = this.handleErrorTipsChange.bind(this)
        this.handleSubmit = this.handleSubmit.bind(this)
        this.handleMediaUploadError = this.handleMediaUploadError.bind(this)
        this.handleGetMediaUrlError = this.handleGetMediaUrlError.bind(this)
        this.getMediaUrlById = this.getMediaUrlById.bind(this)
    }

    handleChange(data) {
        this.setState({
            data
        })
    }

    handleErrorTipsChange(errorTips) {
        this.setState({
            errorTips
        })
    }

    handleMediaUploadError(path, errorMsg, resp) {
        // demo数据调试
        console.log(path + ' 字段媒体上传失败(' + errorMsg + '), 接口返回如下:')
        console.log(resp)

        // mock 数据, 文件上传失败后设置一个mock值, 并重新校验表单
        const { data } = this.state
        const newData = _.cloneDeep(data)
        _.set(newData, path, 'mock_media_id')
        const errorTips = validateCreative(newData, template)

        this.setState({
            data: newData,
            errorTips
        })
    }

    handleGetMediaUrlError(path, errorMsg, resp) {

        // demo数据调试
        console.log(path + ' 字段图片URL获取失败(' + errorMsg + '), 接口返回如下:')
        console.log(resp)
    }

    getMediaUrlById(mediaId, fieldConfig) {
        return new Promise((resolve, reject) => {
            if (mediaId) {
                /* 通过image_id获取其url */
                if (fieldConfig.element_type === 'ELEMENT_TYPE_IMAGE') {
                    let url = _.get(images_get_resp, 'data.list[0].preview_url')
                    resolve(url);
                }
            } else {
                reject(new Error('no media id found'));
            }
        });
    }

    handleSubmit() {
        const { data } = this.state

        // validate the form
        let errorTips = validateCreative(data, template)

        this.setState({
            errorTips,
            showError: true
        })

        // demo数据调试
        console.log('demo演示,表单数据:')
        console.log(data)
    }

    render() {
        const { data, errorTips, showError } = this.state

        return (
            <div className=tsaui-adcreative-form-example tsaui>
                <AdCreativeForm
                    template={template}
                    config={this.config}

                    data={data}
                    onChange={this.handleChange}

                    showError={showError}
                    errorTips={errorTips}
                    onErrorTipsChange={this.handleErrorTipsChange}
                    validateField={validateField}

                    onMediaUploadError={this.handleMediaUploadError}
                    onGetMediaUrlError={this.handleGetMediaUrlError}

                    getMediaUrlById={this.getMediaUrlById}
                />
                <button type=button className=btn btn-primary onClick={this.handleSubmit} >提交(console中查看)</button>
            </div>
        );
    }
}

render(<Example />, document.getElementById('test'));