Просмотр исходного кода

feat(inspection-flow): 增强整改阶段进度与结果展示

- 新增整改阶段进度条,显示同时整改的完成数量
- 整改阶段展示整改内容及整改日期信息
- 整改阶段可编辑时支持移除整改人操作
- 重构审批流程布局,统一摘要与详情结构
- 整改阶段状态文本改用流程状态替代审批通过
- 调整整改阶段意见标签为说明并优化空状态提示
caipin 2 недель назад
Родитель
Сommit
d8d03cfe70
3 измененных файлов с 62 добавлено и 66 удалено
  1. 24 0
      app/public/css/main.css
  2. 19 33
      app/view/quality/inspection_flow.ejs
  3. 19 33
      app/view/safe/inspection_flow.ejs

+ 24 - 0
app/public/css/main.css

@@ -3311,6 +3311,18 @@ button.gy-stat:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
 .safe-inspection-flow .flow-phase-person {
     padding: 12px 18px;
 }
+.safe-inspection-flow .flow-progress-layout .flow-phase-title,
+.safe-inspection-flow .flow-stage-progress,
+.safe-inspection-flow .flow-timeline-empty {
+    margin-left: 70px;
+}
+.safe-inspection-flow .flow-stage-progress {
+    margin-bottom: 8px;
+}
+.safe-inspection-flow .flow-rectification-result {
+    white-space: pre-wrap;
+    overflow-wrap: break-word;
+}
 .safe-inspection-flow .flow-person-names {
     min-width: 0;
     overflow-wrap: break-word;
@@ -3473,6 +3485,18 @@ button.gy-stat:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
 .quality-inspection-flow .flow-phase-person {
     padding: 12px 18px;
 }
+.quality-inspection-flow .flow-progress-layout .flow-phase-title,
+.quality-inspection-flow .flow-stage-progress,
+.quality-inspection-flow .flow-timeline-empty {
+    margin-left: 70px;
+}
+.quality-inspection-flow .flow-stage-progress {
+    margin-bottom: 8px;
+}
+.quality-inspection-flow .flow-rectification-result {
+    white-space: pre-wrap;
+    overflow-wrap: break-word;
+}
 .quality-inspection-flow .flow-person-names {
     min-width: 0;
     overflow-wrap: break-word;

+ 19 - 33
app/view/quality/inspection_flow.ejs

@@ -21,8 +21,7 @@
     <% } else { %>
         <div class="flow-title text-center mb-1">审批流程</div>
     <% } %>
-    <% if (!showTimeline) { %>
-    <div class="row flow-layout">
+    <div class="row flow-layout<%= showTimeline ? ' flow-progress-layout' : '' %>">
         <div class="col-md-4 flow-summary mb-3">
             <table class="table table-bordered table-sm flow-summary-table mb-0" aria-label="审批流程人员">
                 <colgroup><col class="flow-phase-label"><col></colgroup>
@@ -49,7 +48,6 @@
             </table>
         </div>
         <div class="col-md-8 flow-details">
-    <% } %>
             <% inspection.flowStages.forEach(phase => { %>
                 <% if (phase.stage === 1 || inspection.need_rectification || !inspection.readOnly) { %>
                     <% const reportMode = ctx.tender.info.shenpi.inspection;
@@ -58,27 +56,6 @@
                     <% if (showTimeline) { %>
                     <section class="flow-phase-section" data-flow-stage="<%= phase.stage %>">
                         <div class="flow-phase-title text-center text-muted">巡检<%= phase.name %></div>
-                        <div class="row flow-layout">
-                            <div class="col-md-4 flow-summary mb-3">
-                                <div class="card">
-                                    <ul class="list-group list-group-flush">
-                                        <% phase.nodes.forEach(node => { %>
-                                            <li class="list-group-item d-flex align-items-center flow-phase-person">
-                                                <i class="fa <%= node.origin ? 'fa-play-circle fa-rotate-90' : node.label === '终审' ? 'fa-stop-circle' : 'fa-chevron-circle-down' %> mr-2" aria-hidden="true"></i>
-                                                <div class="flow-person-names">
-                                                    <% node.auditors.forEach(audit => { %><div><%= audit.name %></div><% }); %>
-                                                </div>
-                                                <div class="ml-auto pl-2 text-right">
-                                                    <span class="badge badge-light badge-pill"><%= node.label %></span>
-                                                    <% if (phase.stage === 2) { %><small class="d-block text-muted"><%= flowStatusText[node.status] %></small><% } %>
-                                                </div>
-                                            </li>
-                                        <% }); %>
-                                        <% if (!phase.nodes.length) { %><li class="list-group-item text-muted"><%= phase.stage === 2 ? '整改人由上报审批人指派' : '尚未设置审批人' %></li><% } %>
-                                    </ul>
-                                </div>
-                            </div>
-                            <div class="col-md-8 flow-details">
                     <% } else { %>
                     <div class="mb-3<%= phase.stage !== 1 && !inspection.need_rectification ? ' d-none' : '' %>" data-flow-stage="<%= phase.stage %>">
                     <% } %>
@@ -109,7 +86,12 @@
                                 </div>
                             </div>
                         <% } %>
-                        <% if (showTimeline && phase.stage !== 2) { %>
+                        <% if (showTimeline) { %>
+                            <% if (phase.stage === 2 && phase.auditors.length) { %>
+                                <div class="flow-stage-progress d-flex justify-content-between flex-wrap text-muted">
+                                    <span>同时整改</span><span>已完成 <%= inspection.rectificationDone %>/<%= inspection.rectificationTotal %></span>
+                                </div>
+                            <% } %>
                             <ul class="timeline-list list-unstyled flow-timeline">
                                 <% phase.nodes.forEach((node, index) => { %>
                                     <% const tone = node.status === 3 ? 'success' : [2, 5, 6, 12].includes(node.status) ? 'warning' : node.status === 4 ? 'danger' : 'secondary';
@@ -123,7 +105,7 @@
                                         <div class="timeline-item-content">
                                             <div class="d-flex justify-content-between py-1">
                                                 <span class="text-black-50"><%= node.label %></span>
-                                                <span class="text-<%= tone %>"><%= node.origin ? '上报审批' : node.status === 3 ? '审批通过' : flowStatusText[node.status] %></span>
+                                                <span class="text-<%= tone %>"><%= node.origin ? '上报审批' : phase.stage !== 2 && node.status === 3 ? '审批通过' : flowStatusText[node.status] %></span>
                                             </div>
                                             <div class="card">
                                                 <div class="card-body px-3 py-2">
@@ -132,9 +114,17 @@
                                                             <div class="d-flex align-items-start">
                                                                 <div class="flow-person-names"><span class="h6 mr-1"><%= audit.name %></span><small class="text-muted"><%= audit.company || '' %><%= audit.company && audit.role ? '-' : '' %><%= audit.role || '' %></small></div>
                                                                 <% const personTone = node.origin || audit.status === 3 ? 'success' : [2, 5, 6, 12].includes(audit.status) ? 'warning' : audit.status === 4 ? 'danger' : 'secondary'; %>
-                                                                <span class="ml-auto pl-2 text-<%= personTone %>"><% if (!node.origin && node.auditors.length > 1) { %><small class="mr-1"><%= flowStatusText[audit.status] %></small><% } %><i class="fa <%= node.origin || audit.status === 3 ? 'fa-check-circle' : [2, 12].includes(audit.status) ? 'fa-commenting' : [5, 6].includes(audit.status) ? 'fa-reply' : audit.status === 4 ? 'fa-stop-circle' : 'fa-circle-o' %>" aria-hidden="true"></i></span>
+                                                                <% if (phase.stage === 2 && editable) { %>
+                                                                    <button class="btn btn-link btn-sm text-danger flow-remove-user p-0 ml-auto" data-stage="<%= phase.stage %>" data-id="<%= audit.aid %>" type="button">移除</button>
+                                                                <% } else { %>
+                                                                    <span class="ml-auto pl-2 text-<%= personTone %>"><% if (!node.origin && node.auditors.length > 1) { %><small class="mr-1"><%= flowStatusText[audit.status] %></small><% } %><i class="fa <%= node.origin || audit.status === 3 ? 'fa-check-circle' : [2, 12].includes(audit.status) ? 'fa-commenting' : [5, 6].includes(audit.status) ? 'fa-reply' : audit.status === 4 ? 'fa-stop-circle' : 'fa-circle-o' %>" aria-hidden="true"></i></span>
+                                                                <% } %>
                                                             </div>
-                                                            <div class="bg-light flow-opinion mt-1" aria-label="处理意见"><i class="fa fa-commenting-o mr-1" aria-hidden="true"></i><%= audit.opinion || '' %></div>
+                                                            <% if (phase.stage === 2) { %>
+                                                                <% if (audit.rectification_item) { %><div class="flow-rectification-result mt-2"><%= audit.rectification_item %></div><% } %>
+                                                                <% if (audit.rectification_date) { %><small class="d-block text-muted mt-1">整改日期:<%= moment(audit.rectification_date).format('YYYY-MM-DD') %></small><% } %>
+                                                            <% } %>
+                                                            <% if (phase.stage !== 2 || audit.opinion) { %><div class="bg-light flow-opinion mt-1" aria-label="<%= phase.stage === 2 ? '说明' : '处理意见' %>"><i class="fa fa-commenting-o mr-1" aria-hidden="true"></i><%= audit.opinion || '' %></div><% } %>
                                                         </div>
                                                     <% }); %>
                                                 </div>
@@ -142,7 +132,7 @@
                                         </div>
                                     </li>
                                 <% }); %>
-                                <% if (!phase.nodes.length) { %><li class="text-muted py-2">尚未设置审批人</li><% } %>
+                                <% if (!phase.nodes.length) { %><li class="flow-timeline-empty text-muted py-2"><%= phase.stage === 2 ? '整改人由上报审批人指派,可设置多人同时处理。' : '尚未设置审批人' %></li><% } %>
                             </ul>
                         <% } else { %>
                         <div class="card">
@@ -196,8 +186,6 @@
                         </div>
                         <% } %>
                     <% if (showTimeline) { %>
-                            </div>
-                        </div>
                     </section>
                     <% } else { %>
                     </div>
@@ -205,10 +193,8 @@
                 <% } %>
             <% }); %>
             <div class="alert alert-warning flow-no-rectification<%= inspection.need_rectification ? ' d-none' : '' %>">本次巡检无整改/批复流程</div>
