layui.use(['table', 'laydate', 'form'], function(){
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var areaMap = {};
// Handlebars helper for area color
Handlebars.registerHelper('getAreaColor', function(areaId) {
if (areaId && areaMap[areaId] && areaMap[areaId].color) {
return areaMap[areaId].color;
}
return 'transparent';
});
// 初始加载
function initMap() {
loadAreas(); // 加载库区颜色信息
loadRowsOptions(); // 加载「排」选项(始终需要)
loadLayersOptions(); // 加载「层」选项(提前准备)
getLocTable('byRow', 1); // 默认按排 + 第1排
}
if (I18n.isReady()) {
initMap();
} else {
$(document).on('i18n:ready', initMap);
}
// Listen for dynamic language updates (no reload)
$(document).on('i18n:updated', function() {
// Update selection button text
if (isSelectionMode) {
$('#btnSelectMode').text(I18n.t('disable_selection'));
} else {
$('#btnSelectMode').text(I18n.t('enable_selection'));
}
// Update assign button text if visible
if ($('.loc-selected').length > 0) {
$('#btnAssignZone').text(I18n.t('assign_zone') + ' (' + $('.loc-selected').length + ')');
} else {
$('#btnAssignZone').text(I18n.t('assign_zone'));
}
// Re-render legend to update text
loadAreas();
// Re-render select options if needed (but options usually don't have text needing translation unless hardcoded)
// Re-render form to apply changes
form.render();
});
// 加载库区信息并显示图例
function loadAreas() {
$.ajax({
url: baseUrl + '/area/list/auth?page=1&limit=1000',
headers: {'token': localStorage.getItem('token')},
async: false,
success: function(res) {
if (res.code === 200) {
areaMap = {};
var legendHtml = '
' + I18n.t('zone_legend') + ':
';
// 默认颜色列表,用于自动分配
var defaultColors = ['#FF5733', '#33FF57', '#3357FF', '#FF33A1', '#A133FF', '#33FFF5', '#FFD700', '#FF8C00'];
var colorIndex = 0;
res.data.records.forEach(function(area) {
var color = area.backup1;
// 增强颜色校验:如果为空、null字符串或长度过短,则视为无效
if (!color || color === 'null' || color.trim().length < 3) {
color = defaultColors[colorIndex % defaultColors.length];
colorIndex++;
}
areaMap[area.id] = {name: area.areaName, color: color, fullArea: area};
legendHtml += '' + area.areaName + '
';
});
$('#areaLegend').html(legendHtml).show();
}
}
});
}
// 编辑库区颜色
window.editAreaColor = function(areaId) {
if (!areaId || !areaMap[areaId]) return;
var areaData = areaMap[areaId];
var contentHtml = '';
layer.open({
type: 1,
title: I18n.t('modify_zone_color'),
area: ['350px', '250px'],
content: contentHtml,
btn: [I18n.t('save'), I18n.t('cancel')],
yes: function(index) {
var newColor = $('#singleAreaColorPicker').val();
if (newColor !== areaData.color) {
$.ajax({
url: baseUrl + '/area/update/auth',
method: 'POST',
headers: {'token': localStorage.getItem('token')},
data: { id: areaId, backup1: newColor },
success: function(res) {
if (res.code === 200) {
layer.msg(I18n.t('color_updated'));
layer.close(index);
loadAreas(); // 刷新图例和缓存
// 刷新地图以应用新颜色
var mode = $('#viewMode').val();
if (mode === 'byRow') getLocTable('byRow', $('#rowSelect').val());
else getLocTable('byLayer', $('#layerSelect').val());
} else {
layer.msg(res.msg || I18n.t('update_failed'));
}
}
});
} else {
layer.close(index);
}
}
});
};
// 加载所有可用排
function loadRowsOptions() {
$.ajax({
url: baseUrl + "/report/viewLocMapList/rows.action",
headers: {'token': localStorage.getItem('token')},
method: 'POST',
async: false,
success: function (res) {
if (res.code === 200) {
var tpl = $("#locMastRowTemplate").html();
var template = Handlebars.compile(tpl);
$('#rowSelect').append(template(res));
form.render('select');
} else if (res.code === 403) {
top.location.href = baseUrl + "/";
}
}
});
}
// 加载所有可用层(需要后端支持新接口)
function loadLayersOptions() {
$.ajax({
url: baseUrl + "/report/viewLocMapList/layers.action",
headers: {'token': localStorage.getItem('token')},
method: 'POST',
async: false,
success: function (res) {
if (res.code === 200) {
var tpl = $("#locMastRowTemplate").html();
var template = Handlebars.compile(tpl);
$('#layerSelect').append(template(res));
form.render('select');
}
}
});
}
// 核心:根据模式加载库位表
function getLocTable(mode, value) {
var url = baseUrl + "/report/viewLocMapList.action";
var data = {};
if (mode === 'byRow') {
data.row = value;
} else if (mode === 'byLayer') {
data.layer = value;
}
$.ajax({
url: url,
headers: {'token': localStorage.getItem('token')},
data: data,
method: 'POST',
success: function (res) {
if (res.code === 200) {
var tpl = $("#locMapTemplate").html();
var template = Handlebars.compile(tpl);
$('#locMap').html(template(res.data));
} else if (res.code === 403) {
top.location.href = baseUrl + "/";
} else {
layer.msg(res.msg || I18n.t('load_failed'));
}
}
});
}
// 监听 显示模式 切换
form.on('select(viewMode)', function (data) {
var mode = data.value;
if (mode === 'byRow') {
$('#rowSelectBox').show();
$('#layerSelectBox').hide();
// 读取当前选中的排
var currentRow = $('#rowSelect').val() || 1;
getLocTable('byRow', currentRow);
} else if (mode === 'byLayer') {
$('#rowSelectBox').hide();
$('#layerSelectBox').show();
var currentLayer = $('#layerSelect').val() || 1;
getLocTable('byLayer', currentLayer);
}
});
// 监听 排 变化
form.on('select(row)', function (data) {
if ($('#viewMode').val() === 'byRow') {
getLocTable('byRow', data.value);
}
});
// 监听 层 变化
form.on('select(layer)', function (data) {
if ($('#viewMode').val() === 'byLayer') {
getLocTable('byLayer', data.value);
}
});
// --- 框选功能 ---
var isSelectionMode = false;
var isDragging = false;
var startX, startY;
var $selectionBox = $('#selectionBox');
var $container = $('#locMapContain');
$('#btnSelectMode').click(function () {
isSelectionMode = !isSelectionMode;
if (isSelectionMode) {
$(this).text(I18n.t('disable_selection')).addClass('layui-btn-danger').removeClass('layui-btn-normal');
// 禁用原有点击事件,防止冲突 (通过 CSS pointer-events 或移除 onclick)
// 这里选择移除 onclick 属性
$('.a-loc').each(function(){
$(this).attr('data-onclick', $(this).attr('onclick')).removeAttr('onclick');
});
layer.msg(I18n.t('selection_mode_tip'));
} else {
$(this).text(I18n.t('enable_selection')).addClass('layui-btn-normal').removeClass('layui-btn-danger');
$('.loc-selected').removeClass('loc-selected');
$('#btnAssignZone').hide();
// 恢复点击事件
$('.a-loc').each(function(){
if($(this).attr('data-onclick')) {
$(this).attr('onclick', $(this).attr('data-onclick'));
}
});
}
});
$container.on('mousedown', function (e) {
if (!isSelectionMode) return;
// 如果点在滚动条上,可能也会触发,简单判断目标是否是 container 或 table
if(e.target.tagName !== 'TD' && e.target.id !== 'locMapContain' && e.target.tagName !== 'TABLE' && e.target.tagName !== 'TBODY' && e.target.tagName !== 'TR') return;
isDragging = true;
var offset = $container.offset();
// 相对于 container 内容的坐标 (包含滚动)
startX = e.pageX - offset.left + $container.scrollLeft();
startY = e.pageY - offset.top + $container.scrollTop();
$selectionBox.css({
left: startX,
top: startY,
width: 0,
height: 0,
display: 'block'
});
// 阻止默认文本选择
e.preventDefault();
});
$container.on('mousemove', function (e) {
if (!isSelectionMode || !isDragging) return;
var offset = $container.offset();
var currentX = e.pageX - offset.left + $container.scrollLeft();
var currentY = e.pageY - offset.top + $container.scrollTop();
var width = Math.abs(currentX - startX);
var height = Math.abs(currentY - startY);
var left = Math.min(currentX, startX);
var top = Math.min(currentY, startY);
$selectionBox.css({
width: width,
height: height,
left: left,
top: top
});
});
$(document).on('mouseup', function (e) {
if (!isSelectionMode || !isDragging) return;
isDragging = false;
$selectionBox.hide();
// 计算框选区域 (相对于视口,用于 getBoundingClientRect 比较)
// 或者都转换为相对于 container 的坐标
// 这里使用相对于 container 的坐标比较更稳妥
var boxLeft = parseFloat($selectionBox.css('left'));
var boxTop = parseFloat($selectionBox.css('top'));
var boxWidth = parseFloat($selectionBox.css('width'));
var boxHeight = parseFloat($selectionBox.css('height'));
var boxRight = boxLeft + boxWidth;
var boxBottom = boxTop + boxHeight;
// 获取 container 的 offset
var containerOffset = $container.offset();
$('.a-loc').each(function () {
var $el = $(this);
var elOffset = $el.offset();
// 转换为相对于 container 的坐标 (加上 scroll)
var elLeft = elOffset.left - containerOffset.left + $container.scrollLeft();
var elTop = elOffset.top - containerOffset.top + $container.scrollTop();
var elWidth = $el.outerWidth();
var elHeight = $el.outerHeight();
var elRight = elLeft + elWidth;
var elBottom = elTop + elHeight;
// 碰撞检测
if (!(elLeft > boxRight || elRight < boxLeft || elTop > boxBottom || elBottom < boxTop)) {
$el.toggleClass('loc-selected');
}
});
if ($('.loc-selected').length > 0) {
$('#btnAssignZone').show().text(I18n.t('assign_zone') + ' (' + $('.loc-selected').length + ')');
} else {
$('#btnAssignZone').hide();
}
});
// --- 分配库区 ---
$('#btnAssignZone').click(function () {
var selectedLocs = [];
$('.loc-selected').each(function () {
selectedLocs.push($(this).attr('title')); // title has locNo
});
if (selectedLocs.length === 0) return;
// 获取库区列表
$.ajax({
url: baseUrl + '/area/list/auth?page=1&limit=1000',
headers: {'token': localStorage.getItem('token')},
success: function(listRes) {
if (listRes.code === 200) {
var optionsHtml = '';
var areas = listRes.data.records;
areas.forEach(function(area) {
optionsHtml += '';
});
var contentHtml = '';
layer.open({
type: 1,
title: I18n.t('assign_zone_and_color'),
area: ['400px', '350px'],
content: contentHtml,
btn: [I18n.t('confirm'), I18n.t('cancel')],
success: function(layero, index) {
form.render('select');
form.on('select(selectArea)', function(data){
var areaId = data.value;
if(areaId && areaMap[areaId]) {
$('#areaColorPicker').val(areaMap[areaId].color || '#cccccc');
}
});
},
yes: function(index) {
var areaId = $('#selectArea').val();
var newColor = $('#areaColorPicker').val();
if (!areaId) {
layer.msg(I18n.t('please_select_zone'));
return;
}
// 1. 更新库区颜色 (如果有变化)
if (areaMap[areaId] && areaMap[areaId].color !== newColor) {
$.ajax({
url: baseUrl + '/area/update/auth',
method: 'POST',
headers: {'token': localStorage.getItem('token')},
data: { id: areaId, backup1: newColor },
async: false, // 同步更新以确保刷新时颜色正确
success: function() {
loadAreas(); // 刷新图例和缓存
}
});
}
// 2. 批量更新库位
$.ajax({
url: baseUrl + '/locMast/batchUpdateArea/auth',
method: 'POST',
headers: {'token': localStorage.getItem('token')},
contentType: 'application/json',
data: JSON.stringify({
locNos: selectedLocs,
areaId: parseInt(areaId)
}),
success: function(updRes) {
if (updRes.code === 200) {
layer.msg(I18n.t('assign_success'));
layer.close(index);
// 刷新
var mode = $('#viewMode').val();
if (mode === 'byRow') getLocTable('byRow', $('#rowSelect').val());
else getLocTable('byLayer', $('#layerSelect').val());
// 重置状态
$('.loc-selected').removeClass('loc-selected');
$('#btnAssignZone').hide();
// 保持框选模式
if(isSelectionMode) {
// 重新移除onclick
setTimeout(function(){
$('.a-loc').each(function(){
$(this).attr('data-onclick', $(this).attr('onclick')).removeAttr('onclick');
});
}, 500); // 简单延时等待渲染
}
} else {
layer.msg(updRes.msg || I18n.t('operation_failed'));
}
}
});
}
});
} else {
layer.msg(listRes.msg || I18n.t('fetch_zone_list_failed'));
}
}
});
});
});