Explorar el Código

项目大屏调整

ellisran hace 1 semana
padre
commit
251ab79707

+ 36 - 0
app/lib/project_screen.js

@@ -0,0 +1,36 @@
+'use strict';
+
+module.exports = {
+    getProgressPaths(rows) {
+        const nodes = new Map(rows.map(row => [String(row.tree_id), row]));
+        const paths = new Map();
+        for (const row of rows) {
+            const path = [];
+            const visited = new Set();
+            let node = row;
+            while (node && !visited.has(String(node.tree_id))) {
+                path.unshift(node);
+                visited.add(String(node.tree_id));
+                node = nodes.get(String(node.tree_pid));
+            }
+            paths.set(row.id, path);
+        }
+        return paths;
+    },
+    sortProgressRows(rows, paths) {
+        return rows.slice().sort((a, b) => {
+            const pathA = paths.get(a.id);
+            const pathB = paths.get(b.id);
+            for (let i = 0; i < Math.min(pathA.length, pathB.length); i++) {
+                if (pathA[i].id === pathB[i].id) continue;
+                return pathA[i].tree_order - pathB[i].tree_order || String(pathA[i].id).localeCompare(String(pathB[i].id));
+            }
+            return pathA.length - pathB.length;
+        });
+    },
+    formatProgressPath(path, abbreviated = false) {
+        const names = path.map(node => node.name);
+        if (abbreviated && names.length > 2) return [names[0], '...', names[names.length - 1]].join(' / ');
+        return names.join(' / ');
+    },
+};

+ 7 - 6
app/public/css/main.css

@@ -2851,13 +2851,14 @@ animation:shake 1s .2s ease both;}
 .gy-stage-dialog #gy-dialog-project{font-size:16px;font-weight:400;line-height:1.6;color:#c4d4e5;overflow-wrap:anywhere}
 .gy-stage-dialog .gy-table thead th{text-align:center!important}
 .gy-stage-dialog .gy-table tbody td{text-align:center!important}
-.gy-stage-dialog .gy-table thead th:first-child,.gy-stage-dialog .gy-table tbody td:first-child{text-align:left!important}
+.gy-stage-dialog .gy-table tbody td:nth-child(2){text-align:left!important}
 .gy-stage-dialog .gy-stage-group .gy-table{table-layout:fixed}
