日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Saiku Table展示数据合并bug修复(二十五)

發布時間:2023/12/13 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Saiku Table展示数据合并bug修复(二十五) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Saiku Table展示數據合并bug修復

?

Saiku以table的形式展示數據,如果點擊了 非空的字段 按鈕,則會自動進行數據合并,為空的數據行以及數據列都會自動隱藏掉。

?

首先我們應該定位問題:

1.查看接口返回值,會發現接口返回都正常,數值沒有任何問題,所以我們能清楚的知道與后臺沒有關系。

2.從頁面上定位問題,會發現是table渲染問題 :?/saiku-ui/js/saiku/render/SaikuTableRenderer.js? (如果是編譯好的saiku,請找到 saiku-server\tomcat\webapps\ROOT\js\saiku\render\SaikuTableRenderer.js??)

?

接下來我們來分析一下問題原因:

1.渲染頁面主要是 SaikuTableRenderer.js文件中的此方法:

  SaikuTableRenderer.prototype.internalRender = function(allData, options)

2.數據內容都存放在<table>標簽中,存放內容為 tableContent,tableContent包含所有的數據信息。

js代碼里面主要有兩層for循環,將數據取出然后以字符串形式拼湊到 tableContent 里面,最后返回到html頁面中渲染。

第一次是循環取出行數據信息

? for (var row = 0, rowLen = table.length; row < rowLen; row++)?

第二層是第一層循環中的行數據中取出對應的列數據,然后拼湊為<tr>標記的行數據 rowContent 里面?

?for (var col = 0, colLen = table[row].length; col < colLen; col++)?

3.主要邏輯:

有個boolean類型的 same 標記,用來判斷上下文數據信息是否一致,如果一致 same=true,后面就會自動合并

 var same = !headerSame && !isHeaderLowestLvl && (col == 0 || !topParentsDiffer(data, row, col)) && header.value === previousRow[col].value ;

我們主要來看一下這個值:header.value === previousRow[col].value ,意思就是說當前記錄列值與上一條記錄的列數據相同時,same就為true,讓其自動合并

  自動合并的原理: 將當前記錄的此列值置為空

   var value = (same ? "<div>&nbsp;</div>" : '<div rel="' + row + ":" + col + '">'?+ (sameAsPrevValue && Settings.ALLOW_TABLE_DATA_COLLAPSE ? '<span class="expander expanded" style="cursor: pointer;">&#9660;</span>' : '' ) + header.value + '</div>');

不斷的循環出當前行的列值,然后將列值拼湊為 rowContent

   rowContent += '<th class="' + cssclass + '" ' + (colspan > 0 ? ' colspan="' + colspan + '"' : "") + tipsy + '>' + value + '</th>';

但是下面還有個判斷,就是當數據(DATA_CELL 就是標記度量值信息)為空時,saiku會將當前rowContent置為空?

  

這里三個條件分別是:?

  用戶是否點擊了隱藏空數據按鈕,也就是我們開頭說的 非空的字段 按鈕 : option.hideEmpty

  當前數據信息 header.type屬性 是否為 DATA_CELL 類型

  當前行數據的指標信息是否都為空 (這里上方有代碼如判斷,我沒有全部截取圖片): rowWithOnlyEmptyCells

?

這樣子一來,問題就暴露啦

如果我有兩個部門的數據信息,每個部門個 3條數據,第一個部門三條數據都完整,第二個部門第一條數據 指標值都為空,后面兩條數據完整

以上邏輯就會這樣判斷:

  第一個部門數據正常展示,部門信息相同會自動合并,后面的數據也會正常展示,這個沒問題

  第二個部門的數據,第一條數據 首先部門不會合并到第一個部門,因為當前數據的部門value值與上一條記錄的部門value值不同,但是由于cell指標數據為空,所以 rowContent最后就會置為空,相當于不展示此條數據

  第二個部門第二條數據,部門數據會先判斷當前數據的value是否與上一條數據的value相同,結果會發現相同,就會把當前數據的部門信息置為空,后面因為有cell指標數據,所以后面就會展示這條rowContent信息,但是此條數據不完整了,沒有了部門名稱信息。

  第二個部門第三條數據同第二條數據一樣。

最后我們就會得出這樣的結果:

  第一個部門的數據正常展示

  第二個部門的數據由于都沒有部門信息就會自動合并到第一個部門去展示。

?

其次我們來講一下處理方案:

能定位到問題,了解問題原因離解決問題就不遠了哈哈哈哈

我這邊的處理方案是增加一個boolean類型標記值 headerFlag,用于決定same值,因為其實數據展示的時候是否合并就是在用same的取值

這個headerFlag值定義在兩個for循環以外,默認為true,意思就是默認情況下影響數據的合并展示

headerFlag定義

?

根據headerFlag的值來定義same值

當有rowContent被置為空的時候,就將headerFlag標記置為false,就是為了保證當前一行數據為空時,下一次不會自動將部門列信息置為空了

?

接下來我們就應該開始考慮什么時候講headerFlag標記轉為true了啦

?有以下兩種情況我們需要考慮到

>>>? 當前行的列數據值不等于上一行數據的列數據值時,表示這是一次新的判斷,我們將headerFlag置為true,一切按照原來的一樣

>>> 當前tableContent中包含當前行列數據信息時,表示當前列已經存在了,我們可以讓它去做合并了,就將headerFlag置為true.

?

這樣子我們就能處理好這個table自動合并的bug了,可能還有更好的辦法或者是有全的解法,如有還望不吝賜教哈,多謝~

?

最后提供完整的 SaikuTableRenderer.js文件(修改后的)

