HTML5中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

這篇文章給大家介紹 HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù),內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比荔波網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式荔波網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋荔波地區(qū)。費(fèi)用合理售后完善,10多年實(shí)體公司更值得信賴。

1. 創(chuàng)建一個(gè)樹(shù)狀結(jié)構(gòu)

有了解過(guò)HT for Web的朋友,對(duì)樹(shù)狀結(jié)構(gòu)數(shù)據(jù)的創(chuàng)建應(yīng)該都不陌生,在這里我就不做深入的探討了。樹(shù)狀結(jié)構(gòu)數(shù)據(jù)的創(chuàng)建很簡(jiǎn)單,在這里為了讓代碼更簡(jiǎn)潔,我封裝了三個(gè)方法來(lái)創(chuàng)建樹(shù)狀結(jié)構(gòu)數(shù)據(jù),具體代碼如下:

/**
 * 創(chuàng)建連線
 * @param {ht.DataModel} dataModel - 數(shù)據(jù)容器
 * @param {ht.Node} source - 起點(diǎn)
 * @param {ht.Node} target - 終點(diǎn)
 */
function createEdge(dataModel, source, target) {
    // 創(chuàng)建連線,鏈接父親節(jié)點(diǎn)及孩子節(jié)點(diǎn)
    var edge = new ht.Edge();
    edge.setSource(source);
    edge.setTarget(target);
    dataModel.add(edge);
}

/**
 * 創(chuàng)建節(jié)點(diǎn)對(duì)象
 * @param {ht.DataModel} dataModel - 數(shù)據(jù)容器
 * @param {ht.Node} [parent] - 父親節(jié)點(diǎn)
 * @returns {ht.Node} 節(jié)點(diǎn)對(duì)象
 */
function createNode(dataModel, parent) {
    var node = new ht.Node();
    if (parent) {
        // 設(shè)置父親節(jié)點(diǎn)
        node.setParent(parent);

createEdge(dataModel, parent, node);
    }
    // 添加到數(shù)據(jù)容器中
    dataModel.add(node);
    return node;
}

/**
 * 創(chuàng)建結(jié)構(gòu)樹(shù)
 * @param {ht.DataModel} dataModel - 數(shù)據(jù)容器
 * @param {ht.Node} parent - 父親節(jié)點(diǎn)
 * @param {Number} level - 深度
 * @param {Array} count - 每層節(jié)點(diǎn)個(gè)數(shù)
 * @param {function(ht.Node, Number, Number)} callback - 回調(diào)函數(shù)(節(jié)點(diǎn)對(duì)象,節(jié)點(diǎn)對(duì)應(yīng)的層級(jí),節(jié)點(diǎn)在層級(jí)中的編號(hào))
 */
function createTreeNodes(dataModel, parent, level, count, callback) {
    level--;
    var num = (typeof count === 'number' ? count : count[level]);

while (num--) {
        var node = createNode(dataModel, parent);
        // 調(diào)用回調(diào)函數(shù),用戶可以在回調(diào)里面設(shè)置節(jié)點(diǎn)相關(guān)屬性
        callback(node, level, num);
        if (level === 0) continue;
        // 遞歸調(diào)用創(chuàng)建孩子節(jié)點(diǎn)
        createTreeNodes(dataModel, node, level, count, callback);
    }
}

嘿嘿,代碼寫得可能有些復(fù)雜了,簡(jiǎn)單的做法就是嵌套幾個(gè)for循環(huán)來(lái)創(chuàng)建樹(shù)狀結(jié)構(gòu)數(shù)據(jù),在這里我就不多說(shuō)了,接下來(lái)我們來(lái)探究第二個(gè)問(wèn)題。

2. 在2D拓?fù)湎履M3D樹(shù)狀結(jié)構(gòu)每層的半徑計(jì)算

在3D下的樹(shù)狀結(jié)構(gòu)體***的問(wèn)題就在于,每個(gè)節(jié)點(diǎn)的層次及每層節(jié)點(diǎn)圍繞其父親節(jié)點(diǎn)的半徑計(jì)算?,F(xiàn)在樹(shù)狀結(jié)構(gòu)數(shù)據(jù)已經(jīng)有了,那么接下來(lái)就該開(kāi)始計(jì)算半徑了,我們從兩層樹(shù)狀結(jié)構(gòu)開(kāi)始推算:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

我現(xiàn)在先創(chuàng)建了兩層的樹(shù)狀結(jié)構(gòu),所有的子節(jié)點(diǎn)是一字排開(kāi),并沒(méi)有環(huán)繞其父親節(jié)點(diǎn),那么我們?cè)撊绾稳ゴ_定這些孩子節(jié)點(diǎn)的位置呢?

