Explorar o código

feat(files): 为固定目录单元格添加锁图标标记

- 新增 _initFixedDirectoryMarker 方法,通过扩展树形单元格类型绘制锁图标
- 重写 paint 方法,在固定目录单元格右侧绘制锁图标并裁切名称区域
- 重写 showTip 方法,调整提示区域避免遮挡锁图标
- 重写鼠标事件方法,悬停锁图标时显示"不可改名、不可删除"提示
- 拦截锁图标区域的点击事件,防止触发编辑操作
- 在初始化流程中调用该方法完成标记注册
caipin hai 16 horas
pai
achega
2910cf0648
Modificáronse 1 ficheiros con 87 adicións e 0 borrados
  1. 87 0
      app/public/js/filesjs.js

+ 87 - 0
app/public/js/filesjs.js

@@ -92,6 +92,7 @@ $(document).ready(function() {
             this._bindEvents();
             this._initNameClipboard();
             this._loadFilingData();
+            this._initFixedDirectoryMarker();
             this.refreshFileOrderButton();
         }
 
@@ -1345,6 +1346,92 @@ $(document).ready(function() {
             SpreadJsObj.safeRightClickSelection($trigger, e, spread);
             return true;
         }
+
+        _initFixedDirectoryMarker() {
+            // 仅装饰当前目录表的单元格实例,名称数据及其他页面的树表保持原样。
+            const cellType = this.sheet.extendCellType.tree;
+            const host = this.spread.getHost();
+            const paint = cellType.paint, showTip = cellType.showTip;
+            const mouseEnter = cellType.processMouseEnter, mouseLeave = cellType.processMouseLeave;
+            const mouseMove = cellType.processMouseMove, mouseDown = cellType.processMouseDown;
+            const markerWidth = 20, iconSize = 12, rightPadding = 6;
+            const isFixed = (sheet, row, col) => col === 0 && sheet.zh_tree &&
+                sheet.zh_tree.nodes[row] && Number(sheet.zh_tree.nodes[row].is_fixed);
+            const hasMarker = hit => isFixed(hit.sheet, hit.row, hit.col) &&
+                hit.cellRect.width >= markerWidth && hit.cellRect.height >= iconSize;
+            const hitsMarker = hit => hasMarker(hit) &&
+                hit.x >= hit.cellRect.x + hit.cellRect.width - rightPadding - iconSize &&
+                hit.x <= hit.cellRect.x + hit.cellRect.width - rightPadding &&
+                Math.abs(hit.y - hit.cellRect.y - hit.cellRect.height / 2) <= iconSize / 2;
+            let overMarker = false;
+
+            cellType.paint = function(canvas, value, x, y, w, h, style, options) {
+                if (!isFixed(options.sheet, options.row, options.col) || w < markerWidth || h < iconSize) {
+                    return paint.apply(this, arguments);
+                }
+                // 树缩进、图标和文字均裁切在名称区域内,深层目录也不会覆盖右侧锁标识。
+                canvas.save();
+                canvas.beginPath();
+                canvas.rect(x, y, w - markerWidth, h);
+                canvas.clip();
+                paint.call(this, canvas, value, x, y, w - markerWidth, h, style, options);
+                canvas.restore();
+                canvas.save();
+                canvas.beginPath();
+                canvas.rect(x + w - markerWidth, y, markerWidth, h);
+                canvas.clip();
+                canvas.fillStyle = style.backColor || 'white';
+                canvas.fillRect(x + w - markerWidth, y, markerWidth, h);
+                canvas.translate(x + w - rightPadding - iconSize, y + (h - iconSize) / 2);
+                canvas.strokeStyle = '#8a949e';
+                canvas.lineWidth = 1.2;
+                canvas.beginPath();
+                canvas.moveTo(3.5, 5.5);
+                canvas.lineTo(3.5, 3.5);
+                canvas.bezierCurveTo(3.5, .5, 8.5, .5, 8.5, 3.5);
+                canvas.lineTo(8.5, 5.5);
+                canvas.stroke();
+                canvas.strokeRect(1.5, 5.5, 9, 6);
+                canvas.beginPath();
+                canvas.moveTo(6, 8);
+                canvas.lineTo(6, 10);
+                canvas.stroke();
+                canvas.restore();
+            };
+            cellType.showTip = function(hit, text) {
+                if (!hasMarker(hit)) return showTip.call(this, hit, text);
+                const nameHit = Object.assign({}, hit, {
+                    cellRect: Object.assign({}, hit.cellRect, { width: hit.cellRect.width - markerWidth }),
+                });
+                return showTip.call(this, nameHit, text);
+            };
+            cellType.processMouseEnter = function(hit) {
+                overMarker = hitsMarker(hit);
+                if (overMarker) {
+                    mouseLeave.call(this, hit);
+                    host.setAttribute('title', '固定目录:不可改名、不可删除');
+                } else {
+                    host.removeAttribute('title');
+                    return mouseEnter.call(this, hit);
+                }
+            };
+            cellType.processMouseMove = function(hit) {
+                if (hitsMarker(hit) !== overMarker) {
+                    mouseLeave.call(this, hit);
+                    this.processMouseEnter(hit);
+                }
+                if (mouseMove) return mouseMove.call(this, hit);
+            };
+            cellType.processMouseLeave = function(hit) {
+                overMarker = false;
+                host.removeAttribute('title');
+                return mouseLeave.call(this, hit);
+            };
+            cellType.processMouseDown = function(hit) {
+                if (!hitsMarker(hit)) return mouseDown.call(this, hit);
+            };
+            this.sheet.repaint();
+        }
     }
 
     // 初始化