Hadoop數(shù)據(jù)分析平臺實戰(zhàn)——250JSSDK數(shù)據(jù)收集引擎編寫

離線數(shù)據(jù)分析平臺實戰(zhàn)——250JSSDK數(shù)據(jù)收集引擎編寫

JsSDK設(shè)計規(guī)則

在js sdk中我們需要收集launch、pageview话浇、chargeRequest和eventDuration四種數(shù)據(jù),
所以我們需要在js中寫入四個方法來分別收集這些數(shù)據(jù)这揣,
另外我們還需要提供一些操作cookie和發(fā)送數(shù)據(jù)的的公用方法踊谋。

Paste_Image.png

SDK測試

啟動集群上的hdfs+nginx+flume進(jìn)程立由,
通過模擬數(shù)據(jù)的發(fā)送然后將數(shù)據(jù)發(fā)送到nginx服務(wù)器中,
查看最終是否在hdfs中有數(shù)據(jù)的寫入洼裤。

命令:

啟動hdfs

start-dfs.sh: 命令
su root:切換用戶

啟動nginx

service nginx restart: 進(jìn)程

啟動flume進(jìn)程:

進(jìn)入flume安裝根目錄邻辉,執(zhí)行命令:
flume-ng agent --conf ./conf/ --conf-file ./conf/test2.conf --name agent &

參考資料

一、將analytics.js集成到你想收集收集的頁面即可逸邦。
集成方式主要分為以下兩種:
    1) 第一種方式
        `將analytics.js集成到所有頁面的的頭部恩沛,然后通過提供的方法調(diào)用進(jìn)行數(shù)據(jù)收集。
        <script src='//www.bjsxt.com/js/common/analytics.js'></script>
        <script>__AE__.setMemberId("123456");</script>
    2) 第二種方式
        `使用javascript代碼缕减,異步引入analytics.js文件雷客,在引入之前可以通過_aelog_設(shè)置會員id
        <script type="text/javascript">
            var _aelog_ = _aelog_ || window._aelog_ || [];
            _aelog_.push(['member_id', '123456']); // 如果此時用戶已經(jīng)登錄,那么通過才參數(shù)指定用戶id
            window._aelog_ = _aelog_;
        
            (function() {
                var amwae = document.createElement('script');
                amwae.type = 'text/javascript';
                amwae.async = true;
                amwae.src = '//www.beifeng.com/js/common/analytics.js'; // 指定鏈接
                var script = document.getElementsByTagName('script')[0];
                script.parentNode.insertBefore(amwae, script);
            })();
        </script>
