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';
|
});
|
|
// 初始加载
|
loadAreas(); // 加载库区颜色信息
|
loadRowsOptions(); // 加载「排」选项(始终需要)
|
loadLayersOptions(); // 加载「层」选项(提前准备)
|
getLocTable('byRow', 1); // 默认按排 + 第1排
|
|
// 加载库区信息并显示图例
|
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 = '<div class="area-legend-item" style="cursor:default;font-weight:bold;">库区图例:</div>';
|
// 默认颜色列表,用于自动分配
|
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 += '<div class="area-legend-item" onclick="editAreaColor(\'' + area.id + '\')"><span class="area-color-box" style="background-color:' + color + '"></span>' + area.areaName + '</div>';
|
});
|
$('#areaLegend').html(legendHtml).show();
|
}
|
}
|
});
|
}
|
|
// 编辑库区颜色
|
window.editAreaColor = function(areaId) {
|
if (!areaId || !areaMap[areaId]) return;
|
var areaData = areaMap[areaId];
|
|
var contentHtml = '<div style="padding: 20px;"><form class="layui-form">' +
|
'<div class="layui-form-item">' +
|
'<label class="layui-form-label" style="width: auto; padding-left: 0;">库区名称:</label>' +
|
'<div class="layui-input-inline" style="line-height: 45px;">' + areaData.name + '</div>' +
|
'</div>' +
|
'<div class="layui-form-item">' +
|
'<label class="layui-form-label" style="width: auto; padding-left: 0;">选择颜色</label>' +
|
'<div class="layui-input-inline"><input type="color" id="singleAreaColorPicker" value="' + (areaData.color || '#cccccc') + '" style="height: 38px; width: 100%;"></div>' +
|
'</div>' +
|
'</form></div>';
|
|
layer.open({
|
type: 1,
|
title: '修改库区颜色',
|
area: ['350px', '250px'],
|
content: contentHtml,
|
btn: ['保存', '取消'],
|
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('颜色已更新');
|
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 || '更新失败');
|
}
|
}
|
});
|
} 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 || '加载失败');
|
}
|
}
|
});
|
}
|
|
// 监听 显示模式 切换
|
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('关闭框选').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('已开启框选模式,请在库位图上拖拽选择');
|
} else {
|
$(this).text('开启框选').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('分配库区 (' + $('.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 = '<option value="">请选择库区</option>';
|
var areas = listRes.data.records;
|
areas.forEach(function(area) {
|
optionsHtml += '<option value="' + area.id + '">' + area.areaName + ' (' + area.areaId + ')</option>';
|
});
|
|
var contentHtml = '<div style="padding: 20px;"><form class="layui-form">' +
|
'<div class="layui-form-item"><select id="selectArea" lay-filter="selectArea">' + optionsHtml + '</select></div>' +
|
'<div class="layui-form-item">' +
|
'<label class="layui-form-label" style="width: auto; padding-left: 0;">库区颜色</label>' +
|
'<div class="layui-input-inline"><input type="color" id="areaColorPicker" value="#cccccc" style="height: 38px; width: 100%;"></div>' +
|
'</div>' +
|
'</form></div>';
|
|
layer.open({
|
type: 1,
|
title: '分配库区及颜色',
|
area: ['400px', '350px'],
|
content: contentHtml,
|
btn: ['确定', '取消'],
|
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('请选择库区');
|
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('分配成功');
|
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 || '操作失败');
|
}
|
}
|
});
|
}
|
});
|
} else {
|
layer.msg(listRes.msg || '无法获取库区列表');
|
}
|
}
|
});
|
});
|
|
});
|