');
}
},
error: function () {
$('#shc-result', layero).html('
' + __('Query failed') + '
');
},
complete: function () {
$btn.prop('disabled', false);
}
});
},
renderSpecialHotCold: function (data, lookback, layero) {
var getColor = function (num) {
return Controller.api.getColorByNum(num);
};
var statusTag = function (status) {
var map = {
'hot': '🔥 热号',
'cold': '❄ 冷号',
'normal': '➜ 温号',
'unknown': '数据不足'
};
return map[status] || '';
};
// 新接口返回 {list: [...], current: {hot: [], cold: [], warm: []}}
var listData = data.list || data;
var current = data.current || null;
if (!listData || listData.length === 0) {
$('#shc-result', layero).html('
暂无数据
');
return;
}
var html = '
';
// 当前冷热号汇总区域
if (current && (current.hot.length > 0 || current.cold.length > 0)) {
var renderNumBall = function (item) {
var color = getColor(item.num);
return '' + item.num + '';
};
html += '
';
html += '
当前热号
';
html += '
';
for (var h = 0; h < current.hot.length; h++) {
html += renderNumBall(current.hot[h]);
}
if (current.hot.length === 0) {
html += '暂无热号';
}
html += '
';
html += '';
html += '
当前冷号
';
html += '
';
for (var c = 0; c < current.cold.length; c++) {
html += renderNumBall(current.cold[c]);
}
if (current.cold.length === 0) {
html += '暂无冷号';
}
html += '
';
html += '
';
}
// 历史记录表格
html += '
' +
'
' +
'
期号
' +
'
特码
' +
'
冷热
' +
'
次数
' +
'
平均
' +
'
排名
' +
'
';
for (var i = 0; i < listData.length; i++) {
var item = listData[i];
var rowClass = '';
if (item.status === 'hot') rowClass = 'style="background:#fff5f5;"';
else if (item.status === 'cold') rowClass = 'style="background:#f5f8ff;"';
html += '
' +
'
' + item.expect + '
' +
'
' +
'' + item.specialNum + '' +
'
' +
'
' + statusTag(item.status) + '
' +
'
' + item.count + '
' +
'
' + item.avgCount + '
' +
'
' + item.rank + '
' +
'
';
}
html += '
';
$('#shc-result', layero).html(html);
},
/**
* 筛号器弹窗
*/
showNumberFilterDialog: function () {
var html = '' +
'
';
Layer.open({
type: 1,
title: '筛号器',
area: ['700px', '750px'],
content: html,
shadeClose: true,
success: function (layero, index) {
// 渲染号码网格
Controller.api.renderNumberFilterGrid(layero);
// 尾号下拉选择
$('#nf-tail', layero).on('change', function () {
Controller.api.applyNumberFilters(layero);
});
// 生肖按钮点击
$('.nf-zodiac', layero).on('click', function () {
var $btn = $(this);
$btn.toggleClass('btn-default').toggleClass('btn-gray');
Controller.api.applyNumberFilters(layero);
});
// 波色按钮点击
$('.nf-color-btn', layero).on('click', function () {
var $btn = $(this);
$btn.toggleClass('btn-default').toggleClass('btn-gray');
Controller.api.applyNumberFilters(layero);
});
// 重置按钮
$('.btn-nf-reset', layero).on('click', function () {
$('#nf-tail', layero).val('');
$('.nf-zodiac', layero).removeClass('btn-gray').addClass('btn-default');
$('.nf-color-btn', layero).removeClass('btn-gray').addClass('btn-default');
Controller.api.applyNumberFilters(layero);
});
}
});
},
/**
* 渲染筛号器号码网格
*/
renderNumberFilterGrid: function (layero) {
var zodiacOrder = ['鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪'];
var zodiacNums = {};
for (var i = 0; i < zodiacOrder.length; i++) {
zodiacNums[zodiacOrder[i]] = [];
}
var colorMap = Controller.api.colorMap;
for (var num = 1; num <= 49; num++) {
var animal = Controller.api.getAnimalByNum(num);
if (!zodiacNums[animal]) zodiacNums[animal] = [];
zodiacNums[animal].push(num);
}
var html = '';
for (var z = 0; z < zodiacOrder.length; z++) {
var zodiac = zodiacOrder[z];
var nums = zodiacNums[zodiac];
if (nums.length === 0) continue;
html += '
';
html += '
' + zodiac + '
';
html += '
';
for (var i = 0; i < nums.length; i++) {
var num = nums[i];
var colorHex = Controller.api.getColorByNum(num);
var colorRaw = colorMap[num] || '';
var colorLabel = '';
if (colorRaw.indexOf('红') !== -1) colorLabel = '红';
else if (colorRaw.indexOf('蓝') !== -1) colorLabel = '蓝';
else if (colorRaw.indexOf('绿') !== -1) colorLabel = '绿';
html += '
' +
'' + num + '' +
'
' + zodiac + '
' +
'
';
}
html += '
';
}
$('#nf-numbers', layero).html(html);
},
/**
* 应用筛号器过滤条件
*/
applyNumberFilters: function (layero) {
var tailVal = $('#nf-tail', layero).val();
// 收集被点击(置灰)的生肖
var excludedZodiacs = [];
$('.nf-zodiac.btn-gray', layero).each(function () {
excludedZodiacs.push($(this).data('zodiac'));
});
// 收集被点击(置灰)的波色
var excludedColors = [];
$('.nf-color-btn.btn-gray', layero).each(function () {
excludedColors.push($(this).data('color'));
});
$('.nf-number', layero).each(function () {
var $num = $(this);
var num = parseInt($num.data('num'));
var tail = $num.data('tail');
var animal = $num.data('animal');
var color = $num.data('color');
var hidden = false;
// 尾号筛选:选择了具体尾号则屏蔽该尾号
if (tailVal !== '' && parseInt(tailVal) === tail) {
hidden = true;
}
// 排除的生肖
if (excludedZodiacs.indexOf(animal) !== -1) {
hidden = true;
}
// 排除的波色
if (excludedColors.indexOf(color) !== -1) {
hidden = true;
}
if (hidden) {
$num.css('opacity', '0.25').css('filter', 'grayscale(100%)');
} else {
$num.css('opacity', '1').css('filter', 'none');
}
});
},
bindevent: function () {
Form.api.bindevent($("form[role=form]"));
},
/**
* 通用分析弹窗(波色、生肖、奇偶、大小、尾数)
*/
showAnalysisDialog: function (type) {
var titles = {
colorWave: __('Color Wave'),
zodiac: __('Zodiac'),
oddEven: __('Odd/Even'),
bigSmall: __('Big/Small'),
tailNumbers: __('Tail Numbers')
};
var endpoints = {
colorWave: 'history/colorWaveAnalysis',
zodiac: 'history/zodiacAnalysis',
oddEven: 'history/oddEvenAnalysis',
bigSmall: 'history/bigSmallAnalysis',
tailNumbers: 'history/tailNumbers'
};
var hasType = ['colorWave', 'zodiac', 'oddEven', 'bigSmall', 'tailNumbers'].indexOf(type) !== -1;
var html = '
';
if (hasType) {
html += '
' +
' ' +
' ' +
' ' +
'
';
}
html += '
' +
' ' +
' ' +
' ' +
'
' +
'' +
'
';
Layer.open({
type: 1,
title: titles[type] || type,
area: ['650px', '550px'],
content: html,
shadeClose: true,
success: function (layero, index) {
$('#btn-analysis-' + type, layero).on('click', function () {
var periods = parseInt($('#analysis-periods-' + type, layero).val()) || 30;
var tp = hasType ? $('input[name="analysis-type-' + type + '"]:checked', layero).val() : 'all';
Controller.api.queryAnalysis(periods, tp, type, endpoints[type], layero);
});
if (hasType) {
$('input[name="analysis-type-' + type + '"]', layero).on('change', function () {
var periods = parseInt($('#analysis-periods-' + type, layero).val()) || 30;
Controller.api.queryAnalysis(periods, $(this).val(), type, endpoints[type], layero);
});
}
}
});
},
queryAnalysis: function (periods, type, analysisType, endpoint, layero) {
var $btn = $('#btn-analysis-' + analysisType, layero);
$btn.prop('disabled', true);
$('#analysis-result-' + analysisType, layero).html('
');
}
},
error: function () {
$('#dash-result', layero).html('
' + __('Query failed') + '
');
},
complete: function () {
$btn.prop('disabled', false);
}
});
},
renderDashboard: function (data, layero) {
var getColor = function (color) {
if (!color) return '#95a5a6';
if (color.indexOf('红') !== -1) return '#e74c3c';
if (color.indexOf('蓝') !== -1) return '#3498db';
if (color.indexOf('绿') !== -1) return '#2ecc71';
return '#95a5a6';
};
var hc = data.hotcold;
var cw = data.colorwave;
var zo = data.zodiac;
var oe = data.oddeven;
var bs = data.bigsmall;
var sm = data.sum;
var tn = data.tailnumbers;
var ballHtml = function (item) {
return '
' + item.num + '
' + item.count + '
';
};
var html = '
';
// 冷热号码
html += '
🔥❄️ 冷热号码
';
html += '
热号 Top5
';
for (var i = 0; i < 5; i++) html += ballHtml(hc.hot[i]);
html += '
冷号 Top5
';
for (var i = 0; i < 5; i++) html += ballHtml(hc.cold[i]);
html += '
';
// 波色分析
html += '
🎨 波色比例
';
html += '
';
html += '
' + cw.red + '
红波 ' + cw.red_pct + '%
';
html += '
' + cw.blue + '
蓝波 ' + cw.blue_pct + '%
';
html += '
' + cw.green + '
绿波 ' + cw.green_pct + '%
';
html += '
';
// 生肖分析
html += '
⭐ 生肖排名
';
html += '
';
for (var i = 0; i < Math.min(zo.list.length, 12); i++) {
var z = zo.list[i];
html += '
' + z.animal + '
' + z.count + ' (' + z.percent + '%)
';
}
html += '
';
// 奇偶分析
html += '
⚖️ 奇偶分析
';
html += '
';
html += '
' + oe.odd + ' (' + oe.odd_pct + '%)
奇数
';
html += '
' + oe.even + ' (' + oe.even_pct + '%)
偶数
';
html += '
';
// 大小分析
html += '
📊 大小分析
';
html += '
';
html += '
' + bs.big + ' (' + bs.big_pct + '%)
大数(25-49)
';
html += '
' + bs.small + ' (' + bs.small_pct + '%)
小数(1-24)
';
html += '
';
// 和值
html += '
📈 和值统计
';
html += '
';
html += '
' + sm.avg + '
平均
';
html += '
' + sm.max + '
最大
';
html += '
' + sm.min + '
最小
';
html += '
';
// 尾数
html += '
🔢 尾数频率
';
html += '
';
for (var i = 0; i < tn.all.length; i++) {
var t = tn.all[i];
html += '