注意:當(dāng)用戶登錄后桥狡,請調(diào)用__AE__.setMemberId('123456')方法進(jìn)行會員id的設(shè)置搅裙,方便用戶數(shù)據(jù)的收集。
(function(){
    var CookieUtil = {
            // get the cookie of the key is name
            get: function(name) {
                var cookieName = encodeURIComponent(name) + "=",
                    cookieStart = document.cookie.indexOf(cookieName),
                    cookieValue = null;
                if (cookieStart > -1) {
                    var cookieEnd = document.cookie.indexOf(";", cookieStart);
                    if (cookieEnd == -1) {
                        cookieEnd = document.cookie.length;
                    }
                    cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length, cookieEnd));
                }
                return cookieValue;
            },
            // set the name/value pair to browser cookie
            set: function(name, value, expires, path, domain, secure) {
                var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);

                if (expires) {
                    // set the expires time
                    var expiresTime = new Date();
                    expiresTime.setTime(expires);
                    cookieText += ";expires=" +  expiresTime.toGMTString();
                }

                if (path) {
                    cookieText += ";path=" + path;
                }

                if (domain) {
                    cookieText += ";domain=" + domain;
                }

                if (secure) {
                    cookieText += ";secure";
                }

                document.cookie = cookieText;
            },
            setExt: function(name, value) {
                this.set(name, value, new Date().getTime() + 315360000000, "/");
            }
    };

    // 主體裹芝,其實就是tracker js
    var tracker = {
            // config
            clientConfig: {
                serverUrl: "http://hh/log.gif",
                sessionTimeout: 360, // 360s -> 6min
                maxWaitTime: 3600, // 3600s -> 60min -> 1h
                ver: "1"
            },

            cookieExpiresTime: 315360000000, // cookie過期時間部逮,10年
            
            columns: {
                // 發(fā)送到服務(wù)器的列名稱
                eventName: "en",
                version: "ver",
                platform: "pl",
                sdk: "sdk",
                uuid: "u_ud",
                memberId: "u_mid",
                sessionId: "u_sd",
                clientTime: "c_time",
                language: "l",
                userAgent: "b_iev",
                resolution: "b_rst",
                currentUrl: "p_url",
                referrerUrl: "p_ref",
                title: "tt",
                orderId: "oid",
                orderName: "on",
                currencyAmount: "cua",
                currencyType: "cut",
                paymentType: "pt",
                category: "ca",
                action: "ac",
                kv: "kv_",
                duration: "du"
            },

            keys: {
                pageView: "e_pv",
                chargeRequestEvent: "e_crt",
                launch: "e_l",
                eventDurationEvent: "e_e",
                sid: "cktrack_sid",
                uuid: "cktrack_uuid",
                mid: "cktrack_mid",
                preVisitTime: "cktrack_previsit",
                
            },

            /**
             * 獲取會話id
             */
            getSid: function() {
                return CookieUtil.get(this.keys.sid);
            },

            /**
             * 保存會話id到cookie
             */
            setSid: function(sid) {
                if (sid) {
                    CookieUtil.setExt(this.keys.sid, sid);
                }
            },

            /**
             * 獲取uuid,從cookie中
             */
            getUuid: function() {
                return CookieUtil.get(this.keys.uuid);
            },

            /**
             * 保存uuid到cookie
             */
            setUuid: function(uuid) {
                if (uuid) {
                    CookieUtil.setExt(this.keys.uuid, uuid);
                }
            },

            /**
             * 獲取memberID
             */
            getMemberId: function() {
                return CookieUtil.get(this.keys.mid);
            },

            /**
             * 設(shè)置mid
             */
            setMemberId: function(mid) {
                if (mid) {
                    CookieUtil.setExt(this.keys.mid, mid);
                }
            },

            startSession: function() {
                // 加載js就觸發(fā)的方法
                if (this.getSid()) {
                    // 會話id存在嫂易,表示uuid也存在
                    if (this.isSessionTimeout()) {
                        // 會話過期,產(chǎn)生新的會話
                        this.createNewSession();
                    } else {
                        // 會話沒有過期兄朋,更新最近訪問時間
                        this.updatePreVisitTime(new Date().getTime());
                    }
                } else {
                    // 會話id不存在,表示uuid也不存在
                    this.createNewSession();
                }
                this.onPageView();
            },

            onLaunch: function() {
                // 觸發(fā)launch事件
                var launch = {};
                launch[this.columns.eventName] = this.keys.launch; // 設(shè)置事件名稱
                this.setCommonColumns(launch); // 設(shè)置公用columns
                this.sendDataToServer(this.parseParam(launch)); // 最終發(fā)送編碼后的數(shù)據(jù)
            },

            onPageView: function() {
                // 觸發(fā)page view事件
                if (this.preCallApi()) {
                    var time = new Date().getTime();
                    var pageviewEvent = {};
                    pageviewEvent[this.columns.eventName] = this.keys.pageView;
                    pageviewEvent[this.columns.currentUrl] = window.location.href; // 設(shè)置當(dāng)前url
                    pageviewEvent[this.columns.referrerUrl] = document.referrer; // 設(shè)置前一個頁面的url
                    pageviewEvent[this.columns.title] = document.title; // 設(shè)置title
                    this.setCommonColumns(pageviewEvent); // 設(shè)置公用columns
                    this.sendDataToServer(this.parseParam(pageviewEvent)); // 最終發(fā)送編碼后的數(shù)據(jù)ss
                    this.updatePreVisitTime(time);
                }
            },

            onChargeRequest: function(orderId, name, currencyAmount, currencyType, paymentType) {
                // 觸發(fā)訂單產(chǎn)生事件
                if (this.preCallApi()) {
                    if (!orderId || !currencyType || !paymentType) {
                        this.log("訂單id怜械、貨幣類型以及支付方式不能為空");
                        return ;
                    }

                    if (typeof(currencyAmount) == "number") {
                        // 金額必須是數(shù)字
                        var time = new Date().getTime();
                        var chargeRequestEvent = {};
                        chargeRequestEvent[this.columns.eventName] = this.keys.chargeRequestEvent;
                        chargeRequestEvent[this.columns.orderId] = orderId;
                        chargeRequestEvent[this.columns.orderName] = name;
                        chargeRequestEvent[this.columns.currencyAmount] = currencyAmount;
                        chargeRequestEvent[this.columns.currencyType] = currencyType;
                        chargeRequestEvent[this.columns.paymentType] = paymentType;
                        this.setCommonColumns(chargeRequestEvent); // 設(shè)置公用columns
                        this.sendDataToServer(this.parseParam(chargeRequestEvent)); // 最終發(fā)送編碼后的數(shù)據(jù)ss
                        this.updatePreVisitTime(time);
                    } else {
                        this.log("訂單金額必須是數(shù)字");
                        return ;
                    }   
                }
            },
            
            onEventDuration: function(category, action, map, duration) {
                // 觸發(fā)event事件
                if (this.preCallApi()) {
                    if (category && action) {
                        var time = new Date().getTime();
                        var event = {};
                        event[this.columns.eventName] = this.keys.eventDurationEvent;
                        event[this.columns.category] = category;
                        event[this.columns.action] = action;
                        if (map) {
                            for (var k in map){
                                if (k && map[k]) {
                                    event[this.columns.kv + k] = map[k];
                                }
                            }
                        }
                        if (duration) {
                            event[this.columns.duration] = duration;
                        }
                        this.setCommonColumns(event); // 設(shè)置公用columns
                        this.sendDataToServer(this.parseParam(event)); // 最終發(fā)送編碼后的數(shù)據(jù)ss
                        this.updatePreVisitTime(time);
                    } else {
                        this.log("category和action不能為空");
                    }
                }
            },

            /**
             * 執(zhí)行對外方法前必須執(zhí)行的方法
             */
            preCallApi: function() {
                if (this.isSessionTimeout()) {
                    // 如果為true颅和,表示需要新建
                    this.startSession();
                } else {
                    this.updatePreVisitTime(new Date().getTime());
                }
                return true;
            },

            sendDataToServer: function(data) {
                // 發(fā)送數(shù)據(jù)data到服務(wù)器,其中data是一個字符串
                var that = this;
                var i2 = new Image(1,1);
                i2.onerror = function(){
                    // 這里可以進(jìn)行重試操作
                };
                i2.src = this.clientConfig.serverUrl + "?" + data;
            },

            /**
             * 往data中添加發(fā)送到日志收集服務(wù)器的公用部分
             */
            setCommonColumns: function(data) {
                data[this.columns.version] = this.clientConfig.ver;
                data[this.columns.platform] = "website";
                data[this.columns.sdk] = "js";
                data[this.columns.uuid] = this.getUuid(); // 設(shè)置用戶id
                data[this.columns.memberId] = this.getMemberId(); // 設(shè)置會員id
                data[this.columns.sessionId] = this.getSid(); // 設(shè)置sid
                data[this.columns.clientTime] = new Date().getTime(); // 設(shè)置客戶端時間
                data[this.columns.language] = window.navigator.language; // 設(shè)置瀏覽器語言
                data[this.columns.userAgent] = window.navigator.userAgent; // 設(shè)置瀏覽器類型
                data[this.columns.resolution] = screen.width + "*" + screen.height; // 設(shè)置瀏覽器分辨率
            },

            /**
             * 創(chuàng)建新的會員缕允,并判斷是否是第一次訪問頁面峡扩,如果是,進(jìn)行l(wèi)aunch事件的發(fā)送障本。
             */
            createNewSession: function() {
                var time = new Date().getTime(); // 獲取當(dāng)前操作時間
                // 1. 進(jìn)行會話更新操作
                var sid = this.generateId(); // 產(chǎn)生一個session id
                this.setSid(sid);
                this.updatePreVisitTime(time); // 更新最近訪問時間
                // 2. 進(jìn)行uuid查看操作
                if (!this.getUuid()) {
                    // uuid不存在教届,先創(chuàng)建uuid响鹃,然后保存到cookie,最后觸發(fā)launch事件
                    var uuid = this.generateId(); // 產(chǎn)品uuid
                    this.setUuid(uuid);
                    this.onLaunch();
                }
            },

            /**
             * 參數(shù)編碼返回字符串
             */
            parseParam: function(data) {
                var params = "";
                for (var e in data) {
                    if (e && data[e]) {
                        params += encodeURIComponent(e) + "=" + encodeURIComponent(data[e]) + "&";
                    }
                }
                if (params) {
                    return params.substring(0, params.length - 1);
                } else {
                    return params;
                }
            },

            /**
             * 產(chǎn)生uuid
             */
            generateId: function() {
                var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
                var tmpid = [];
                var r;
                tmpid[8] = tmpid[13] = tmpid[18] = tmpid[23] = '-';
                tmpid[14] = '4';

                for (i=0; i<36; i++) {
                    if (!tmpid[i]) {
                        r = 0| Math.random()*16;
                        tmpid[i] = chars[(i==19) ? (r & 0x3) | 0x8 : r];
                    }
                }
                return tmpid.join('');
            },

            /**
             * 判斷這個會話是否過期案训,查看當(dāng)前時間和最近訪問時間間隔時間是否小于this.clientConfig.sessionTimeout<br/>
             * 如果是小于买置,返回false;否則返回true。
             */
            isSessionTimeout: function() {
                var time = new Date().getTime();
                var preTime = CookieUtil.get(this.keys.preVisitTime);
                if (preTime) {
                    // 最近訪問時間存在,那么進(jìn)行區(qū)間判斷
                    return time - preTime > this.clientConfig.sessionTimeout * 1000;
                }
                return true;
            },

            /**
             * 更新最近訪問時間
             */
            updatePreVisitTime: function(time) {
                CookieUtil.setExt(this.keys.preVisitTime, time);
            },

            /**
             * 打印日志
             */
            log: function(msg) {
                console.log(msg);
            },
            
    };

    // 對外暴露的方法名稱
    window.__AE__ = {
        startSession: function() {
            tracker.startSession();
        },
        onPageView: function() {
            tracker.onPageView();
        },
        onChargeRequest: function(orderId, name, currencyAmount, currencyType, paymentType) {
            tracker.onChargeRequest(orderId, name, currencyAmount, currencyType, paymentType);
        },
        onEventDuration: function(category, action, map, duration) {
            tracker.onEventDuration(category, action, map, duration);
        },
        setMemberId: function(mid) {
            tracker.setMemberId(mid);
        }
    };

    // 自動加載方法
    var autoLoad = function() {
        // 進(jìn)行參數(shù)設(shè)置
        var _aelog_ = _aelog_ || window._aelog_ || [];
        var memberId = null;
        for (i=0;i<_aelog_.length;i++) {
            _aelog_[i][0] === "memberId" && (memberId = _aelog_[i][1]);
        }
        // 根據(jù)是給定memberid强霎,設(shè)置memberid的值
        memberId && __AE__.setMemberId(memberId);
        // 啟動session
        __AE__.startSession();
    };

    autoLoad();
})();