function SaikuTableRenderer(data, options) {this._data = data;this._options = _.extend({}, SaikuRendererOptions, options); }function getAxisLevelsName(data, axisName) {var queryData = data.query.queryModel.axes[axisName].hierarchies;var len = queryData.length;var arrLevels = [];for (var i = 0; i < len; i++) {for (var level in queryData[i].levels) {if (queryData[i].levels.hasOwnProperty(level)) {if (Settings.COLUMN_TITLE_TABLE_USE_LEVEL_CAPTION_NAME) {arrLevels.push(queryData[i].levels[level].caption);}else {arrLevels.push(level);}}}}return arrLevels; }function setStyleNegativeNumber(value) {var className = '';if (Settings.STYLE_NEGATIVE_NUMBER && parseFloat(value) < 0) {className = ' style_negative_number ';}return className; }function getAxisSize(data, axisName) {var queryData = data.query.queryModel.axes[axisName].hierarchies;var len = queryData.length;var axisSize = 0;for (var i = 0; i < len; i++) {axisSize += _.size(queryData[i].levels);}return axisSize; }function getDomColumnsLevelsName(htmlObject) {var $htmlObject = $(htmlObject.closest('.workspace').find('.workspace_fields').find('.columns.axis_fields').find('.hierarchy').find('.d_level'));var arrLevels = [];$.each($htmlObject, function(key, level) {if ($(level).attr('style') === 'display: list-item;') {if (Settings.COLUMN_TITLE_TABLE_USE_LEVEL_CAPTION_NAME) {arrLevels.push($(level).find('.level').attr('title'));}else {arrLevels.push($(level).find('.level').attr('level'));}}});return arrLevels; }/*table render method*/ SaikuTableRenderer.prototype.render = function(data, options) {var self = this;if (data) {this._data = data;}if (options) {this._options = _.extend({}, SaikuRendererOptions, options);}if (typeof this._data == "undefined") {return;}if (this._data != null && this._data.error != null) {return;}if (this._data == null || (this._data.cellset && this._data.cellset.length === 0)) {return;}this.hideEmpty = this._options.hideEmpty;if (this._options.htmlObject) { // $(this._options.htmlObject).stickyTableHeaders("destroy");// in case we have some left over scrollersif (self._options.hasOwnProperty('batch')) {$(self._options.htmlObject).parent().parent().unbind('scroll');}_.defer(function(that) {if (self._options.hasOwnProperty('batch') && !self._options.hasOwnProperty('batchSize')) {self._options['batchSize'] = 1000;}// the key method to render data by table form. 20190423var html = self.internalRender(self._data, self._options);$(self._options.htmlObject).html(html);// Render the totals summary$('#totals_summary').remove(); // Remove one previous totals div, if present$(self._options.htmlObject).after(self.renderSummary(data)); // Render the new summary// $(self._options.htmlObject).stickyTableHeaders( { container: self._options.htmlObject.parent().parent(), fixedOffset: self._options.htmlObject.parent().parent().offset().top });_.defer(function(that) {if (self._options.hasOwnProperty('batch') && self._options.hasBatchResult) {var batchRow = 0;var batchIsRunning = false;var batchIntervalSize = self._options.hasOwnProperty('batchIntervalSize') ? self._options.batchIntervalSize : 20;var batchIntervalTime = self._options.hasOwnProperty('batchIntervalTime') ? self._options.batchIntervalTime : 20;var len = self._options.batchResult.length;var batchInsert = function() {// maybe add check for reach table bottom - ($('.workspace_results').scrollTop() , $('.workspace_results table').height()if (!batchIsRunning && len > 0 && batchRow < len) {batchIsRunning = true;var batchContent = "";var startb = batchRow;for (var i = 0; batchRow < len && i < batchIntervalSize ; i++, batchRow++) {batchContent += self._options.batchResult[batchRow];}if (batchRow > startb) {$(self._options.htmlObject).append( $(batchContent));}batchIsRunning = false;}if (batchRow >= len) {$(self._options.htmlObject).parent().parent().unbind('scroll');}};var lazyBatchInsert = _.debounce(batchInsert, batchIntervalTime);$(self._options.htmlObject).parent().parent().scroll(function () {lazyBatchInsert();});}});return html;});} else {var html = this.internalRender(this._data, self._options);return html;}};SaikuTableRenderer.prototype.clear = function(data, options) {var self = this;if (this._options && this._options.htmlObject && this._options.hasOwnProperty('batch')) {$(self._options.htmlObject).parent().parent().unbind('scroll');}};SaikuTableRenderer.prototype.processData = function(data, options) {this._hasProcessed = true; };function genTotalDataCells(currentIndex, cellIndex, scanSums, scanIndexes, lists) {var contents = '';var lists = lists[ROWS];for (var i = scanSums.length - 1; i >= 0; i--) {if (currentIndex == scanSums[i]) {var currentListNode = lists[i][scanIndexes[i]];for (var m = 0; m < currentListNode.cells.length; m++) {contents += '<td class="data total">' + currentListNode.cells[m][cellIndex].value + '</td>';}scanIndexes[i]++;if (scanIndexes[i] < lists[i].length)scanSums[i] += lists[i][scanIndexes[i]].width;}}return contents; }function genTotalHeaderCells(currentIndex, bottom, scanSums, scanIndexes, lists, wrapContent) {var contents = '';for (var i = bottom; i >= 0; i--) {if (currentIndex == scanSums[i]) {var currentListNode = lists[i][scanIndexes[i]];var cssClass;if (i == 0 && bottom == 1)cssClass = "col";else if (i == bottom)cssClass = "col_total_corner";else if (i == bottom - 1 && currentListNode.captions)cssClass = "col_total_first";else cssClass = "col_null";for (var m = 0; m < currentListNode.cells.length; m++) {var text = '?';if (bottom == lists.length - 1) {if (currentListNode.captions) {text = lists[i][scanIndexes[i]].captions[m];}if (i == 0 && scanIndexes[i] == 0) {if (currentListNode.captions)text += "?";else text = "";text += (wrapContent ? "<span class='i18n'>Grand Total</span>" : "Grand Total");}}contents += '<th class="' + cssClass + '">'+ (wrapContent ? '<div>' + text + '</div>' : text ) + '</th>';}scanIndexes[i]++;if (scanIndexes[i] < lists[i].length)scanSums[i] += lists[i][scanIndexes[i]].width;}}return contents; }function totalIntersectionCells(currentIndex, bottom, scanSums, scanIndexes, lists) {var contents = '';for (var i = bottom; i >= 0; i--) {if (currentIndex == scanSums[i]) {var currentListNode = lists[i][scanIndexes[i]];var cssClass = "data total";for (var m = 0; m < currentListNode.cells.length; m++) {var text = '?';contents += '<td class="' + cssClass + '">' + text + '</td>';}scanIndexes[i]++;if (scanIndexes[i] < lists[i].length)scanSums[i] += lists[i][scanIndexes[i]].width;}}return contents; }function isNextTotalsRow(currentIndex, scanSums, scanIndexes, totalsLists, wrapContent) {var colLists = totalsLists[COLUMNS];var colScanSums = scanSums[COLUMNS];var colScanIndexes = scanIndexes[COLUMNS];var bottom = colLists.length - 2;var contents = -1;for (var i = bottom; i >= 0; i--) {if (currentIndex == colScanSums[i]) {for (var m = 0; m < colLists[i][colScanIndexes[i]].cells.length; m++) {contents += '<tr>';for (var j = 0; j <= bottom; j++) {var cssClass;var text = '?';if (i == 0 && j == 0)cssClass = 'row';else if (i == j + 1){cssClass = 'row_total_corner';return j;}else if (i == j && colLists[i][colScanIndexes[i]].captions) {cssClass = 'row_total_first';} else if (i < j + 1)cssClass = 'row_total';elsecssClass = 'row_null';if (j == bottom ) {if (colLists[i][colScanIndexes[i]].captions) {text = colLists[i][colScanIndexes[i]].captions[m];}if (i == 0 && colScanIndexes[i] == 0) {if (colLists[i][colScanIndexes[i]].captions)text += "?";else text = "";text += (wrapContent ? "<span class='i18n'>Grand Total</span>" : "Grand Total");}}}}}}return -1; }function genTotalHeaderRowCells(currentIndex, scanSums, scanIndexes, totalsLists, wrapContent) {var colLists = totalsLists[COLUMNS];var colScanSums = scanSums[COLUMNS];var colScanIndexes = scanIndexes[COLUMNS];var bottom = colLists.length - 2;var contents = '';for (var i = bottom; i >= 0; i--) {if (currentIndex == colScanSums[i]) {for (var m = 0; m < colLists[i][colScanIndexes[i]].cells.length; m++) {contents += '<tr>';for (var j = 0; j <= bottom; j++) {var cssClass;var text = '?';if (i == 0 && j == 0)cssClass = 'row';else if (i == j + 1)cssClass = 'row_total_corner';else if (i == j && colLists[i][colScanIndexes[i]].captions) {cssClass = 'row_total_first';} else if (i < j + 1)cssClass = 'row_total';elsecssClass = 'row_null';if (j == bottom ) {if (colLists[i][colScanIndexes[i]].captions) {text = colLists[i][colScanIndexes[i]].captions[m];}if (i == 0 && colScanIndexes[i] == 0) {if (colLists[i][colScanIndexes[i]].captions)text += "?";else text = "";text += (wrapContent ? "<span class='i18n'>Grand Total</span>" : "Grand Total");}}contents += '<th class="' + cssClass + '">'+ (wrapContent ? '<div>' + text + '</div>' : text ) + '</th>';}var scanIndexes = {};var scanSums = {};if (totalsLists[ROWS]) {for (var z = 0; z < totalsLists[ROWS].length; z++) {scanIndexes[z] = 0;scanSums[z] = totalsLists[ROWS][z][scanIndexes[z]].width;}}for (var k = 0; k < colLists[i][colScanIndexes[i]].cells[m].length; k++) {contents += '<td class="data total">' + colLists[i][colScanIndexes[i]].cells[m][k].value + '</td>';if (totalsLists[ROWS]) {contents += totalIntersectionCells(k + 1, totalsLists[ROWS].length - 1, scanSums, scanIndexes, totalsLists[ROWS]);}}contents += '</tr>';}colScanIndexes[i]++;if (colScanIndexes[i] < colLists[i].length) {colScanSums[i] += colLists[i][colScanIndexes[i]].width;}}}return contents; }var ROWS = "ROWS"; var COLUMNS = "COLUMNS";function nextParentsDiffer(data, row, col) {while (row-- > 0) {if (data[row][col].properties.uniquename != data[row][col + 1].properties.uniquename)return true;}return false; }function topParentsDiffer(data, row, col) {while (col-- > 0)if (data[row][col].properties.uniquename != data[row - 1][col].properties.uniquename)return true;return false; }/*** This function is intended to traverse the totals arrays and cleanup empty* totals. This will optimize the query result on screen, displaying just the* needed cells.* @param dirs The direction array ['ROWS', 'COLUMNS']* @param totalsLists The totals from allData.rowTotalsLists and allData.colTotalsLists.*/ function cleanupTotals(dirs, totalsLists) {// For each direction (ROWS/COLUMNS)for (var dirIndex = 0; dirIndex < dirs.length; dirIndex++) {var dir = dirs[dirIndex];// If there are defined totalsif (totalsLists[dir]) {var isEmpty = true; // A flag to indicate if this total is emptyfor (var row = 0; row < totalsLists[dir].length; row++) {var totalsInfoArray = totalsLists[dir][row];for (var totalIndex = 0; totalIndex < totalsInfoArray.length; totalIndex++) {var cells = totalsLists[dir][row][totalIndex].cells;for (var cellIndex = 0; cellIndex < cells.length; cellIndex++) {var cellArray = cells[cellIndex];// For each total cellfor (var i = 0; i < cellArray.length; i++) {var cell = cellArray[i];// If it contains a value different from emptyif (cell.value !== '-') {isEmpty = false; // So, this total is not empty}}}}}if (isEmpty) { // If this total is emptytotalsLists[dir] = null; // Remove it}}} }/*the main method to render data by table form. 20190423*/ SaikuTableRenderer.prototype.internalRender = function(allData, options) {var tableContent = "";var rowContent = "";var data = allData.cellset;var newRowContent = '';var arrRowData = [];var objRowData = [];var table = data ? data : [];var colSpan;var colValue;var isHeaderLowestLvl;var isBody = false;var firstColumn;var isLastColumn, isLastRow;var nextHeader;var processedRowHeader = false;var lowestRowLvl = 0;var rowGroups = [];var batchSize = null;var batchStarted = false;var isColHeader = false, isColHeaderDone = false;var resultRows = [];var wrapContent = true;if (options) {batchSize = options.hasOwnProperty('batchSize') ? options.batchSize : null;wrapContent = options.hasOwnProperty('wrapContent') ? options.wrapContent : true;}var totalsLists = {};totalsLists[COLUMNS] = allData.rowTotalsLists;totalsLists[ROWS] = allData.colTotalsLists;var scanSums = {};var scanIndexes = {};var dirs = [ROWS, COLUMNS];var hasMeasures = allData.query && allData.query.queryModel && allData.query.queryModel.details? allData.query.queryModel.details.measures.length: 0;if (typeof this._options.htmlObject === 'object' &&Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE &&hasMeasures > 0 &&allData.query.type === 'QUERYMODEL' &&allData.query.queryModel.details.axis === 'COLUMNS' &&allData.query.queryModel.details.location === 'BOTTOM') {var arrColumnTitleTable = getAxisLevelsName(allData, COLUMNS);var arrDomColumnTitleTable = getDomColumnsLevelsName(this._options.htmlObject);var colspanColumnTitleTable = getAxisSize(allData, ROWS);var auxColumnTitleTable = 0;if (arrColumnTitleTable.length === arrDomColumnTitleTable.length) {arrColumnTitleTable = arrDomColumnTitleTable;}else {arrColumnTitleTable = _.intersection(arrDomColumnTitleTable, arrColumnTitleTable);}}for (var i = 0; i < dirs.length; i++) {scanSums[dirs[i]] = new Array();scanIndexes[dirs[i]] = new Array();}// Here we cleaup the empty totalscleanupTotals(dirs, totalsLists);if (totalsLists[COLUMNS]) {for (var i = 0; i < totalsLists[COLUMNS].length; i++) {scanIndexes[COLUMNS][i] = 0;scanSums[COLUMNS][i] = totalsLists[COLUMNS][i][scanIndexes[COLUMNS][i]].width;}}var headerFlag=true;// add this flag to solve the bug when same data to merge。 20190423for (var row = 0, rowLen = table.length; row < rowLen; row++) {var rowShifted = row - allData.topOffset;colSpan = 1;colValue = "";isHeaderLowestLvl = false;isLastColumn = false;isLastRow = false;isColHeader = false;var headerSame = false;if (totalsLists[ROWS]) {for (var i = 0; i < totalsLists[ROWS].length; i++) {scanIndexes[ROWS][i] = 0;scanSums[ROWS][i] = totalsLists[ROWS][i][scanIndexes[ROWS][i]].width;}}rowWithOnlyEmptyCells = true;rowContent = "<tr>";var header = null;if (row === 0) {rowContent = "<thead>" + rowContent;}if (typeof this._options.htmlObject === 'object' &&Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE &&hasMeasures > 0 &&allData.query.type === 'QUERYMODEL' &&allData.query.queryModel.details.axis === 'COLUMNS' &&allData.query.queryModel.details.location === 'BOTTOM' &&auxColumnTitleTable < arrColumnTitleTable.length) {rowContent += '<th class="row_header" style="text-align: right;" colspan="' + colspanColumnTitleTable + '" title="' + arrColumnTitleTable[auxColumnTitleTable] + '">'+ (wrapContent ? '<div>' + arrColumnTitleTable[auxColumnTitleTable] + '</div>' : arrColumnTitleTable[auxColumnTitleTable])+ '</th>';auxColumnTitleTable += 1;}for (var col = 0, colLen = table[row].length; col < colLen; col++) {var colShifted = col - allData.leftOffset;header = data[row][col];if (header.type === "COLUMN_HEADER") {isColHeader = true;}// If the cell is a column header and is null (top left of table)if (header.type === "COLUMN_HEADER" && header.value === "null" && (firstColumn == null || col < firstColumn)) {if (((!Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE || (Settings.ALLOW_AXIS_COLUMN_TITLE_TABLE && allData.query.queryModel.details.location !== 'BOTTOM')) || hasMeasures === 0) ||allData.query.type === 'MDX') {rowContent += '<th class="all_null">?</th>';}} // If the cell is a column header and isn't null (column header of table)else if (header.type === "COLUMN_HEADER") {if (firstColumn == null) {firstColumn = col;}if (table[row].length == col+1)isLastColumn = true;elsenextHeader = data[row][col+1];if (isLastColumn) {// Last column in a row...if (header.value == "null") {rowContent += '<th class="col_null">?</th>';} else {if (totalsLists[ROWS])colSpan = totalsLists[ROWS][row + 1][scanIndexes[ROWS][row + 1]].span;rowContent += '<th class="col" style="text-align: center;" colspan="' + colSpan + '" title="' + header.value + '">'+ (wrapContent ? '<div rel="' + row + ":" + col +'">' + header.value + '</div>' : header.value)+ '</th>';}} else {// All the rest...var groupChange = (col > 1 && row > 1 && !isHeaderLowestLvl && col > firstColumn) ?data[row-1][col+1].value != data[row-1][col].value || data[row-1][col+1].properties.uniquename != data[row-1][col].properties.uniquename: false;var maxColspan = colSpan > 999 ? true : false;if (header.value != nextHeader.value || nextParentsDiffer(data, row, col) || isHeaderLowestLvl || groupChange || maxColspan) {if (header.value == "null") {rowContent += '<th class="col_null" colspan="' + colSpan + '">?</th>';} else {if (totalsLists[ROWS])colSpan = totalsLists[ROWS][row + 1][scanIndexes[ROWS][row + 1]].span;rowContent += '<th class="col" style="text-align: center;" colspan="' + (colSpan == 0 ? 1 : colSpan) + '" title="' + header.value + '">'+ (wrapContent ? '<div rel="' + row + ":" + col +'">' + header.value + '</div>' : header.value)+ '</th>';}colSpan = 1;} else {colSpan++;}}if (totalsLists[ROWS])rowContent += genTotalHeaderCells(col - allData.leftOffset + 1, row + 1, scanSums[ROWS], scanIndexes[ROWS], totalsLists[ROWS], wrapContent);} // If the cell is a row header and is null (grouped row header)else if (header.type === "ROW_HEADER" && header.value === "null") {rowContent += '<th class="row_null">?</th>';} // If the cell is a row header and isn't null (last row header)else if (header.type === "ROW_HEADER") {if (lowestRowLvl == col)isHeaderLowestLvl = true;elsenextHeader = data[row][col+1];var previousRow = data[row - 1];var nextRow = data[row + 1];// when same set fixed value is false ,It means the same data will not merge。table data will show row by row.20190423//var same=false; /*judge the current value and previousRow value,if equals ,all set comeback,set the headerFlag is true, we can judge the data as usual. 20190423*/if(header.value !== previousRow[col].value){headerFlag =true;}/*judge the tableContent include value or not, if include ,set the headerFlag value is true to avoid repeat datas showed in table.20190423*/if(tableContent.indexOf(header.value) > -1 ){headerFlag =true;}/*add headerFlag to judge the data is same ,then control the data merge wheather or not.20190423 */var same = !headerSame && !isHeaderLowestLvl && (col == 0 || !topParentsDiffer(data, row, col)) && header.value === previousRow[col].value && headerFlag;headerSame = !same;var sameAsPrevValue = false;if(Settings.ALLOW_TABLE_DATA_COLLAPSE){if (row > 0 && row < rowLen - 1) {if (totalsLists[ROWS] == null || (col <= colLen - totalsLists[ROWS].length - 1)) {var checkOther = true;if (totalsLists[COLUMNS] && rowShifted >= 0 && col <= isNextTotalsRow(rowShifted + 1, scanSums, scanIndexes, totalsLists, wrapContent)) {sameAsPrevValue = true;checkOther = false;}if (checkOther && nextRow[col].value == header.value) {if (col > 0) {for (var j = 0; j < col; j++) {if (nextRow[j].value == data[row][j].value) {sameAsPrevValue = true;} else {sameAsPrevValue = false;break;}}} else {sameAsPrevValue = true;}}}} else if(row > 0 && row == rowLen - 1) {if (totalsLists[COLUMNS] && rowShifted >= 0 && col <= isNextTotalsRow(rowShifted + 1, scanSums, scanIndexes, totalsLists, wrapContent)) {sameAsPrevValue = true;}}}var value = (same ? "<div>?</div>" : '<div rel="' + row + ":" + col + '">'+ (sameAsPrevValue && Settings.ALLOW_TABLE_DATA_COLLAPSE ? '<span class="expander expanded" style="cursor: pointer;">▼</span>' : '' ) + header.value + '</div>');if (!wrapContent) {value = (same ? "?" : header.value );}var tipsy = "";/* var tipsy = ' original-title="';if (!same && header.metaproperties) {for (key in header.metaproperties) {if (key.substring(0,1) != "$" && key.substring(1,2).toUpperCase() != key.substring(1,2)) {tipsy += "<b>" + safe_tags_replace(key) + "</b> : " + safe_tags_replace(header.metaproperties[key]) + "<br>";}}}tipsy += '"';*/var cssclass = (same ? "row_null" : "row");var colspan = 0;if (!isHeaderLowestLvl && (typeof nextHeader == "undefined" || nextHeader.value === "null")) {colspan = 1;var group = header.properties.dimension;var level = header.properties.level;var groupWidth = (group in rowGroups ? rowGroups[group].length - rowGroups[group].indexOf(level) : 1);for (var k = col + 1; colspan < groupWidth && k <= (lowestRowLvl+1) && data[row][k] !== "null"; k++) {colspan = k - col;}col = col + colspan -1;}/*when the content is to long ,we will set new line to show it.*/// eg value: <div rel="3:0">新業務及保單行政部</div>if(cssclass == "row" && value.length>0){var startPos = value.indexOf('>'); //find start position of the tag. eg: <div rel="3:0">var endPos = value.lastIndexOf('<'); //find end position of the tag. eg: </div>var tmpValue = value.substr( startPos+1 ,endPos-startPos-1); // get the content value. eg: 新業務及保單行政部//將value值每隔40個字自動加上換行符//each 40 character add one <br> tag to get new line. if(tmpValue.length>120){ tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,40)+"<br/>"+tmpValue.substr(120,tmpValue.length-120);}else if(tmpValue.length>80){ tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,40)+"<br/>"+tmpValue.substr(80,tmpValue.length-80);}else if(tmpValue.length>40){tmpValue = tmpValue.substr(0,40)+"<br/>"+tmpValue.substr(40,tmpValue.length-40);}// compared with old value, this value only add <br> tag for show data in table more beautiful.value = value.substr(0,startPos+1) + tmpValue + value.substr(endPos,value.length-endPos);}rowContent += '<th class="' + cssclass + '" ' + (colspan > 0 ? ' colspan="' + colspan + '"' : "") + tipsy + '>' + value + '</th>';}else if (header.type === "ROW_HEADER_HEADER") {var hierName = function(data) {var hier = data.properties.hierarchy;var name = hier.replace(/[\[\]]/gi, '').split('.')[1]? hier.replace(/[\[\]]/gi, '').split('.')[1]: hier.replace(/[\[\]]/gi, '').split('.')[0];return name;};var arrPosRowData = [];if (_.contains(arrRowData, header.value)) {for (var i = 0; i < arrRowData.length; i++) {if (arrRowData[i] === header.value) {arrPosRowData.push(i);}}arrPosRowData.push(col);}rowContent += '<th class="row_header">' + (wrapContent ? '<div>' + header.value + '</div>' : header.value) + '</th>';arrRowData.push(header.value);objRowData.push({name: header.value,hierName: hierName(header) + '/' + header.value});isHeaderLowestLvl = true;processedRowHeader = true;lowestRowLvl = col;if (header.properties.hasOwnProperty("dimension")) {var group = header.properties.dimension;if (!(group in rowGroups)) {rowGroups[group] = [];}rowGroups[group].push(header.properties.level);}if (arrPosRowData.length > 0) {var aux = 0;rowContent = '<tr>';if (row === 0) {rowContent = '<thead>' + rowContent;}for (var i = 0; i < objRowData.length; i++) {if (arrPosRowData[aux] === i) {newRowContent += '<th class="row_header">' + (wrapContent ? '<div>' + objRowData[i].hierName + '</div>' : objRowData[i].hierName) + '</th>';aux += 1;}else {newRowContent += '<th class="row_header">' + (wrapContent ? '<div>' + objRowData[i].name + '</div>' : objRowData[i].name) + '</th>';}}rowContent += newRowContent;}} // If the cell is a normal data cellelse if (header.type === "DATA_CELL") {batchStarted = true;var color = "";var val = _.isEmpty(header.value) ? Settings.EMPTY_VALUE_CHARACTER : header.value;var arrow = "";if (header.properties.hasOwnProperty('image')) {var img_height = header.properties.hasOwnProperty('image_height') ? " height='" + header.properties.image_height + "'" : "";var img_width = header.properties.hasOwnProperty('image_width') ? " width='" + header.properties.image_width + "'" : "";val = "<img " + img_height + " " + img_width + " style='padding-left: 5px' src='" + header.properties.image + "' border='0'>";}// Just apply formatting to non-empty cellsif (val !== '-' && val !== '' && header.properties.hasOwnProperty('style')) {color = " style='background-color: " + header.properties.style + "' ";}if (header.properties.hasOwnProperty('link')) {val = "<a target='__blank' href='" + header.properties.link + "'>" + val + "</a>";}if (header.properties.hasOwnProperty('arrow')) {arrow = "<img height='10' width='10' style='padding-left: 5px' src='./images/arrow-" + header.properties.arrow + ".gif' border='0'>";}if (val !== '-' && val !== '') {rowWithOnlyEmptyCells = false;}rowContent += '<td class="data" ' + color + '>'+ (wrapContent ? '<div class="datadiv '+ setStyleNegativeNumber(header.properties.raw) + '" alt="' + header.properties.raw + '" rel="' + header.properties.position + '">' : "")+ val + arrow+ (wrapContent ? '</div>' : '') + '</td>';if (totalsLists[ROWS])rowContent += genTotalDataCells(colShifted + 1, rowShifted, scanSums[ROWS], scanIndexes[ROWS], totalsLists, wrapContent);}}rowContent += "</tr>";// Change it to let hideEmpty true by defaultif (options.hideEmpty && header.type === "DATA_CELL" && rowWithOnlyEmptyCells) {/*when data_cell is null,set the headerFlag is false ,to fix the problem data merge inccrrect.*/headerFlag=false;rowContent = '';}var totals = "";if (totalsLists[COLUMNS] && rowShifted >= 0) {totals += genTotalHeaderRowCells(rowShifted + 1, scanSums, scanIndexes, totalsLists, wrapContent);}if (batchStarted && batchSize) {if (row <= batchSize) {if (!isColHeader && !isColHeaderDone) {tableContent += "</thead><tbody>";isColHeaderDone = true;}tableContent += rowContent;if (totals.length > 0) {tableContent += totals;}} else {resultRows.push(rowContent);if (totals.length > 0) {resultRows.push(totals);}}} else {if (!isColHeader && !isColHeaderDone) {tableContent += "</thead><tbody>";isColHeaderDone = true;}tableContent += rowContent;if (totals.length > 0) {tableContent += totals;}}}if (options) {options['batchResult'] = resultRows;options['hasBatchResult'] = resultRows.length > 0;}return "<table>" + tableContent + "</tbody></table>"; };SaikuTableRenderer.prototype.renderSummary = function(data) {if (data && data.query) {var hasSomethingToRender = false;var measures = data.query.queryModel.details? data.query.queryModel.details.measures: [];var summaryData = {};for (var i = 0; i < measures.length; i++) {var m = measures[i];if (m.aggregators) {for (var j = 0; j < m.aggregators.length; j++) {var a = m.aggregators[j];if (a.indexOf('_') > 0) {var tokens = a.split('_');var aggregator = tokens[0];var axis = tokens[1];if (aggregator !== 'nil' && aggregator !== 'not') {hasSomethingToRender = true;aggregator = aggregator.capitalizeFirstLetter();if (!(axis in summaryData)) summaryData[axis] = [];summaryData[axis].push(m.name + ": " + aggregator);}}}}}if (hasSomethingToRender) {var summary = "<div id='totals_summary'><br/>";$.each(summaryData, function(key, aggregators) {summary += "<h3>" + key.capitalizeFirstLetter();for (var i = 0; i < aggregators.length; i++) {summary += "<br/>?" + aggregators[i];}summary += "</h3>";});return summary + "</div>";}}return ""; };String.prototype.capitalizeFirstLetter = function() {return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase(); }

  

?

轉載于:https://www.cnblogs.com/DFX339/p/10758503.html

總結

以上是生活随笔為你收集整理的Saiku Table展示数据合并bug修复(二十五)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

91丨精品丨蝌蚪丨白丝jk | 一级黄色大片在线观看 | 99中文在线| 毛片1000部免费看 | 91香蕉视频黄 | 欧美日韩在线精品 | 亚洲国产三级在线 | 97在线观看免费观看高清 | 丁香六月婷婷开心婷婷网 | 丁香婷婷基地 | 日韩高清黄色 | 国产一区视频免费在线观看 | 狠狠色综合网站久久久久久久 | 可以免费观看的av片 | 久99久精品 | 丁香婷婷深情五月亚洲 | 伊人亚洲综合网 | 国内偷拍精品视频 | 91最新在线观看 | 欧美特一级片 | 在线观看日韩精品视频 | 免费在线观看黄色网 | 国产日韩欧美在线看 | 亚洲精品国产精品久久99 | 丁香六月激情婷婷 | 亚洲aⅴ在线观看 | 欧美在线视频一区二区三区 | 精品久久国产精品 | 亚洲国产精品免费 | 久久这里有精品 | 在线观看黄色大片 | 国产精品第一页在线观看 | 国产一区在线视频 | 久久视频在线观看免费 | 美女免费电影 | 色网站黄| 国产精品欧美久久久久无广告 | 在线观看免费视频 | 色婷婷国产精品一区在线观看 | 欧美有色 | 国产 日韩 在线 亚洲 字幕 中文 | 久草在线资源网 | 成人国产精品免费观看 | 国内精品久久久久 | 手机看片中文字幕 | 国产99re | 午夜精品久久久久久久99热影院 | 亚洲成人一区 | 嫩草伊人久久精品少妇av | 久久久午夜剧场 | 欧美成人h版 | 日韩色一区二区三区 | 欧美精品免费视频 | 日本在线观看黄色 | 日韩专区一区二区 | 久久精品超碰 | 国产九九热 | 在线导航福利 | 高清免费在线视频 | 91欧美日韩国产 | 欧美一级片在线免费观看 | 精品久久久久国产免费第一页 | 中文字幕av电影下载 | 国内精品在线一区 | 久久久久日本精品一区二区三区 | 91在线91 | 免费看成人a | 久久天| 黄av免费在线观看 | 免费久久精品视频 | a极黄色片| 国产精品成人一区二区 | 狠狠狠狠狠色综合 | 中文字幕中文字幕在线一区 | 亚洲色图av | 国产精品久久嫩一区二区免费 | 亚洲欧美激情插 | 亚洲va在线va天堂va偷拍 | 久久精品女人毛片国产 | 免费亚洲精品 | 黄色三级在线观看 | 91私密视频 | 夜夜躁日日躁狠狠久久av | 激情久久一区二区三区 | a级免费观看 | 久久久久视| 免费在线看v | 久久永久免费 | 久青草视频在线观看 | 激情一区二区三区欧美 | 亚洲精品中文字幕在线观看 | 久草在线免费看视频 | 欧美激情另类文学 | 日韩乱码中文字幕 | 丁香 久久 综合 | 青青河边草免费视频 | 亚洲高清资源 | 黄色精品久久 | 中文字幕中文字幕在线中文字幕三区 | 91精品国产一区二区在线观看 | 精品国产伦一区二区三区观看说明 | 欧美亚洲国产一卡 | av蜜桃在线 | 97视频人人澡人人爽 | 国产一区在线观看免费 | 一区在线观看 | 久久精品这里热有精品 | 欧美亚洲久久 | 在线不卡中文字幕播放 | 亚洲免费视频在线观看 | 激情五月开心 | 日本精a在线观看 | 毛片永久新网址首页 | 91天堂素人约啪 | 国产69久久| 国产一级视频在线免费观看 | 欧美激情精品久久久久久免费 | 中文字幕在线观看完整版 | 免费中午字幕无吗 | 毛片永久新网址首页 | 国产精品 中文字幕 亚洲 欧美 | 黄色小网站在线 | 99操视频| 狠狠躁夜夜躁人人爽超碰97香蕉 | 欧美 另类 交 | 成人观看视频 | 97精品国自产拍在线观看 | 中文字幕亚洲综合久久五月天色无吗'' | 黄色毛片一级片 | 国产精品videossex国产高清 | 天天插日日插 | 国产成人久久精品一区二区三区 | 色www.| 9幺看片 | 成人h在线观看 | 性日韩欧美在线视频 | 国内精品99 | www.久久久 | 在线观看91精品视频 | 综合色中色 | 丁香六月色 | 国产va在线 | av丝袜天堂| 亚洲成av人片一区二区梦乃 | 日韩久久激情 | 久久不卡日韩美女 | 这里只有精品视频在线 | 在线观看亚洲国产精品 | 日本动漫做毛片一区二区 | 日韩欧美有码在线 | 丝袜美女视频网站 | 中文亚洲欧美日韩 | 亚洲精品国产日韩 | 国产一二三四在线观看视频 | 国产手机在线视频 | 天堂av色婷婷一区二区三区 | 在线a亚洲视频播放在线观看 | 中文 一区二区 | 久草免费手机视频 | 性日韩欧美在线视频 | 国产精品视频地址 | 在线中文字幕播放 | 天天射天天射天天 | 亚洲免费在线视频 | 国内精品久久久久久久 | 中文字幕一区二区三区在线视频 | 日韩av电影手机在线观看 | 国产日韩欧美精品在线观看 | 97夜夜澡人人爽人人免费 | 国产中文字幕网 | 中文字幕av免费在线观看 | 99精品国产99久久久久久福利 | 中文字幕 国产专区 | 午夜视频在线观看一区二区三区 | 欧美福利网址 | 麻豆高清免费国产一区 | 国内丰满少妇猛烈精品播 | 午夜少妇av | 日韩三级视频在线看 | 日韩欧美在线播放 | 精品亚洲免a | 九九激情视频 | 精品99视频 | 日韩91av | www操操操 | 国产无遮挡又黄又爽在线观看 | 国产精品久久久久久久久久久免费 | 91亚洲网| 91精品啪在线观看国产 | 五月丁色| 成人国产精品一区二区 | 国产亚洲人成网站在线观看 | 97成人超碰 | 国产日韩欧美在线观看 | 免费观看www小视频的软件 | 免费在线观看午夜视频 | 一区二区在线电影 | 成人小视频在线 | 五月婷婷亚洲 | 玖玖玖精品 | 国产精品一区二区62 | 精品美女国产在线 | www免费看 | 国产精品高清免费在线观看 | 又湿又紧又大又爽a视频国产 | 日本公妇在线观看 | 久久一区二区三区国产精品 | 日批视频在线 | 亚洲一区二区视频在线播放 | 亚洲精品国产成人 | 久久精品视频网站 | 婷婷网站天天婷婷网站 | 国产视频在线观看一区 | 99久久婷婷国产综合精品 | 国产视频精品久久 | 91精品国产麻豆国产自产影视 | 九九视频免费在线观看 | 综合网av | 亚洲国产合集 | 伊人导航| 免费男女羞羞的视频网站中文字幕 | 亚洲精品综合久久 | 国产精品综合在线观看 | 黄色av影院 | 国产精品久久一卡二卡 | 免费男女网站 | 成人国产精品入口 | 免费在线观看黄色网 | 人人干狠狠操 | 天天激情综合网 | 久久久99精品免费观看 | 久久国产精品久久精品国产演员表 | .国产精品成人自产拍在线观看6 | 日韩午夜视频在线观看 | 五月激情在线 | 91视频在线看 | av在线播放一区二区三区 | 欧美日韩亚洲第一 | 在线观看黄网站 | 草久视频在线观看 | 丁香伊人网 | 免费看av在线 | 欧美日韩国产综合一区二区 | 九九免费在线观看 | 丁香激情网| 精品免费国产一区二区三区四区 | 精品在线观看一区二区三区 | 51久久夜色精品国产麻豆 | 人人插人人看 | 久久久久久久久久久久电影 | 国产精品毛片一区二区三区 | 一级免费黄视频 | 日韩精品免费一区二区三区 | 久久久久久久久久久久久国产精品 | 国产精品成人一区 | 天堂在线一区二区 | 国产精品视频地址 | av官网在线 | 国产精品自在线 | 又大又硬又黄又爽视频在线观看 | 91成年视频 | 欧美日韩不卡一区二区三区 | 高清有码中文字幕 | 色婷婷欧美 | 国产精品99久久久久久宅男 | 天天操天天谢 | 美女视频久久黄 | www.久久久.cum | 久久久在线视频 | 国产中文a | 人人澡人人模 | 亚洲精品www | 国产一区二区午夜 | 999久久久免费视频 午夜国产在线观看 | 久久高清国产视频 | 91在线播放国产 | 亚洲精品玖玖玖av在线看 | 免费观看黄 | 免费午夜网站 | 三日本三级少妇三级99 | 视频在线99 | 成人黄色国产 | 91 在线视频| 一区二区三区动漫 | 久草在线观看视频免费 | h视频在线看 | 免费黄色在线网址 | 99tvdz@gmail.com| av解说在线 | 国产中年夫妇高潮精品视频 | av黄色在线| 国产在线污| 亚洲精品国产拍在线 | 欧美 激情 国产 91 在线 | 久久精品一区二区三区国产主播 | 黄色a在线| 97综合在线 | 超碰在线人人97 | 日韩激情小视频 | 狠狠网亚洲精品 | 国产精品久久久久永久免费看 | 中文字幕免费一区二区 | 激情深爱.com | 中文字幕 国产视频 | 日日夜夜爱 | 精品一区二区三区久久 | 欧美成人播放 | 在线中文字幕av观看 | 免费在线观看av | 天天操天天操天天 | 日日碰狠狠躁久久躁综合网 | 精品视频久久久 | 国产精品美女久久久久久 | 成人一级黄色片 | 高清在线一区二区 | 四虎国产永久在线精品 | a视频在线观看 | 全久久久久久久久久久电影 | 波多野结衣在线中文字幕 | 亚洲黄网址 | 97电影院网 | 国产免费三级在线观看 | 国产色网| 日韩特黄一级欧美毛片特黄 | www.91成人| 亚洲五月婷婷 | 国产精品久久 | 久久久久久高潮国产精品视 | 亚洲国产日韩欧美 | 婷婷5月激情5月 | 精品五月天 | 成人97视频一区二区 | 国产精品久久一区二区三区不卡 | 日韩精品中文字幕久久臀 | 97成人精品视频在线播放 | 久久精品美女 | 91精品一区二区三区蜜桃 | 国产精品久久久久久久久久久杏吧 | 天堂av官网 | 99riav1国产精品视频 | 欧美亚洲一级片 | 国产精品99久久久久的智能播放 | 久久免费视频精品 | 欧美成人在线免费 | 五月激情视频 | 国产精品午夜8888 | 日韩精品中字 | 超碰在线最新网址 | 9ⅰ精品久久久久久久久中文字幕 | 国产一区高清在线 | 四虎在线免费视频 | 欧美狠狠色 | 一本一本久久a久久 | 日韩久久片 | 97精品视频在线 | 欧美一区二区在线免费观看 | 色多多视频在线 | 婷婷久久婷婷 | 色综合久久久久综合体桃花网 | 天天色天天搞 | 亚洲丝袜一区二区 | 中国一级片在线 | 91亚洲国产成人 | 天天做天天射 | 欧美日韩精品在线一区二区 | 黄网站色成年免费观看 | 免费在线观看一级片 | 最新国产精品视频 | 麻豆果冻剧传媒在线播放 | www.天天干 | 日韩午夜小视频 | 网站你懂的 | 一区二区三区在线免费观看视频 | 国产精品视频最多的网站 | 欧美久久久久 | 久久久国产精品视频 | ww亚洲ww亚在线观看 | 在线视频观看你懂的 | 色综合久久久久 | 一区二区三区国 | 精品毛片久久久久久 | 日韩av看片| 最近日本mv字幕免费观看 | 免费成人在线电影 | 成人av一级片 | 成 人 黄 色 视频免费播放 | 高清在线一区二区 | 日韩av五月天| 午夜精品久久久久久久99 | 综合视频在线 | 麻豆首页| 中文成人字幕 | 欧美日韩国产伦理 | 欧美性生活免费 | 国产一级二级av | av大全在线免费观看 | 欧洲精品久久久久毛片完整版 | 亚洲精品中文字幕视频 | 成人av日韩| 韩国三级在线一区 | 狠狠色香婷婷久久亚洲精品 | 人人看人人草 | 99r国产精品 | 麻豆传媒一区二区 | 黄色av高清 | 亚av在线| 成年在线观看 | 国产视 | 精品国产成人av在线免 | 不卡的av电影在线观看 | 亚洲电影图片小说 | 香蕉视频网址 | 日日天天狠狠 | 日韩毛片久久久 | 日韩三级视频在线观看 | 国产精品白浆 | 狠狠躁18三区二区一区ai明星 | 免费黄色网址大全 | 中文字幕在线看人 | 欧美少妇xx| 久久久精品一区二区 | 97天堂| 国内视频在线观看 | 亚洲 综合 国产 精品 | 亚洲九九九在线观看 | av免费看网站 | 美国三级黄色大片 | 国产五月| 中文字幕免| 激情五月激情综合网 | 国产91欧美 | 在线播放国产一区二区三区 | 人人澡人人澡人人 | 久久精品一二三区白丝高潮 | 亚洲日本色 | 久久国产亚洲精品 | 人人澡人人爽欧一区 | 日韩在线视频播放 | 中文字幕在线观看视频一区二区三区 | 日韩一区二区三免费高清在线观看 | 久久综合五月婷婷 | 91成人黄色 | 色欲综合视频天天天 | 91麻豆精品国产自产在线游戏 | av免费在线网 | 中文一区在线 | 成人影音在线 | 手机av在线网站 | 极品美女被弄高潮视频网站 | 久久九九精品久久 | 麻花豆传媒mv在线观看网站 | 亚洲一区美女视频在线观看免费 | 免费一级片观看 | 亚洲1区 在线 | 500部大龄熟乱视频 欧美日本三级 | 久久精品久久精品久久 | 美女网站免费福利视频 | 久久免费视频在线观看30 | 黄色在线观看免费网站 | 国产精品成人一区二区三区吃奶 | 97超碰资源网 | 精品日韩中文字幕 | 国产精品va最新国产精品视频 | 97视频免费看 | 亚洲一区二区黄色 | 久久九九网站 | 久草在线| 丁香花中文字幕 | av丝袜美腿| 日韩午夜电影 | 色婷婷天天干 | 91在线影院 | 一级一级一片免费 | 国产精品男女 | 久久久久视 | 婷婷激情五月 | 欧美老女人xx | 久久草视频 | 日韩午夜精品 | 亚洲少妇激情 | 97av在线视频免费播放 | 免费在线观看视频一区 | 免费日韩av电影 | 久久99爱视频 | 九九视频网| 99在线热播精品免费 | 91在线观看高清 | av中文电影 | 国产日韩欧美视频在线观看 | 免费av影视 | 久久99国产精品久久99 | 天堂va在线观看 | 精品一二三区视频 | www.av免费观看 | 国产精品免费视频久久久 | 欧美午夜精品久久久久 | 国产资源免费在线观看 | 久久久影院一区二区三区 | 欧美在线91 | 99se视频在线观看 | 久久精品99国产国产 | 国产人成精品一区二区三 | 久久国产综合视频 | 在线免费三级 | 久久久精品久久 | 99国产精品视频免费观看一公开 | 亚洲成人午夜av | 91免费版在线观看 | 美女久久久久久久久久 | www.久久久精品 | 在线不卡中文字幕播放 | 中文字幕在线观看第二页 | 成人免费视频网站 | 欧美午夜一区二区福利视频 | 国产成在线观看免费视频 | 欧洲在线免费视频 | 久久久久亚洲国产 | 免费看污的网站 | 久久9999久久免费精品国产 | 日韩视频中文字幕在线观看 | 黄色片视频免费 | 日韩精品在线观看视频 | av免费在线观看1 | 成人av教育 | 日韩精品免费一线在线观看 | 夜夜夜夜操 | 91人人人| 欧美伦理一区二区三区 | 日韩大片免费观看 | 在线91观看 | 91麻豆精品国产自产在线游戏 | 亚洲精品大全 | 欧美日韩精品久久久 | 国产97在线播放 | 天天操天天草 | 一区二区三区在线视频观看58 | 欧美a√大片 | 麻豆精品国产传媒 | 国产精品久久久久久影院 | 久久久免费精品国产一区二区 | 国产色在线观看 | 欧美日韩国产精品一区二区亚洲 | 9在线观看免费高清完整版 玖玖爱免费视频 | 欧美另类sm图片 | 久久免费国产精品 | 国内精品久久久久久久久久清纯 | 亚洲综合欧美日韩狠狠色 | 狠狠插天天干 | 色婷婷一区 | 国产黄免费看 | 久久久久夜色 | 久久国产精品免费一区二区三区 | 日本中文字幕网站 | 国产精品乱码久久久久久1区2区 | 色就色,综合激情 | 天天操天天干天天爽 | 成人av电影在线 | 五月婷婷激情 | 国产精品你懂的在线观看 | 亚洲精品免费在线观看视频 | 人人澡人人爽欧一区 | 久操久| 欧美日韩69| 韩国一区二区三区在线观看 | 午夜免费久久看 | 欧美伦理一区二区 | 精品久久久久久亚洲 | 91天堂影院 | 国产香蕉av| 最新中文字幕在线播放 | 国产精品久久久久久久av大片 | 在线观看色网 | 一区二区精品久久 | 久久久久久久久久久久99 | 国产麻豆视频在线观看 | 91精彩视频在线观看 | 热re99久久精品国产99热 | 免费视频91蜜桃 | 国产黄色一级片 | 国产一区免费观看 | 久久婷婷激情 | 日本久久电影网 | 天天射天天干天天操 | 99久久精品国产亚洲 | 免费观看丰满少妇做爰 | 毛片在线播放网址 | 91精品网站在线观看 | wwxxx日本| 久久这里只有精品1 | 欧美日韩国产一区 | 在线91色 | 最新中文字幕在线播放 | 伊人天天综合 | 免费97视频 | 色亚洲网 | 久久综合久久综合这里只有精品 | 成人av日韩 | 欧美精品一二三 | 免费男女网站 | 中文字幕一区二区三区四区 | 六月色婷婷 | 国产视频 亚洲视频 | 精品国产一区二区三区四 | 久久9视频| 国产亚洲精品福利 | 国产精品女人久久久 | 久久精品视频一 | 色网站黄| 欧美少妇xx| 天天插天天操天天干 | 欧美日韩二三区 | 福利区在线观看 | 狠狠婷婷 | 午夜电影av | 91精品老司机久久一区啪 | 午夜精品一区二区三区在线视频 | 美女视频黄色免费 | 国产中文字幕在线视频 | 久久久久欧美精品 | 免费看毛片网站 | 西西人体www444| 在线看91| 一级做a视频 | 欧美美女视频在线观看 | 毛片无卡免费无播放器 | 粉嫩aⅴ一区二区三区 | 一级欧美黄 | 伊人导航 | 国产一级久久久 | 福利视频一区二区 | 国产中文a| 国产精品99久久久精品免费观看 | 伊人影院99 | 国产精品免费在线 | 久久99久久99免费视频 | 国内精品国产三级国产aⅴ久 | 波多野结衣在线中文字幕 | 亚洲欧洲国产视频 | 黄色官网在线观看 | 国产一级电影免费观看 | 久久天天躁夜夜躁狠狠躁2022 | 精品一区精品二区高清 | 人人操日日干 | 不卡中文字幕av | 久久久国产精品成人免费 | 久久免费视频播放 | 丁香久久久 | 18女毛片 | 中文字幕亚洲欧美日韩2019 | 91精品久久久久久久久 | 国产最新在线观看 | 99精品国产99久久久久久97 | 看黄色.com | 国产又粗又猛又黄又爽的视频 | 99国产视频在线 | 99综合久久 | 免费在线播放视频 | 九九精品视频在线看 | 国产精品麻豆视频 | 91在线免费视频 | 亚洲成人影音 | 九九久久久久久久久激情 | 欧美日韩高清一区二区 国产亚洲免费看 | 成人黄色小说在线观看 | 精品久久免费看 | 97视频在线免费播放 | 亚洲欧美一区二区三区孕妇写真 | 日韩免费在线观看视频 | 国产麻豆精品95视频 | 国产 日韩 欧美 自拍 | 韩国av三级 | 91九色国产蝌蚪 | 久久精品毛片 | 91大神一区二区三区 | 91av官网 | 99re亚洲国产精品 | www.狠狠| 免费看的国产视频网站 | 亚洲国产视频在线 | 在线观看国产福利片 | 亚洲爱爱视频 | 久免费视频 | 欧美性色综合网站 | 国产在线精品视频 | av在线永久免费观看 | www.久久久精品 | 久久精品在线免费观看 | 国产污视频在线观看 | 午夜在线日韩 | 成人av影视 | 亚洲一级免费电影 | 中文在线字幕观看电影 | 欧美成人性网 | 日本久久片 | 国产精品永久在线 | 久久久久夜色 | 国产成人在线观看免费 | 久久综合爱| 日韩av在线小说 | 欧美伊人网 | 午夜视频不卡 | 成人a毛片| 国产色综合 | 五月天天天操 | 91精品电影 | 中日韩三级视频 | 在线观看激情av | 激情视频网页 | 免费看黄色91 | 黄色小说在线观看视频 | 国产日韩在线看 | 久久狠狠一本精品综合网 | 久久99九九99精品 | 久久精品视频一 | 四虎成人精品永久免费av九九 | 日韩精品黄 | 久久国产精品99久久久久 | 久久激情五月激情 | 黄污在线观看 | 超碰免费成人 | 久草视频精品 | 99精品在线| 69av国产| 亚洲一区精品人人爽人人躁 | 人人干人人上 | 91麻豆看国产在线紧急地址 | 中文字幕有码在线 | 国产一区二区三区网站 | 天天操天天怕 | 婷婷久久网 | 黄色一区三区 | 久久精品婷婷 | 性色av一区二区三区在线观看 | 久久视频国产精品免费视频在线 | 在线亚洲人成电影网站色www | 成人啪啪18免费游戏链接 | 亚洲国产一区在线观看 | 亚洲精品乱码白浆高清久久久久久 | 国产高清在线免费观看 | 美女视频黄频大全免费 | 91成人国产| .国产精品成人自产拍在线观看6 | 99国产一区二区三精品乱码 | 国产我不卡 | 天天操天天舔天天干 | 亚洲精品裸体 | 99久热在线精品 | 九九涩涩av台湾日本热热 | 日日夜夜骑 | 成人福利在线播放 | 99福利影院 | 91在线影视 | 夜夜爱av | 婷婷播播网 | 黄色av电影一级片 | 国产精品久久久久久久久久ktv | 国产精品18久久久久久久 | 欧美精品v国产精品v日韩精品 | 91在线区| 国产在线一线 | 麻豆视频在线 | 91精品小视频 | 成年人网站免费在线观看 | 久久在线影院 | 黄色av网站在线免费观看 | 伊人久久影视 | 欧美综合在线观看 | avsex| 正在播放久久 | 99视频| 97在线看片 | 亚洲第一区在线播放 | 成人黄色中文字幕 | 在线小视频你懂得 | 国产一区二区高清不卡 | 天天综合色网 | 精品一区二区电影 | 97在线播放 | 美女视频黄色免费 | 精品久久久久久久久久久久久 | 免费欧美高清视频 | 深夜免费小视频 | 日韩一级片大全 | 中文字幕一区二区三区在线观看 | 91人人爽久久涩噜噜噜 | 国产午夜精品在线 | 国语黄色片| 一级一片免费观看 | 在线免费观看国产精品 | 久草免费在线 | 99视频在线观看视频 | 国产群p| 毛片网在线观看 | 日韩特级黄色片 | 2024av | 婷婷综合五月天 | 久久久综合九色合综国产精品 | 成人91免费视频 | 丝袜美女视频网站 | 中文字幕日韩精品有码视频 | avav片| 亚洲国产精品视频在线观看 | 久久久久久久久久久久久国产精品 | 成人天堂网 | 美女激情影院 | 成人av资源在线 | 欧美激情精品久久久 | 91亚洲精品久久久蜜桃借种 | 精品国产乱码久久久久久三级人 | 久久艹欧美 | 最近最新最好看中文视频 | 久久中文字幕在线视频 | 天天操网 | 日韩欧美成 | 在线激情网 | 国产大片免费久久 | 992tv在线| 欧美激情综合色 | 国产日韩精品一区二区在线观看播放 | 麻豆国产网站 | 国产大陆亚洲精品国产 | 日韩在线欧美在线 | 国产精品九九九九九 | 超碰97免费| 去干成人网 | 国产精品a久久久久 | 免费在线h| 天天干com| 香蕉视频最新网址 | 国产精品爽爽久久久久久蜜臀 | 亚洲成免费 | 精品国产诱惑 | 欧美成人精品在线 | 最近免费中文字幕mv在线视频3 | 免费日韩视 | 日本中文字幕在线视频 | 丁五月婷婷 | 精品一区二区在线看 | 黄色99视频 | 欧美片网站yy | 免费福利小视频 | 亚洲精品字幕在线观看 | 在线成人短视频 | 最近日本韩国中文字幕 | 日韩欧美99 | 在线影视 一区 二区 三区 | 日韩二区三区 | 久久久99精品免费观看乱色 | 在线a视频 | 国产一区免费在线观看 | 国产精品系列在线播放 | 免费福利在线播放 | 成人中心免费视频 | 91精品91| 色综合久久久久综合 | av在线官网 | 久久99久国产精品黄毛片入口 | 成人a级黄色片 | 久久tv| 51久久夜色精品国产麻豆 | 天天干天天怕 | 国产原创在线 | 成人免费 在线播放 | 国产高清日韩欧美 | 97在线观看免费视频 | www免费视频com | 成人91在线| 一区二区三区电影大全 | 免费亚洲成人 | 国产无套一区二区三区久久 | 在线看片中文字幕 | 精品视频在线观看 | 在线视频日韩精品 | 色综合久久综合 | 深夜激情影院 | 国语精品免费视频 | 男女视频久久久 | 国产精品小视频网站 | 亚洲一区二区三区miaa149 | 香蕉视频日本 | 久久久久久免费毛片精品 | 亚洲高清视频在线播放 | 日韩在线三级 | 欧美 日韩 视频 | 日韩av中文在线 | 九九精品在线观看 | 九九久久精品视频 | 美女视频a美女大全免费下载蜜臀 | 99人久久精品视频最新地址 | 色视频网站在线 | 18av在线视频 | 视频一区久久 | 一区二区网 | 日韩黄色软件 | 日韩精品久久一区二区 | 国产一区二区三区在线免费观看 | 久草 | 2019中文| 久久精品国产免费看久久精品 | 国产日韩在线播放 | 日韩在线三区 | 97超碰人人澡人人爱 | 久草在线电影网 | 2020天天干夜夜爽 | 在线小视频你懂得 | 超碰在线免费福利 | 91麻豆文化传媒在线观看 | 在线播放亚洲激情 | 国产亚洲精品久久久久久 | 中文字幕一区二区三区久久蜜桃 | 高清av在线免费观看 | 欧美国产精品久久久久久免费 | a特级毛片 | 一本一本久久a久久精品牛牛影视 | 中文字幕丝袜一区二区 | 中文字幕电影一区 | 射九九 | 国产精品久久久久久久久久久免费 | 在线观看中文字幕一区二区 | 国产精品久久久久久久久久久久 | 欧美在线观看视频免费 | 久久婷婷一区二区三区 | 亚洲成人精品久久 | 91精品久久久久久久久久久久久 | 波多野结衣久久资源 | 亚洲精品国偷拍自产在线观看 | 中文字幕在线免费观看 | 综合色站 | 国产中文字幕av | 国产精品中文 | 精品999在线 | 欧美片网站yy | 亚洲精品88欧美一区二区 | 亚洲成人av电影在线 | 日韩av电影免费在线观看 | 青春草免费视频 | 国产精品久久精品国产 | 激情黄色一级片 | 欧美精彩视频在线观看 | 麻豆91网站 | 国产欧美在线一区 | 国产美女视频免费 | 成人免费在线网 | 天天曰夜夜爽 | 亚洲专区在线视频 | 美女很黄免费网站 | 黄色特一级片 | 欧美三级高清 | av免费观看网址 | 欧美肥妇free| 国产精品亚洲视频 | 国产 视频 高清 免费 | 国产精品久久av | 亚洲精品xxx| 夜夜操天天操 | 99久久综合狠狠综合久久 | 精品91视频| 黄色三级视频片 | 中国老女人日b | 国产精品你懂的在线观看 | 黄色影院在线观看 | 色综合久久久久网 | 国产色婷婷精品综合在线手机播放 | 久久亚洲福利 | 波多野结衣在线观看一区二区三区 | 一级黄色片网站 | 亚洲国产精品成人精品 | 久久久久久国产精品久久 | 91麻豆看国产在线紧急地址 | 久久久久免费网 | 精品伊人久久久 | 国产不卡在线视频 | 欧美一二三区在线观看 | 国产色综合天天综合网 | 操操操操网| 在线观看免费黄色 | 国产亚洲精品成人av久久ww | 81精品国产乱码久久久久久 | 国产裸体永久免费视频网站 | 精品国产成人av | 成人一级片免费看 | 狠狠干狠狠久久 | 9999精品免费视频 | 91精品国产高清自在线观看 | 成年人免费在线播放 | 日韩系列 | 综合铜03 | 免费在线观看av电影 | 免费看污黄网站 | 国产一级免费片 | 亚洲高清在线观看视频 | 久久精品视频免费播放 | 日韩xxxbbb| 天天av天天 | www色,com| 狠狠色狠狠色综合日日92 | 96亚洲精品久久久蜜桃 | 国产精品九九久久久久久久 |