-.gy-stage-dialog .gy-stage-group th:first-child{width:46%}
-.gy-stage-dialog .gy-stage-group th:nth-child(2){width:14%}
-.gy-stage-dialog .gy-stage-group th:nth-child(3){width:18%}
-.gy-stage-dialog .gy-stage-group th:last-child{width:22%}
-.gy-stage-dialog .gy-stage-group td:first-child,.gy-stage-dialog .gy-stage-group td:last-child{white-space:normal;overflow-wrap:anywhere}
+.gy-stage-dialog .gy-stage-group th:first-child{width:10%}
+.gy-stage-dialog .gy-stage-group th:nth-child(2){width:38%}
+.gy-stage-dialog .gy-stage-group th:nth-child(3){width:14%}
+.gy-stage-dialog .gy-stage-group th:nth-child(4){width:18%}
+.gy-stage-dialog .gy-stage-group th:last-child{width:20%}
+.gy-stage-dialog .gy-stage-group td:nth-child(2),.gy-stage-dialog .gy-stage-group td:last-child{white-space:normal;overflow-wrap:anywhere}
 .gy-stage-dialog .close:focus:not(:focus-visible){outline:none;box-shadow:none}
 .gy-stage-dialog .gy-stage-group{--gy-stage-accent:#67b7ff;border:1px solid #52616e;border-radius:6px;overflow:auto}
 .gy-stage-dialog .gy-stage-group + .gy-stage-group{margin-top:24px}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 3
app/public/js/project_screen_guangyuan.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 2
app/public/js/project_screen_guangyuan_building.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 4 - 4
app/public/js/project_screen_guangyuan_finished.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 3 - 3
app/public/js/project_screen_guangyuan_planned.js


+ 23 - 18
app/service/project_screen.js

@@ -1,6 +1,7 @@
 'use strict';
 
 const projectScreenConst = require('../const/project_screen');
+const projectScreenLib = require('../lib/project_screen');
 const Ledger = require('../lib/ledger');
 
 module.exports = app => {
@@ -225,13 +226,15 @@ module.exports = app => {
                 }
                 const parent = nodes.find(n => n.id === node.tree_pid);
                 const progressRows = allProgress.filter(row => row.spid === node.id);
+                const progressPaths = projectScreenLib.getProgressPaths(progressRows);
                 const latest = progressRows[0];
                 const keys = ['edit', 'submit', 'reply'];
                 const latestEvent = latest && keys.map((key, index) => ({ date: latest[key + '_date'], department: latest[key + '_department'], step: ['编制', '报审', '批复'][index] }))
                     .filter(event => event.date).sort((a, b) => String(b.date).localeCompare(String(a.date)))[0];
-                const stages = progressRows.filter(row => row.tree_level > 1 && row.tree_is_leaf === 1).map(row => ({
-                    id: row.id, name: row.name,
-                    path: String(row.tree_full_path).split('-').map(id => progressRows.find(p => String(p.tree_id) === id)).filter(Boolean).map(p => p.name).join(' / ') || row.name,
+                const stages = projectScreenLib.sortProgressRows(progressRows, progressPaths).filter(row => row.tree_level > 1 && row.tree_is_leaf === 1).map(row => ({
+                    id: row.id, name: row.name, code: row.code || '',
+                    path: projectScreenLib.formatProgressPath(progressPaths.get(row.id)),
+                    shortPath: projectScreenLib.formatProgressPath(progressPaths.get(row.id), true),
                     states: keys.map(key => row[key + '_progress'] === '已完成' ? 0 : row[key + '_progress'] === '进行中' ? 1 : 2),
                     dates: keys.map(key => row[key + '_date'] || ''), departments: keys.map(key => row[key + '_department'] || '')
                 }));
@@ -261,21 +264,23 @@ module.exports = app => {
             }) : [];
             const dateText = value => value instanceof Date ? [value.getFullYear(), String(value.getMonth() + 1).padStart(2, '0'), String(value.getDate()).padStart(2, '0')].join('-') : String(value || '').slice(0, 10);
             const trees = new Map(projects.map(p => [p.id, rows.filter(row => row.spid === p.id)]));
-            const leafColumns = tree => tree.filter(row => Number(row.tree_level) > 1 && Number(row.tree_is_leaf) === 1)
-                .sort((a, b) => a.tree_order - b.tree_order).map(row => {
-                    const path = String(row.tree_full_path).split('-').map(id => tree.find(n => String(n.tree_id) === id)).filter(Boolean);
-                    if (!path.length || path[path.length - 1].id !== row.id) path.push(row);
-                    return { key: JSON.stringify([path[0].name, row.name]), root: path[0].name,
-                        rootOrder: Number(path[0].tree_order) || 0,
-                        orderPath: path.slice(1).map(n => Number(n.tree_order) || 0),
-                        name: row.name, date: dateText(row.reply_date) };
-                }).sort((a, b) => {
-                    if (a.root !== b.root) return a.rootOrder - b.rootOrder || a.root.localeCompare(b.root, 'zh-CN');
-                    for (let i = 0; i < Math.min(a.orderPath.length, b.orderPath.length); i++) {
-                        if (a.orderPath[i] !== b.orderPath[i]) return a.orderPath[i] - b.orderPath[i];
-                    }
-                    return a.orderPath.length - b.orderPath.length;
-                });
+            const leafColumns = tree => {
+                const paths = projectScreenLib.getProgressPaths(tree);
+                return tree.filter(row => Number(row.tree_level) > 1 && Number(row.tree_is_leaf) === 1)
+                    .sort((a, b) => a.tree_order - b.tree_order).map(row => {
+                        const path = paths.get(row.id);
+                        return { key: JSON.stringify([path[0].name, row.name]), root: path[0].name,
+                            rootOrder: Number(path[0].tree_order) || 0,
+                            orderPath: path.slice(1).map(n => Number(n.tree_order) || 0),
+                            name: row.name, date: dateText(row.reply_date) };
+                    }).sort((a, b) => {
+                        if (a.root !== b.root) return a.rootOrder - b.rootOrder || a.root.localeCompare(b.root, 'zh-CN');
+                        for (let i = 0; i < Math.min(a.orderPath.length, b.orderPath.length); i++) {
+                            if (a.orderPath[i] !== b.orderPath[i]) return a.orderPath[i] - b.orderPath[i];
+                        }
+                        return a.orderPath.length - b.orderPath.length;
+                    });
+            };
             const columnsByProject = new Map(projects.map(p => [p.id, leafColumns(trees.get(p.id))]));
             const approvedKeys = new Set([].concat(...Array.from(columnsByProject.values())).filter(column => column.date).map(column => column.key));
             // Merge same leaf names under the same root, regardless of intermediate paths.