<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>測試頁面1</title>
<script type="text/javascript" src="./js/analytics.js"></script>
</head>
<body>
    測試頁面1<br/>
    跳轉(zhuǎn)到:
    <a href="demo.jsp">demo</a>
    <a href="demo2.jsp">demo2</a>
    <a href="demo3.jsp">demo3</a>
    <a href="demo4.jsp">demo4</a>
</body>
</html>
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>測試頁面2</title>
<script type="text/javascript" src="./js/analytics.js"></script>
</head>
<body>
    測試頁面2
    <br/>
    <label>orderid: 123456</label><br>
    <label>orderName: 測試訂單123456</label><br/>
    <label>currencyAmount: 524.01</label><br/>
    <label>currencyType: RMB</label><br/>
    <label>paymentType: alipay</label><br/>
    <button onclick="__AE__.onChargeRequest('123456','測試訂單123456',524.01,'RMB','alipay')">觸發(fā)chargeRequest事件</button><br/>
    跳轉(zhuǎn)到:
    <a href="demo.jsp">demo</a>
    <a href="demo2.jsp">demo2</a>
    <a href="demo3.jsp">demo3</a>
    <a href="demo4.jsp">demo4</a>
</body>
</html>
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>測試頁面3</title>
<script type="text/javascript" src="./js/analytics.js"></script>
</head>
<body>
    測試頁面3<br/>
    <label>category: event的category名稱</label><br/>
    <label>action: event的action名稱</label><br/>
    <label>map: {"key1":"value1", "key2":"value2"}</label><br/>
    <label>duration: 1245</label><br/>
    <button onclick="__AE__.onEventDuration('event的category名稱','event的action名稱', {'key1':'value1','key2':'value2'}, 1245)">觸發(fā)帶map和duration的事件</button><br/>
    <button onclick="__AE__.onEventDuration('event的category名稱','event的action名稱')">觸發(fā)不帶map和duration的事件</button><br/>
    跳轉(zhuǎn)到:
    <a href="demo.jsp">demo</a>
    <a href="demo2.jsp">demo2</a>
    <a href="demo3.jsp">demo3</a>
    <a href="demo4.jsp">demo4</a>