首先我們得知道,每個(gè)末端節(jié)點(diǎn)都有一圈屬于自己的領(lǐng)域,不然節(jié)點(diǎn)與節(jié)點(diǎn)之間將會(huì)存在重疊的情況,所以在這里,我們假定末端節(jié)點(diǎn)的領(lǐng)域半徑為25,那 么兩個(gè)相鄰節(jié)點(diǎn)之間的最短距離將是兩倍的節(jié)點(diǎn)領(lǐng)域半徑,也就是50,而這些末端節(jié)點(diǎn)將均勻地圍繞在其父親節(jié)點(diǎn)四周,那么相鄰兩個(gè)節(jié)點(diǎn)的張角就可以確認(rèn)出 來(lái),有了張角,有了兩點(diǎn)間的距離,那么節(jié)點(diǎn)繞其父親節(jié)點(diǎn)的最短半徑也就能計(jì)算出來(lái)了,假設(shè)張角為a,兩點(diǎn)間最小距離為b,那么最小半徑r的計(jì)算公式為:

r = b / 2 / sin(a / 2);

那么接下來(lái)我么就來(lái)布局下這個(gè)樹(shù),代碼是這樣寫的:

/**
 * 布局樹(shù)
 * @param {ht.Node} root - 根節(jié)點(diǎn)
 * @param {Number} [minR] - 末端節(jié)點(diǎn)的最小半徑
 */
function layout(root, minR) {
    // 設(shè)置默認(rèn)半徑
    minR = (minR == null ? 25 : minR);
    // 獲取到所有的孩子節(jié)點(diǎn)對(duì)象數(shù)組
    var children = root.getChildren().toArray();
    // 獲取孩子節(jié)點(diǎn)個(gè)數(shù)
    var len = children.length;
    // 計(jì)算張角
    var degree = Math.PI * 2 / len;
    // 根據(jù)三角函數(shù)計(jì)算繞父親節(jié)點(diǎn)的半徑
    var sin = Math.sin(degree / 2),
        r = minR / sin;
    // 獲取父親節(jié)點(diǎn)的位置坐標(biāo)
    var rootPosition = root.p();

children.forEach(function(child, index) {
        // 根據(jù)三角函數(shù)計(jì)算每個(gè)節(jié)點(diǎn)相對(duì)于父親節(jié)點(diǎn)的偏移量
        var s = Math.sin(degree * index),
            c = Math.cos(degree * index),
            x = s * r,
            y = c * r;

// 設(shè)置孩子節(jié)點(diǎn)的位置坐標(biāo)
        child.p(x + rootPosition.x, y + rootPosition.y);
    });
}

在代碼中,你會(huì)發(fā)現(xiàn)我將末端半徑默認(rèn)設(shè)置為25了,如此,我們通過(guò)調(diào)用layout()方法就可以對(duì)結(jié)構(gòu)樹(shù)進(jìn)行布局了,其布局效果如下:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

從效果圖可以看得出,末端節(jié)點(diǎn)的默認(rèn)半徑并不是很理想,布局出來(lái)的效果連線都快看不到了,因此我們可以增加末端節(jié)點(diǎn)的默認(rèn)半徑來(lái)解決布局太密的問(wèn)題,如將默認(rèn)半徑設(shè)置成40的效果圖如下:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

現(xiàn)在兩層的樹(shù)狀分布解決了,那么我們來(lái)看看三層的樹(shù)狀分布該如何處理。

將第二層和第三層看成一個(gè)整體,那么其實(shí)三層的樹(shù)狀結(jié)構(gòu)跟兩層是一樣的,不同的是在處理第二層節(jié)點(diǎn)時(shí),應(yīng)該將其看做一個(gè)兩層的樹(shù)狀結(jié)構(gòu)來(lái)處理,那么像這種規(guī)律的處理用遞歸***不過(guò)了,因此我們將代碼稍微該著下,在看看效果如何:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

不行,節(jié)點(diǎn)都重疊在一起了,看來(lái)簡(jiǎn)單的遞歸是不行的,那么具體的問(wèn)題出在哪里呢?

仔細(xì)分析了下,發(fā)現(xiàn)父親節(jié)點(diǎn)的領(lǐng)域半徑是由其孩子節(jié)點(diǎn)的領(lǐng)域半徑?jīng)Q定的,因此在布局時(shí)需要知道自身節(jié)點(diǎn)的領(lǐng)域半徑,而且節(jié)點(diǎn)的位置取決于父親節(jié)點(diǎn)的領(lǐng)域半徑及位置信息,這樣一來(lái)就無(wú)法邊計(jì)算半徑邊布局節(jié)點(diǎn)位置了。