-    <% if (!showTimeline) { %>
         </div>
     </div>
-    <% } %>
     <% if (inspection.flowHistory.length) { %>
         <details class="card mb-3 d-none">
             <summary class="card-header">查看处理记录</summary>

+ 19 - 33
app/view/safe/inspection_flow.ejs

@@ -21,8 +21,7 @@
     <% } else { %>
         <div class="flow-title text-center mb-1">审批流程</div>
     <% } %>
-    <% if (!showTimeline) { %>
-    <div class="row flow-layout">
+    <div class="row flow-layout<%= showTimeline ? ' flow-progress-layout' : '' %>">
         <div class="col-md-4 flow-summary mb-3">
             <table class="table table-bordered table-sm flow-summary-table mb-0" aria-label="审批流程人员">
                 <colgroup><col class="flow-phase-label"><col></colgroup>
@@ -49,7 +48,6 @@
             </table>
         </div>
         <div class="col-md-8 flow-details">
-    <% } %>
             <% inspection.flowStages.forEach(phase => { %>
                 <% if (phase.stage === 1 || inspection.need_rectification || !inspection.readOnly) { %>
                     <% const reportMode = ctx.tender.info.shenpi.safe_inspection;
@@ -58,27 +56,6 @@
                     <% if (showTimeline) { %>
                     <section class="flow-phase-section" data-flow-stage="<%= phase.stage %>">
                         <div class="flow-phase-title text-center text-muted">巡检<%= phase.name %></div>
-                        <div class="row flow-layout">
-                            <div class="col-md-4 flow-summary mb-3">
-                                <div class="card">
-                                    <ul class="list-group list-group-flush">
-                                        <% phase.nodes.forEach(node => { %>
-                                            <li class="list-group-item d-flex align-items-center flow-phase-person">
-                                                <i class="fa <%= node.origin ? 'fa-play-circle fa-rotate-90' : node.label === '终审' ? 'fa-stop-circle' : 'fa-chevron-circle-down' %> mr-2" aria-hidden="true"></i>
-                                                <div class="flow-person-names">
-                                                    <% node.auditors.forEach(audit => { %><div><%= audit.name %></div><% }); %>
-                                                </div>
-                                                <div class="ml-auto pl-2 text-right">
-                                                    <span class="badge badge-light badge-pill"><%= node.label %></span>
-                                                    <% if (phase.stage === 2) { %><small class="d-block text-muted"><%= flowStatusText[node.status] %></small><% } %>
-                                                </div>
-                                            </li>
-                                        <% }); %>
-                                        <% if (!phase.nodes.length) { %><li class="list-group-item text-muted"><%= phase.stage === 2 ? '整改人由上报审批人指派' : '尚未设置审批人' %></li><% } %>
-                                    </ul>
-                                </div>
-                            </div>
-                            <div class="col-md-8 flow-details">
                     <% } else { %>
                     <div class="mb-3<%= phase.stage !== 1 && !inspection.need_rectification ? ' d-none' : '' %>" data-flow-stage="<%= phase.stage %>">
                     <% } %>
@@ -109,7 +86,12 @@
                                 </div>
                             </div>
                         <% } %>
-                        <% if (showTimeline && phase.stage !== 2) { %>
+                        <% if (showTimeline) { %>
+                            <% if (phase.stage === 2 && phase.auditors.length) { %>
+                                <div class="flow-stage-progress d-flex justify-content-between flex-wrap text-muted">
+                                    <span>同时整改</span><span>已完成 <%= inspection.rectificationDone %>/<%= inspection.rectificationTotal %></span>
+                                </div>
+                            <% } %>
                             <ul class="timeline-list list-unstyled flow-timeline">
                                 <% phase.nodes.forEach((node, index) => { %>
                                     <% const tone = node.status === 3 ? 'success' : [2, 5, 6, 12].includes(node.status) ? 'warning' : node.status === 4 ? 'danger' : 'secondary';
@@ -123,7 +105,7 @@
                                         <div class="timeline-item-content">
                                             <div class="d-flex justify-content-between py-1">
                                                 <span class="text-black-50"><%= node.label %></span>
-                                                <span class="text-<%= tone %>"><%= node.origin ? '上报审批' : node.status === 3 ? '审批通过' : flowStatusText[node.status] %></span>
+                                                <span class="text-<%= tone %>"><%= node.origin ? '上报审批' : phase.stage !== 2 && node.status === 3 ? '审批通过' : flowStatusText[node.status] %></span>
                                             </div>
                                             <div class="card">
                                                 <div class="card-body px-3 py-2">
@@ -132,9 +114,17 @@
                                                             <div class="d-flex align-items-start">
                                                                 <div class="flow-person-names"><span class="h6 mr-1"><%= audit.name %></span><small class="text-muted"><%= audit.company || '' %><%= audit.company && audit.role ? '-' : '' %><%= audit.role || '' %></small></div>
                                                                 <% const personTone = node.origin || audit.status === 3 ? 'success' : [2, 5, 6, 12].includes(audit.status) ? 'warning' : audit.status === 4 ? 'danger' : 'secondary'; %>
-                                                                <span class="ml-auto pl-2 text-<%= personTone %>"><% if (!node.origin && node.auditors.length > 1) { %><small class="mr-1"><%= flowStatusText[audit.status] %></small><% } %><i class="fa <%= node.origin || audit.status === 3 ? 'fa-check-circle' : [2, 12].includes(audit.status) ? 'fa-commenting' : [5, 6].includes(audit.status) ? 'fa-reply' : audit.status === 4 ? 'fa-stop-circle' : 'fa-circle-o' %>" aria-hidden="true"></i></span>
+                                                                <% if (phase.stage === 2 && editable) { %>
+                                                                    <button class="btn btn-link btn-sm text-danger flow-remove-user p-0 ml-auto" data-stage="<%= phase.stage %>" data-id="<%= audit.aid %>" type="button">移除</button>
+                                                                <% } else { %>
+                                                                    <span class="ml-auto pl-2 text-<%= personTone %>"><% if (!node.origin && node.auditors.length > 1) { %><small class="mr-1"><%= flowStatusText[audit.status] %></small><% } %><i class="fa <%= node.origin || audit.status === 3 ? 'fa-check-circle' : [2, 12].includes(audit.status) ? 'fa-commenting' : [5, 6].includes(audit.status) ? 'fa-reply' : audit.status === 4 ? 'fa-stop-circle' : 'fa-circle-o' %>" aria-hidden="true"></i></span>
+                                                                <% } %>
                                                             </div>
-                                                            <div class="bg-light flow-opinion mt-1" aria-label="处理意见"><i class="fa fa-commenting-o mr-1" aria-hidden="true"></i><%= audit.opinion || '' %></div>
+                                                            <% if (phase.stage === 2) { %>
+                                                                <% if (audit.rectification_item) { %><div class="flow-rectification-result mt-2"><%= audit.rectification_item %></div><% } %>
+                                                                <% if (audit.rectification_date) { %><small class="d-block text-muted mt-1">整改日期:<%= moment(audit.rectification_date).format('YYYY-MM-DD') %></small><% } %>
+                                                            <% } %>
+                                                            <% if (phase.stage !== 2 || audit.opinion) { %><div class="bg-light flow-opinion mt-1" aria-label="<%= phase.stage === 2 ? '说明' : '处理意见' %>"><i class="fa fa-commenting-o mr-1" aria-hidden="true"></i><%= audit.opinion || '' %></div><% } %>
                                                         </div>
                                                     <% }); %>
                                                 </div>
@@ -142,7 +132,7 @@
                                         </div>
                                     </li>
                                 <% }); %>
-                                <% if (!phase.nodes.length) { %><li class="text-muted py-2">尚未设置审批人</li><% } %>
+                                <% if (!phase.nodes.length) { %><li class="flow-timeline-empty text-muted py-2"><%= phase.stage === 2 ? '整改人由上报审批人指派,可设置多人同时处理。' : '尚未设置审批人' %></li><% } %>
                             </ul>
                         <% } else { %>
                         <div class="card">
@@ -196,8 +186,6 @@
                         </div>
                         <% } %>
                     <% if (showTimeline) { %>
-                            </div>
-                        </div>
                     </section>
                     <% } else { %>
                     </div>
@@ -205,10 +193,8 @@
                 <% } %>
             <% }); %>
             <div class="alert alert-warning flow-no-rectification<%= inspection.need_rectification ? ' d-none' : '' %>">本次巡检无整改/批复流程</div>
-    <% if (!showTimeline) { %>
         </div>
     </div>
-    <% } %>
     <% if (inspection.flowHistory.length) { %>
         <details class="card mb-3 d-none">
             <summary class="card-header">查看处理记录</summary>