</body>
</html>
<%@ page contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>測試頁面4</title>
<script type="text/javascript">
(function(){
    var _aelog_ = _aelog_ || window._aelog_ || [];
    // 設(shè)置_aelog_相關(guān)屬性
    _aelog_.push(["memberId","ck"]);
    window._aelog_ = _aelog_;
    (function(){
        var aejs = document.createElement('script');
        aejs.type = 'text/javascript';
        aejs.async = true;
        aejs.src = './js/analytics.js';
        var script = document.getElementsByTagName('script')[0];
        script.parentNode.insertBefore(aejs, script);
    })();
})();
</script>
</head>
<body>
    測試頁面4<br/>
    在本頁面設(shè)置memberid為gerryliu<br/>
    跳轉(zhuǎn)到:
    <a href="demo.jsp">demo</a>
    <a href="demo2.jsp">demo2</a>
    <a href="demo3.jsp">demo3</a>
    <a href="demo4.jsp">demo4</a>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末堕义,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子脆栋,更是在濱河造成了極大的恐慌,老刑警劉巖洒擦,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椿争,死亡現(xiàn)場離奇詭異,居然都是意外死亡熟嫩,警方通過查閱死者的電腦和手機秦踪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掸茅,“玉大人椅邓,你說我怎么就攤上這事∶潦ǎ” “怎么了景馁?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逗鸣。 經(jīng)常有香客問我合住,道長,這世上最難降的妖魔是什么撒璧? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任透葛,我火速辦了婚禮,結(jié)果婚禮上卿樱,老公的妹妹穿的比我還像新娘僚害。我一直安慰自己,他們只是感情好繁调,可當(dāng)我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布萨蚕。 她就那樣靜靜地躺著,像睡著了一般涉馁。 火紅的嫁衣襯著肌膚如雪门岔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天烤送,我揣著相機與錄音寒随,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛妻往,可吹牛的內(nèi)容都是我干的互艾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼讯泣,長吁一口氣:“原來是場噩夢啊……” “哼纫普!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起好渠,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤昨稼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拳锚,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體假栓,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年霍掺,在試婚紗的時候發(fā)現(xiàn)自己被綠了匾荆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡杆烁,死狀恐怖牙丽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情兔魂,我是刑警寧澤烤芦,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站析校,受9級特大地震影響拍棕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜勺良,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一绰播、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尚困,春花似錦蠢箩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至逻谦,卻和暖如春掌实,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背邦马。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工贱鼻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留宴卖,地道東北人。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓邻悬,卻偏偏與公主長得像症昏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子父丰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容