那么現(xiàn)在只能將半徑的計(jì)算和布局分開(kāi)來(lái),做兩步操作了,我們先來(lái)分析下節(jié)點(diǎn)半徑的計(jì)算:

首先需要明確最關(guān)鍵的條件,父親節(jié)點(diǎn)的半徑取決于其孩子節(jié)點(diǎn)的半徑,這個(gè)條件告訴我們,只能從下往上計(jì)算節(jié)點(diǎn)半徑,因此我們?cè)O(shè)計(jì)的遞歸函數(shù)必須是先遞歸后計(jì)算,廢話不多說(shuō),我們來(lái)看下具體的代碼實(shí)現(xiàn):

/**
 * 就按節(jié)點(diǎn)領(lǐng)域半徑
 * @param {ht.Node} root - 根節(jié)點(diǎn)對(duì)象
 * @param {Number} minR - 最小半徑
 */
function countRadius(root, minR) {
    minR = (minR == null ? 25 : minR);

// 若果是末端節(jié)點(diǎn),則設(shè)置其半徑為最小半徑
    if (!root.hasChildren()) {
        root.a('radius', minR);
        return;
    }

// 遍歷孩子節(jié)點(diǎn)遞歸計(jì)算半徑
    var children = root.getChildren();
    children.each(function(child) {
        countRadius(child, minR);
    });

var child0 = root.getChildAt(0);
    // 獲取孩子節(jié)點(diǎn)半徑
    var radius = child0.a('radius');

// 計(jì)算子節(jié)點(diǎn)的1/2張角
    var degree = Math.PI / children.size();
    // 計(jì)算父親節(jié)點(diǎn)的半徑
    var pRadius = radius / Math.sin(degree);

// 設(shè)置父親節(jié)點(diǎn)的半徑及其孩子節(jié)點(diǎn)的布局張角
    root.a('radius', pRadius);
    root.a('degree', degree * 2);
}

OK,半徑的計(jì)算解決了,那么接下來(lái)就該解決布局問(wèn)題了,布局樹(shù)狀結(jié)構(gòu)數(shù)據(jù)需要明確:孩子節(jié)點(diǎn)的坐標(biāo)位置取決于其父親節(jié)點(diǎn)的坐標(biāo)位置,因此布局的遞歸方式和計(jì)算半徑的遞歸方式不同,我們需要先布局父親節(jié)點(diǎn)再遞歸布局孩子節(jié)點(diǎn),具體看看代碼吧:

/**
* 布局樹(shù)
* @param {ht.Node} root - 根節(jié)點(diǎn)
*/
function layout(root) {
    // 獲取到所有的孩子節(jié)點(diǎn)對(duì)象數(shù)組
    var children = root.getChildren().toArray();
    // 獲取孩子節(jié)點(diǎn)個(gè)數(shù)
    var len = children.length;
    // 計(jì)算張角
    var degree = root.a('degree');
    // 根據(jù)三角函數(shù)計(jì)算繞父親節(jié)點(diǎn)的半徑
    var r = root.a('radius');
    // 獲取父親節(jié)點(diǎn)的位置坐標(biāo)
    var rootPosition = root.p();

children.forEach(function(child, index) {
        // 根據(jù)三角函數(shù)計(jì)算每個(gè)節(jié)點(diǎn)相對(duì)于父親節(jié)點(diǎn)的偏移量
        var s = Math.sin(degree * index),
            c = Math.cos(degree * index),
            x = s * r,
            y = c * r;

// 設(shè)置孩子節(jié)點(diǎn)的位置坐標(biāo)
        child.p(x + rootPosition.x, y + rootPosition.y);

// 遞歸調(diào)用布局孩子節(jié)點(diǎn)
        layout(child);
    });
}

代碼寫完了,接下來(lái)就是見(jiàn)證奇跡的時(shí)刻了,我們來(lái)看看效果圖吧:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

不對(duì)呀,代碼應(yīng)該是沒(méi)問(wèn)題的呀,為什么顯示出來(lái)的效果還是會(huì)重疊呢?不過(guò)仔細(xì)觀察我們可以發(fā)現(xiàn)相比上個(gè)版本的布局會(huì)好很多,至少這次只是末端節(jié)點(diǎn)重疊了,那么問(wèn)題出在哪里呢?

