From 8e943b7104561c3b14cf223016698709c5ade4b5 Mon Sep 17 00:00:00 2001
From: lty <876263681@qq.com>
Date: 星期二, 03 二月 2026 15:37:26 +0800
Subject: [PATCH] #pda料箱组托和换码

---
 src/main/webapp/static/js/report/locMap.js |  482 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 441 insertions(+), 41 deletions(-)

diff --git a/src/main/webapp/static/js/report/locMap.js b/src/main/webapp/static/js/report/locMap.js
index 3a3e6e8..d304e4a 100644
--- a/src/main/webapp/static/js/report/locMap.js
+++ b/src/main/webapp/static/js/report/locMap.js
@@ -1,60 +1,460 @@
-layui.use(['table','laydate', 'form'], function(){
+layui.use(['table', 'laydate', 'form'], function(){
     var $ = layui.jquery;
     var layer = layui.layer;
     var form = layui.form;
+    var areaMap = {};
 
-    getLocTable(1);
+    // Handlebars helper for area color
+    Handlebars.registerHelper('getAreaColor', function(areaId) {
+        if (areaId && areaMap[areaId] && areaMap[areaId].color) {
+            return areaMap[areaId].color;
+        }
+        return 'transparent';
+    });
 
-    function getLocTable(row){
+    // 鍒濆鍔犺浇
+    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+"/report/viewLocMapList.action",
+            url: baseUrl + '/area/list/auth?page=1&limit=1000',
             headers: {'token': localStorage.getItem('token')},
-            data: {row: row},
-            method: 'POST',
-            success: function (res) {
+            async: false,
+            success: function(res) {
                 if (res.code === 200) {
-                    var tpl = $("#locMapTemplate").html();
-                    var template = Handlebars.compile(tpl);
-                    var html = template(res.data);
-                    $('#locMap').html(html);
-                } else if (res.code === 403) {
-                    top.location.href = "/";
-                } else {
-                    layer.msg(res.msg)
+                    areaMap = {};
+                    var legendHtml = '<div class="area-legend-item" style="cursor:default;font-weight:bold;">' + I18n.t('zone_legend') + ':</div>';
+                    // 榛樿棰滆壊鍒楄〃锛岀敤浜庤嚜鍔ㄥ垎閰�
+                    var defaultColors = ['#FF5733', '#33FF57', '#3357FF', '#FF33A1', '#A133FF', '#33FFF5', '#FFD700', '#FF8C00'];
+                    var colorIndex = 0;
+
+                    res.data.records.forEach(function(area) {
+                        var color = area.backup1;
+                        // 澧炲己棰滆壊鏍¢獙锛氬鏋滀负绌恒�乶ull瀛楃涓叉垨闀垮害杩囩煭锛屽垯瑙嗕负鏃犳晥
+                        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();
                 }
             }
         });
     }
 
-    form.on('select(row)', function (data) {
-        getLocTable(data.value);
-    });
-});
+    // 缂栬緫搴撳尯棰滆壊
+    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;">' + I18n.t('zone_name') + ':</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;">' + I18n.t('select_color') + '</label>' +
+            '<div class="layui-input-inline"><input type="color" id="singleAreaColorPicker" value="' + (areaData.color || '#cccccc') + '" style="height: 38px; width: 100%;"></div>' +
+            '</div>' +
+            '</form></div>';
 
-var locNo = '';
-function locDetl(el) {
-    var value = $(el).attr('title');
-    var html = $(el).html();
-    if (value===null
-        ||value === undefined
-        || value.trim()===''
-        || html.trim()==='S'
-        || html.trim()==='D'
-        || html.trim()==='O'
-    ){
-
-    } else {
         layer.open({
-            type: 2,
-            title: '搴撲綅鐗╂枡',
-            maxmin: true,
-            area: [top.detailWidth, top.detailHeight],
-            shadeClose: true,
-            content: 'locDetl.html',
-            success: function(layero, index){
-                locNo = value;
+            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();
+
+        // 璁$畻妗嗛�夊尯鍩� (鐩稿浜庤鍙o紝鐢ㄤ簬 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 = '<option value="">' + I18n.t('please_select_zone') + '</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;">' + I18n.t('zone_color') + '</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: 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, // 鍚屾鏇存柊浠ョ‘淇濆埛鏂版椂棰滆壊姝g‘
+                                        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'));
+                }
+            }
+        });
+    });
+
+});
\ No newline at end of file

--
Gitblit v1.9.1