不知道大家有沒(méi)有發(fā)現(xiàn),排除節(jié)點(diǎn)自身的大小,倒數(shù)第二層節(jié)點(diǎn)與節(jié)點(diǎn)之間的領(lǐng)域是相切的,那么也就是說(shuō)節(jié)點(diǎn)的半徑不僅和其孩子節(jié)點(diǎn)的半徑有關(guān),還與其孫子節(jié)點(diǎn)的半徑有關(guān),那我們把計(jì)算節(jié)點(diǎn)半徑的方法改造下,將孫子節(jié)點(diǎn)的半徑也考慮進(jìn)去再看看效果如何,改造后的代碼如下:

/**
* 就按節(jié)點(diǎn)領(lǐng)域半徑
* @param {ht.Node} root - 根節(jié)點(diǎn)對(duì)象
* @param {Number} minR - 最小半徑
*/
function countRadius(root, minR) {
   ……

var child0 = root.getChildAt(0);
    // 獲取孩子節(jié)點(diǎn)半徑
    var radius = child0.a('radius');

var child00 = child0.getChildAt(0);
    // 半徑加上孫子節(jié)點(diǎn)半徑,避免節(jié)點(diǎn)重疊
    if (child00) radius += child00.a('radius');

……
}

下面就來(lái)看看效果吧~

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

哈哈,看來(lái)我們分析對(duì)了,果然就不再重疊了,那我們來(lái)看看再多一層節(jié)點(diǎn)會(huì)是怎么樣的壯觀場(chǎng)景呢?

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

哦,NO!這不是我想看到的效果,又重疊了,好討厭。

不要著急,我們?cè)賮?lái)仔細(xì)分析分析下,在前面,我們提到過(guò)一個(gè)名詞——領(lǐng)域半徑,什么是領(lǐng)域半徑呢?很簡(jiǎn)單,就是可以容納下自身及其所有孩子節(jié)點(diǎn)的最 小半徑,那么問(wèn)題就來(lái)了,末端節(jié)點(diǎn)的領(lǐng)域半徑為我們指定的最小半徑,那么倒數(shù)第二層的領(lǐng)域半徑是多少呢?并不是我們前面計(jì)算出來(lái)的半徑,而應(yīng)該加上末端節(jié) 點(diǎn)自身的領(lǐng)域半徑,因?yàn)樗鼈冎g存在著包含關(guān)系,子節(jié)點(diǎn)的領(lǐng)域必須包含于其父親節(jié)點(diǎn)的領(lǐng)域中,那我們?cè)诳纯瓷蠄D,是不是感覺(jué)末端節(jié)點(diǎn)的領(lǐng)域被侵占了。那么 我們前面計(jì)算出來(lái)的半徑代表著什么呢?前面計(jì)算出來(lái)的半徑其實(shí)代表著孩子節(jié)點(diǎn)的布局半徑,在布局的時(shí)候是通過(guò)該半徑來(lái)布局的。

OK,那我們來(lái)總結(jié)下,節(jié)點(diǎn)的領(lǐng)域半徑是其下每層節(jié)點(diǎn)的布局半徑之和,而布局半徑需要根據(jù)其孩子節(jié)點(diǎn)個(gè)數(shù)及其領(lǐng)域半徑共同決定。

好了,我們現(xiàn)在知道問(wèn)題的所在了,那么我們的代碼該如何去實(shí)現(xiàn)呢?接著往下看:

/**
* 就按節(jié)點(diǎn)領(lǐng)域半徑及布局半徑
* @param {ht.Node} root - 根節(jié)點(diǎn)對(duì)象
* @param {Number} minR - 最小半徑
*/
function countRadius(root, minR) {
    minR = (minR == null ? 25 : minR);

// 若果是末端節(jié)點(diǎn),則設(shè)置其布局半徑及領(lǐng)域半徑為最小半徑
    if (!root.hasChildren()) {
        root.a('radius', minR);
        root.a('totalRadius', minR);
        return;
    }

// 遍歷孩子節(jié)點(diǎn)遞歸計(jì)算半徑
    var children = root.getChildren();
    children.each(function(child) {
        countRadius(child, minR);
    });

var child0 = root.getChildAt(0);
    // 獲取孩子節(jié)點(diǎn)半徑
    var radius = child0.a('radius'),
        totalRadius = child0.a('totalRadius');

// 計(jì)算子節(jié)點(diǎn)的1/2張角
    var degree = Math.PI / children.size();
    // 計(jì)算父親節(jié)點(diǎn)的布局半徑
    var pRadius = totalRadius / Math.sin(degree);

// 緩存父親節(jié)點(diǎn)的布局半徑
    root.a('radius', pRadius);
    // 緩存父親節(jié)點(diǎn)的領(lǐng)域半徑
    root.a('totalRadius', pRadius + totalRadius);
    // 緩存其孩子節(jié)點(diǎn)的布局張角
    root.a('degree', degree * 2);
}

在代碼中我們將節(jié)點(diǎn)的領(lǐng)域半徑緩存起來(lái),從下往上一層一層地疊加上去。接下來(lái)我們一起驗(yàn)證其正確性:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

搞定,就是這樣子了,2D拓?fù)渖厦娴牟季指愣?,那么接下?lái)該出動(dòng)3D拓?fù)淅瞺

3. 加入z軸坐標(biāo),呈現(xiàn)3D下的樹(shù)狀結(jié)構(gòu)

3D拓?fù)渖厦娌季譄o(wú)非就是多加了一個(gè)坐標(biāo)系,而且這個(gè)坐標(biāo)系只是控制節(jié)點(diǎn)的高度而已,并不會(huì)影響到節(jié)點(diǎn)之間的重疊,所以接下來(lái)我們來(lái)改造下我們的程序,讓其能夠在3D上正常布局。

也不需要太大的改造,我們只需要修改下布局器并且將2D拓?fù)浣M件改成3D拓?fù)浣M件就可以了。

/**
* 布局樹(shù)
* @param {ht.Node} root - 根節(jié)點(diǎn)
*/
function layout(root) {
    // 獲取到所有的孩子節(jié)點(diǎn)對(duì)象數(shù)組
    var children = root.getChildren().toArray();
    // 獲取孩子節(jié)點(diǎn)個(gè)數(shù)
    var len = children.length;
    // 計(jì)算張角
    var degree = root.a('degree');
    // 根據(jù)三角函數(shù)計(jì)算繞父親節(jié)點(diǎn)的半徑
    var r = root.a('radius');
    // 獲取父親節(jié)點(diǎn)的位置坐標(biāo)
    var rootPosition = root.p3();

children.forEach(function(child, index) {
        // 根據(jù)三角函數(shù)計(jì)算每個(gè)節(jié)點(diǎn)相對(duì)于父親節(jié)點(diǎn)的偏移量
        var s = Math.sin(degree * index),
            c = Math.cos(degree * index),
            x = s * r,
            z = c * r;

// 設(shè)置孩子節(jié)點(diǎn)的位置坐標(biāo)
        child.p3(x + rootPosition[0], rootPosition[1] - 100, z + rootPosition[2]);

// 遞歸調(diào)用布局孩子節(jié)點(diǎn)
        layout(child);
    });
}

上面是改造成3D布局后的布局器代碼,你會(huì)發(fā)現(xiàn)和2D的布局器代碼就差一個(gè)坐標(biāo)系的的計(jì)算,其他的都一樣,看下在3D上布局的效果:

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

恩,有模有樣的了,在文章的開(kāi)頭,我們可以看到每一層的節(jié)點(diǎn)都有不同的顏色及大小,這些都是比較簡(jiǎn)單,在這里我就不做深入的講解,具體的代碼實(shí)現(xiàn)如下:

var level = 4,
    size = (level + 1) * 20;

var root = createNode(dataModel);
root.setName('root');
root.p(100, 100);

root.s('shape3d', 'sphere');
root.s('shape3d.color', randomColor());
root.s3(size, size, size);

var colors = {},
    sizes = {};
createTreeNodes(dataModel, root, level - 1, 5, function(data, level, num) {
    if (!colors[level]) {
        colors[level] = randomColor();
        sizes[level] = (level + 1) * 20;
    }

size = sizes[level];

data.setName('item-' + level + '-' + num);
    // 設(shè)置節(jié)點(diǎn)形狀為球形
    data.s('shape3d', 'sphere');
    data.s('shape3d.color', colors[level]);
    data.s3(size, size, size);
});

在這里引入了一個(gè)隨機(jī)生成顏色值的方法,對(duì)每一層隨機(jī)生成一種顏色,并將節(jié)點(diǎn)的形狀改成了球形,讓頁(yè)面看起來(lái)美觀些(其實(shí)很丑)。

HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)

關(guān)于 HTML5 中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

網(wǎng)站欄目:HTML5中怎么實(shí)現(xiàn)一個(gè)3D網(wǎng)絡(luò)拓?fù)錁?shù)
分享鏈接:http://muchs.cn/article34/pdpcpe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、自適應(yīng)網(wǎng)站小程序開(kāi)發(fā)、域名注冊(cè)虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)