Commit 9120066cfe0aed12a4ed7dfe25d6b4f1a3fac6c4

Authored by 王彪总
1 parent 5902ef3e

业务线 小程序不用写死,从后端接口获取

@@ -136,7 +136,7 @@ page { @@ -136,7 +136,7 @@ page {
136 top: var(--btn-top, 100px); 136 top: var(--btn-top, 100px);
137 right: 15px; 137 right: 15px;
138 //transform: translateX(-50%); 138 //transform: translateX(-50%);
139 - background-color: #3c9cff; 139 + background-color: #3b9dff;
140 color: #ffffff; 140 color: #ffffff;
141 border: none; 141 border: none;
142 border-radius: 4px; 142 border-radius: 4px;
common/config/env.js
@@ -2,12 +2,12 @@ @@ -2,12 +2,12 @@
2 const env = { 2 const env = {
3 // 开发环境 3 // 开发环境
4 development: { 4 development: {
5 - baseUrl: 'https://test.jichengshanshui.com.cn:28302', 5 + // baseUrl: 'https://test.jichengshanshui.com.cn:28302',
6 // https://test.jichengshanshui.com.cn:28302 6 // https://test.jichengshanshui.com.cn:28302
7 7
8 - // baseUrl: 'http://192.168.1.111:48081', 8 + baseUrl: 'http://192.168.1.163:48081',
9 9
10 - uploadUrl: 'https://test.jichengshanshui.com.cn:28302', 10 + uploadUrl: 'http://192.168.1.163:48081',
11 // baseApi:'admin-api', 11 // baseApi:'admin-api',
12 // appApi:'app-api' 12 // appApi:'app-api'
13 }, 13 },
common/utils/common.js
@@ -124,6 +124,17 @@ export const getActionButtonType = (code) => { @@ -124,6 +124,17 @@ export const getActionButtonType = (code) => {
124 } 124 }
125 125
126 /** 126 /**
  127 + * 操作按钮行每行按钮数:单个按钮占一半宽度(左对齐),多个按钮等分,最多 5 个一行
  128 + * @param {number} count - 按钮总数
  129 + * @returns {number} 栅格列数
  130 + */
  131 +export const getActionRowCols = (count) => {
  132 + const total = Number(count) || 0
  133 + // 1 个按钮时用 2 列,按钮占 1 列即页面一半
  134 + return total <= 1 ? 2 : Math.min(total, 5)
  135 +}
  136 +
  137 +/**
127 * 计算两个时间的时间差,返回格式化字符串(天/小时/分钟/秒,按需显示,无无效单位) 138 * 计算两个时间的时间差,返回格式化字符串(天/小时/分钟/秒,按需显示,无无效单位)
128 * @param {string | Date | number} startTime - 开始时间(时间字符串/Date对象/10位/13位时间戳) 139 * @param {string | Date | number} startTime - 开始时间(时间字符串/Date对象/10位/13位时间戳)
129 * @param {string | Date | number} endTime - 结束时间(时间字符串/Date对象/10位/13位时间戳) 140 * @param {string | Date | number} endTime - 结束时间(时间字符串/Date对象/10位/13位时间戳)
pages-sub/daily/maintain-manage/index.vue
@@ -82,7 +82,7 @@ @@ -82,7 +82,7 @@
82 <!-- </view>--> 82 <!-- </view>-->
83 83
84 <view class="common-custom-btn" style="--btn-top: 48px;" @click="goToDetail(item)"> 84 <view class="common-custom-btn" style="--btn-top: 48px;" @click="goToDetail(item)">
85 - 养护任务 85 + 执行任务
86 </view> 86 </view>
87 <!-- <view class="u-body-item u-flex">--> 87 <!-- <view class="u-body-item u-flex">-->
88 <!-- <view class="u-body-item-title">批次号:</view>--> 88 <!-- <view class="u-body-item-title">批次号:</view>-->
pages-sub/daily/maintain-manage/now-list-page.vue
@@ -145,9 +145,18 @@ const handleAddReport = () =&gt; { @@ -145,9 +145,18 @@ const handleAddReport = () =&gt; {
145 align-items: center; 145 align-items: center;
146 margin-bottom: 0; 146 margin-bottom: 0;
147 } 147 }
  148 + // 查看按钮:与其他操作按钮统一蓝色样式
148 .look-btn { 149 .look-btn {
149 - font-size: 28rpx;  
150 - color: #1989fa; 150 + box-sizing: border-box;
  151 + width: 132rpx;
  152 + height: 48rpx;
  153 + line-height: 48rpx;
  154 + font-size: 24rpx;
  155 + text-align: center;
  156 + color: #fff;
  157 + background-color: #3b9dff;
  158 + border-radius: 6rpx;
  159 + flex-shrink: 0;
151 } 160 }
152 } 161 }
153 .empty-wrap { 162 .empty-wrap {
pages-sub/daily/maintain-manage/type-list-page.vue
@@ -348,13 +348,18 @@ onUnload(() =&gt; { @@ -348,13 +348,18 @@ onUnload(() =&gt; {
348 color: #666; 348 color: #666;
349 flex: 1; 349 flex: 1;
350 } 350 }
  351 +// 统一样式:去作业/去查看/结束任务 统一蓝色,固定宽高保证上下对齐时大小一致
351 .mini-btn { 352 .mini-btn {
  353 + box-sizing: border-box;
  354 + width: 132rpx;
  355 + height: 48rpx;
  356 + line-height: 48rpx;
352 font-size: 24rpx; 357 font-size: 24rpx;
353 - color: #333;  
354 - background: #f5f5f5;  
355 - border: 1rpx solid #ddd; 358 + text-align: center;
  359 + color: #fff;
  360 + background: #3b9dff;
356 border-radius: 6rpx; 361 border-radius: 6rpx;
357 - padding: 8rpx 20rpx; 362 + padding: 0;
358 flex-shrink: 0; 363 flex-shrink: 0;
359 } 364 }
360 .invalid-modal-content { 365 .invalid-modal-content {
pages-sub/problem/ai-manage/index.vue
@@ -95,7 +95,8 @@ @@ -95,7 +95,8 @@
95 <view class="u-line-1 u-body-value">{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view> 95 <view class="u-line-1 u-body-value">{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
96 </view> 96 </view>
97 <!-- 操作按钮行:已配置工作流动作时按配置逐个渲染按钮,点击直接执行对应动作 --> 97 <!-- 操作按钮行:已配置工作流动作时按配置逐个渲染按钮,点击直接执行对应动作 -->
98 - <view class="u-body-item task-btn-row mt-20"> 98 + <view class="u-body-item task-btn-row mt-20"
  99 + :style="{'--cols': getActionRowCols(actionBtnCount(item))}">
99 <template v-if="hasConfiguredActions(item)"> 100 <template v-if="hasConfiguredActions(item)">
100 <view 101 <view
101 v-for="action in item.configuredActions" 102 v-for="action in item.configuredActions"
@@ -103,7 +104,7 @@ @@ -103,7 +104,7 @@
103 :class="['task-btn', 'task-btn--' + getActionButtonType(action.code)]" 104 :class="['task-btn', 'task-btn--' + getActionButtonType(action.code)]"
104 @click.stop="handleUnifiedProcess(item, action)" 105 @click.stop="handleUnifiedProcess(item, action)"
105 >{{ action.name }}</view> 106 >{{ action.name }}</view>
106 - <view class="task-btn task-btn--info" @click.stop="handleDetail(item)">详情</view> 107 + <view class="task-btn task-btn--primary" @click.stop="handleDetail(item)">详情</view>
107 </template> 108 </template>
108 <!-- 未配置:沿用原有节点按钮 --> 109 <!-- 未配置:沿用原有节点按钮 -->
109 <template v-else> 110 <template v-else>
@@ -111,7 +112,7 @@ @@ -111,7 +112,7 @@
111 @click.stop="handleUnifiedReject(item)">回退</view> 112 @click.stop="handleUnifiedReject(item)">回退</view>
112 <view class="task-btn task-btn--primary" 113 <view class="task-btn task-btn--primary"
113 @click.stop="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</view> 114 @click.stop="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</view>
114 - <view class="task-btn task-btn--info" @click.stop="handleDetail(item)">详情</view> 115 + <view class="task-btn task-btn--primary" @click.stop="handleDetail(item)">详情</view>
115 </template> 116 </template>
116 </view> 117 </view>
117 </view> 118 </view>
@@ -276,7 +277,7 @@ import { @@ -276,7 +277,7 @@ import {
276 } from '@/api/regional-order-manage/regional-order-manage' 277 } from '@/api/regional-order-manage/regional-order-manage'
277 import { getTaskActions } from '@/api/work-order-manage/work-order-manage' 278 import { getTaskActions } from '@/api/work-order-manage/work-order-manage'
278 import { useUserStore } from '@/pinia/user'; 279 import { useUserStore } from '@/pinia/user';
279 -import { nextStepMap, buzStatusMap, getActionButtonType, toWorkerImplementPage } from '@/common/utils/common' 280 +import { nextStepMap, buzStatusMap, getActionButtonType, getActionRowCols, toWorkerImplementPage } from '@/common/utils/common'
280 import { useUploadImgs } from '@/common/utils/useUploadImgs' 281 import { useUploadImgs } from '@/common/utils/useUploadImgs'
281 282
282 // ========== 全局实例 & 常量 ========== 283 // ========== 全局实例 & 常量 ==========
@@ -510,6 +511,16 @@ const getProcessButtonText = (item) =&gt; { @@ -510,6 +511,16 @@ const getProcessButtonText = (item) =&gt; {
510 const hasConfiguredActions = (item) => 511 const hasConfiguredActions = (item) =>
511 Array.isArray(item?.configuredActions) && item.configuredActions.length > 0 512 Array.isArray(item?.configuredActions) && item.configuredActions.length > 0
512 513
  514 +/** 操作按钮行按钮数量:单个占一半宽度,多个等分,最多 5 个一行 */
  515 +const actionBtnCount = (item) => {
  516 + if (hasConfiguredActions(item)) {
  517 + return item.configuredActions.length + 1 // 配置动作 + 详情
  518 + }
  519 + let count = 2 // 主按钮 + 详情
  520 + if (showRejectButton(item)) count++
  521 + return count
  522 +}
  523 +
513 /** 待办-处理工单:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */ 524 /** 待办-处理工单:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */
514 const handleUnifiedProcess = async (item, action = null) => { 525 const handleUnifiedProcess = async (item, action = null) => {
515 const actions = Array.isArray(item?.configuredActions) 526 const actions = Array.isArray(item?.configuredActions)
@@ -749,11 +760,12 @@ onShow(() =&gt; { @@ -749,11 +760,12 @@ onShow(() =&gt; {
749 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); 760 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
750 } 761 }
751 762
752 -// 卡片操作按钮:自动换行、右对齐,动作多时每行 3~4 个,不再整行铺满 763 +// 卡片操作按钮:单个占一半宽度,多个等分,每行最多 5 个
753 .task-btn-row { 764 .task-btn-row {
754 - display: flex;  
755 - flex-wrap: wrap;  
756 - justify-content: flex-end; 765 + display: grid;
  766 + grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr));
  767 + column-gap: 12rpx;
  768 + row-gap: 10rpx;
757 margin-bottom: -10rpx; 769 margin-bottom: -10rpx;
758 } 770 }
759 771
@@ -761,20 +773,23 @@ onShow(() =&gt; { @@ -761,20 +773,23 @@ onShow(() =&gt; {
761 box-sizing: border-box; 773 box-sizing: border-box;
762 height: 56rpx; 774 height: 56rpx;
763 line-height: 56rpx; 775 line-height: 56rpx;
764 - padding: 0 24rpx;  
765 - margin: 0 0 10rpx 12rpx; 776 + padding: 0 12rpx;
766 border-radius: 8rpx; 777 border-radius: 8rpx;
767 font-size: 24rpx; 778 font-size: 24rpx;
768 color: #fff; 779 color: #fff;
  780 + text-align: center;
769 white-space: nowrap; 781 white-space: nowrap;
  782 + overflow: hidden;
  783 + text-overflow: ellipsis;
770 } 784 }
771 785
  786 +/* 按动作编码配色:通过/实施/结束类动作绿色,退回类橙色 */
772 .task-btn--primary { 787 .task-btn--primary {
773 - background-color: #3c9cff; 788 + background-color: #3b9dff;
774 } 789 }
775 790
776 .task-btn--success { 791 .task-btn--success {
777 - background-color: #5ac725; 792 + background-color: #078d0a;
778 } 793 }
779 794
780 .task-btn--warning { 795 .task-btn--warning {
@@ -789,7 +804,6 @@ onShow(() =&gt; { @@ -789,7 +804,6 @@ onShow(() =&gt; {
789 background-color: #909399; 804 background-color: #909399;
790 } 805 }
791 806
792 -  
793 // 弹窗公共样式 807 // 弹窗公共样式
794 .reject-modal-content, .accept-modal-content { 808 .reject-modal-content, .accept-modal-content {
795 width: 100%; 809 width: 100%;
pages-sub/problem/regional-order-manage/index.vue
@@ -107,7 +107,8 @@ @@ -107,7 +107,8 @@
107 </view> 107 </view>
108 108
109 <!-- 待办工单(0):已配置工作流动作时按配置逐个渲染按钮,点击直接执行对应动作 --> 109 <!-- 待办工单(0):已配置工作流动作时按配置逐个渲染按钮,点击直接执行对应动作 -->
110 - <view v-if="activeTab === 0" class="u-body-item task-btn-row mt-20"> 110 + <view v-if="activeTab === 0" class="u-body-item task-btn-row mt-20"
  111 + :style="{'--cols': getActionRowCols(actionBtnCount(item))}">
111 <template v-if="hasConfiguredActions(item)"> 112 <template v-if="hasConfiguredActions(item)">
112 <view 113 <view
113 v-for="action in item.configuredActions" 114 v-for="action in item.configuredActions"
@@ -115,7 +116,7 @@ @@ -115,7 +116,7 @@
115 :class="['task-btn', 'task-btn--' + getActionButtonType(action.code)]" 116 :class="['task-btn', 'task-btn--' + getActionButtonType(action.code)]"
116 @click.stop="handleUnifiedProcess(item, action)" 117 @click.stop="handleUnifiedProcess(item, action)"
117 >{{ action.name }}</view> 118 >{{ action.name }}</view>
118 - <view class="task-btn task-btn--info" @click.stop="handleDetail(item)">详情</view> 119 + <view class="task-btn task-btn--primary" @click.stop="handleDetail(item)">详情</view>
119 </template> 120 </template>
120 <!-- 未配置:沿用原有节点按钮 --> 121 <!-- 未配置:沿用原有节点按钮 -->
121 <template v-else> 122 <template v-else>
@@ -125,7 +126,7 @@ @@ -125,7 +126,7 @@
125 @click.stop="handleRenew(item)">重新提交</view> 126 @click.stop="handleRenew(item)">重新提交</view>
126 <view class="task-btn task-btn--primary" 127 <view class="task-btn task-btn--primary"
127 @click.stop="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</view> 128 @click.stop="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</view>
128 - <view class="task-btn task-btn--info" @click.stop="handleDetail(item)">详情</view> 129 + <view class="task-btn task-btn--primary" @click.stop="handleDetail(item)">详情</view>
129 </template> 130 </template>
130 </view> 131 </view>
131 132
@@ -241,7 +242,7 @@ import { @@ -241,7 +242,7 @@ import {
241 } from '@/api/regional-order-manage/regional-order-manage' 242 } from '@/api/regional-order-manage/regional-order-manage'
242 import { getTaskActions } from '@/api/work-order-manage/work-order-manage' 243 import { getTaskActions } from '@/api/work-order-manage/work-order-manage'
243 import { useUserStore } from '@/pinia/user'; 244 import { useUserStore } from '@/pinia/user';
244 -import { nextStepMap, buzStatusMap, getActionButtonType, toWorkerImplementPage } from '@/common/utils/common' 245 +import { nextStepMap, buzStatusMap, getActionButtonType, getActionRowCols, toWorkerImplementPage } from '@/common/utils/common'
245 import { useUploadImgs } from '@/common/utils/useUploadImgs' 246 import { useUploadImgs } from '@/common/utils/useUploadImgs'
246 247
247 // ========== 全局实例 & 常量 ========== 248 // ========== 全局实例 & 常量 ==========
@@ -491,6 +492,17 @@ const getProcessButtonText = (item) =&gt; { @@ -491,6 +492,17 @@ const getProcessButtonText = (item) =&gt; {
491 const hasConfiguredActions = (item) => 492 const hasConfiguredActions = (item) =>
492 Array.isArray(item?.configuredActions) && item.configuredActions.length > 0 493 Array.isArray(item?.configuredActions) && item.configuredActions.length > 0
493 494
  495 +/** 操作按钮行按钮数量:单个占一半宽度,多个等分,最多 5 个一行 */
  496 +const actionBtnCount = (item) => {
  497 + if (hasConfiguredActions(item)) {
  498 + return item.configuredActions.length + 1 // 配置动作 + 详情
  499 + }
  500 + let count = 2 // 主按钮 + 详情
  501 + if (showRejectButton(item)) count++
  502 + if (nextStepMap[item.taskKey]?.renewShow) count++
  503 + return count
  504 +}
  505 +
494 /** 待办-处理工单:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */ 506 /** 待办-处理工单:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */
495 const handleUnifiedProcess = async (item, action = null) => { 507 const handleUnifiedProcess = async (item, action = null) => {
496 const actions = Array.isArray(item?.configuredActions) 508 const actions = Array.isArray(item?.configuredActions)
@@ -576,7 +588,6 @@ const handleProcess = async (item) =&gt; { @@ -576,7 +588,6 @@ const handleProcess = async (item) =&gt; {
576 }); 588 });
577 } 589 }
578 590
579 -  
580 // 验收弹窗 591 // 验收弹窗
581 else if (['巡查员验收', '养护组长验收'].includes(stepName)) { 592 else if (['巡查员验收', '养护组长验收'].includes(stepName)) {
582 currentAcceptItem.value = item; 593 currentAcceptItem.value = item;
@@ -745,11 +756,12 @@ onLoad(() =&gt; { @@ -745,11 +756,12 @@ onLoad(() =&gt; {
745 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); 756 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
746 } 757 }
747 758
748 -// 卡片操作按钮:自动换行、右对齐,动作多时每行 3~4 个,不再整行铺满 759 +// 卡片操作按钮:单个占页面一半宽度(左对齐),多个等分,每行最多 5 个,超出自动换行
749 .task-btn-row { 760 .task-btn-row {
750 - display: flex;  
751 - flex-wrap: wrap;  
752 - justify-content: flex-end; 761 + display: grid;
  762 + grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr));
  763 + column-gap: 12rpx;
  764 + row-gap: 10rpx;
753 margin-bottom: -10rpx; 765 margin-bottom: -10rpx;
754 } 766 }
755 767
@@ -757,20 +769,23 @@ onLoad(() =&gt; { @@ -757,20 +769,23 @@ onLoad(() =&gt; {
757 box-sizing: border-box; 769 box-sizing: border-box;
758 height: 56rpx; 770 height: 56rpx;
759 line-height: 56rpx; 771 line-height: 56rpx;
760 - padding: 0 24rpx;  
761 - margin: 0 0 10rpx 12rpx; 772 + padding: 0 12rpx;
762 border-radius: 8rpx; 773 border-radius: 8rpx;
763 font-size: 24rpx; 774 font-size: 24rpx;
764 color: #fff; 775 color: #fff;
  776 + text-align: center;
765 white-space: nowrap; 777 white-space: nowrap;
  778 + overflow: hidden;
  779 + text-overflow: ellipsis;
766 } 780 }
767 781
  782 +/* 按动作编码配色:通过/实施/结束类动作绿色,退回类橙色 */
768 .task-btn--primary { 783 .task-btn--primary {
769 - background-color: #3c9cff; 784 + background-color: #3b9dff;
770 } 785 }
771 786
772 .task-btn--success { 787 .task-btn--success {
773 - background-color: #5ac725; 788 + background-color: #078d0a;
774 } 789 }
775 790
776 .task-btn--warning { 791 .task-btn--warning {
@@ -785,7 +800,6 @@ onLoad(() =&gt; { @@ -785,7 +800,6 @@ onLoad(() =&gt; {
785 background-color: #909399; 800 background-color: #909399;
786 } 801 }
787 802
788 -  
789 // 新增样式:解决按钮和文字间距、排版问题 803 // 新增样式:解决按钮和文字间距、排版问题
790 .flex-1 { flex: 1; } 804 .flex-1 { flex: 1; }
791 .text-right { text-align: right; } 805 .text-right { text-align: right; }
pages-sub/problem/regional-order-manage/list-detail.vue
@@ -178,7 +178,7 @@ @@ -178,7 +178,7 @@
178 <template #content> 178 <template #content>
179 <view class="step-content-wrap"> 179 <view class="step-content-wrap">
180 <view class="step-title"> 180 <view class="step-title">
181 - {{ item.name ? item.name.replace('大区经理', '业务调度员') : item.name }} 181 + {{ item.name }}
182 </view> 182 </view>
183 <view class="step-desc"> 183 <view class="step-desc">
184 <view class="operator-name up-line-1" v-if="item.tasks"> 184 <view class="operator-name up-line-1" v-if="item.tasks">
@@ -225,8 +225,9 @@ @@ -225,8 +225,9 @@
225 <!-- 底部操作按钮 --> 225 <!-- 底部操作按钮 -->
226 <view v-if="activeTab === '0' && (configuredActions || nextStepMap[orderDetail.taskKey])" 226 <view v-if="activeTab === '0' && (configuredActions || nextStepMap[orderDetail.taskKey])"
227 class="fixed-bottom-btn-wrap order-action-bar"> 227 class="fixed-bottom-btn-wrap order-action-bar">
228 - <!-- 已配置工作流动作:每行最多 3 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->  
229 - <view v-if="hasConfiguredActions" class="order-action-row"> 228 + <!-- 已配置工作流动作:每行最多 5 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->
  229 + <view v-if="hasConfiguredActions" class="order-action-row"
  230 + :style="{'--cols': getActionRowCols(configuredActions.length)}">
230 <view 231 <view
231 v-for="action in configuredActions" 232 v-for="action in configuredActions"
232 :key="action.code" 233 :key="action.code"
@@ -234,8 +235,8 @@ @@ -234,8 +235,8 @@
234 @click.stop="handleUnifiedProcess(orderDetail, action)" 235 @click.stop="handleUnifiedProcess(orderDetail, action)"
235 >{{ action.name }}</view> 236 >{{ action.name }}</view>
236 </view> 237 </view>
237 - <!-- 未配置:沿用原有节点按钮(整行展示) -->  
238 - <view v-else class="order-action-row order-action-row--single"> 238 + <!-- 未配置:沿用原有节点按钮 -->
  239 + <view v-else class="order-action-row" :style="{'--cols': getActionRowCols(legacyActionCount)}">
239 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning" 240 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning"
240 @click.stop="handleUnifiedReject(orderDetail)">回退</view> 241 @click.stop="handleUnifiedReject(orderDetail)">回退</view>
241 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success" 242 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success"
@@ -337,7 +338,7 @@ import { timeFormat } from &#39;@/uni_modules/uview-plus&#39; @@ -337,7 +338,7 @@ import { timeFormat } from &#39;@/uni_modules/uview-plus&#39;
337 import { getApprovalDetail,workOrderDetailByID } from '@/api/regional-order-manage/regional-order-manage' 338 import { getApprovalDetail,workOrderDetailByID } from '@/api/regional-order-manage/regional-order-manage'
338 import { getTaskActions } from '@/api/work-order-manage/work-order-manage' 339 import { getTaskActions } from '@/api/work-order-manage/work-order-manage'
339 340
340 -import { nextStepMap, calculateFormatTimeDiff, getActionButtonType, toWorkerImplementPage } from '@/common/utils/common' 341 +import { nextStepMap, calculateFormatTimeDiff, getActionButtonType, getActionRowCols, toWorkerImplementPage } from '@/common/utils/common'
341 import { useUploadImgs } from '@/common/utils/useUploadImgs' 342 import { useUploadImgs } from '@/common/utils/useUploadImgs'
342 import { useUserStore } from '@/pinia/user' 343 import { useUserStore } from '@/pinia/user'
343 344
@@ -523,15 +524,20 @@ const showRejectButton = computed(() =&gt; { @@ -523,15 +524,20 @@ const showRejectButton = computed(() =&gt; {
523 const hasConfiguredActions = computed(() => 524 const hasConfiguredActions = computed(() =>
524 Array.isArray(configuredActions.value) && configuredActions.value.length > 0) 525 Array.isArray(configuredActions.value) && configuredActions.value.length > 0)
525 526
  527 +/** 未配置统一动作时的按钮个数(与模板渲染顺序一致) */
  528 +const legacyActionCount = computed(() => {
  529 + let count = 1
  530 + if (showRejectButton.value) count++
  531 + if (nextStepMap[orderDetail.value.taskKey]?.renewShow) count++
  532 + return count
  533 +})
  534 +
526 /** 底部操作栏行数:详情内容据此预留底部间距,避免按钮遮挡内容 */ 535 /** 底部操作栏行数:详情内容据此预留底部间距,避免按钮遮挡内容 */
527 const actionBarRows = computed(() => { 536 const actionBarRows = computed(() => {
528 if (hasConfiguredActions.value) { 537 if (hasConfiguredActions.value) {
529 - return Math.ceil(configuredActions.value.length / 3) 538 + return Math.ceil(configuredActions.value.length / 5)
530 } 539 }
531 - let rows = 1  
532 - if (showRejectButton.value) rows++  
533 - if (nextStepMap[orderDetail.value.taskKey]?.renewShow) rows++  
534 - return rows 540 + return 1
535 }) 541 })
536 542
537 /** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */ 543 /** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
@@ -1025,8 +1031,7 @@ onLoad((options: any) =&gt; { @@ -1025,8 +1031,7 @@ onLoad((options: any) =&gt; {
1025 height: 70px !important; 1031 height: 70px !important;
1026 } 1032 }
1027 1033
1028 -// 底部动作按钮:动作多时自动换行  
1029 -// 底部操作栏:白底 + 顶部投影,按钮每行最多 3 个,避免多动作时整屏遮挡工单详情 1034 +// 底部操作栏:白底 + 顶部投影,按钮每行最多 5 个,避免多动作时整屏遮挡工单详情
1030 .order-action-bar { 1035 .order-action-bar {
1031 background-color: #fff; 1036 background-color: #fff;
1032 box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06); 1037 box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
@@ -1035,18 +1040,17 @@ onLoad((options: any) =&gt; { @@ -1035,18 +1040,17 @@ onLoad((options: any) =&gt; {
1035 padding-bottom: calc(10rpx + env(safe-area-inset-bottom)); 1040 padding-bottom: calc(10rpx + env(safe-area-inset-bottom));
1036 } 1041 }
1037 1042
  1043 +// 底部操作按钮:单按钮占一半宽度,多个按钮等分,每行最多 5 个
1038 .order-action-row { 1044 .order-action-row {
1039 - display: flex;  
1040 - flex-wrap: wrap;  
1041 - margin: -6rpx; 1045 + display: grid;
  1046 + grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr));
  1047 + gap: 12rpx;
1042 } 1048 }
1043 1049
1044 .order-action-btn { 1050 .order-action-btn {
1045 box-sizing: border-box; 1051 box-sizing: border-box;
1046 - width: calc((100% - 36rpx) / 3);  
1047 height: 68rpx; 1052 height: 68rpx;
1048 line-height: 68rpx; 1053 line-height: 68rpx;
1049 - margin: 6rpx;  
1050 padding: 0 8rpx; 1054 padding: 0 8rpx;
1051 border-radius: 8rpx; 1055 border-radius: 8rpx;
1052 font-size: 26rpx; 1056 font-size: 26rpx;
@@ -1057,17 +1061,13 @@ onLoad((options: any) =&gt; { @@ -1057,17 +1061,13 @@ onLoad((options: any) =&gt; {
1057 text-overflow: ellipsis; 1061 text-overflow: ellipsis;
1058 } 1062 }
1059 1063
1060 -// 未配置统一动作时按钮整行展示,保持原有观感  
1061 -.order-action-row--single .order-action-btn {  
1062 - width: 100%;  
1063 -}  
1064 - 1064 +/* 按动作编码配色:通过/实施/结束类动作绿色,退回类橙色 */
1065 .order-action-btn--primary { 1065 .order-action-btn--primary {
1066 - background-color: #3c9cff; 1066 + background-color: #3b9dff;
1067 } 1067 }
1068 1068
1069 .order-action-btn--success { 1069 .order-action-btn--success {
1070 - background-color: #5ac725; 1070 + background-color: #078d0a;
1071 } 1071 }
1072 1072
1073 .order-action-btn--warning { 1073 .order-action-btn--warning {
pages-sub/problem/regional-order-manage/order-detail.vue
@@ -198,7 +198,7 @@ @@ -198,7 +198,7 @@
198 <view class="step-content-wrap"> 198 <view class="step-content-wrap">
199 <!-- 1. 原标题内容:节点名称 + 操作人 --> 199 <!-- 1. 原标题内容:节点名称 + 操作人 -->
200 <view class="step-title"> 200 <view class="step-title">
201 - {{ item.name ? item.name.replace('大区经理', '业务调度员') : item.name }} 201 + {{ item.name }}
202 </view> 202 </view>
203 203
204 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) --> 204 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) -->
@@ -255,8 +255,9 @@ @@ -255,8 +255,9 @@
255 <!-- activeTab==0的时候才出现, 也就是待办 --> 255 <!-- activeTab==0的时候才出现, 也就是待办 -->
256 <view v-if="activeTab==0&&(configuredActions||nextStepMap[orderDetail.taskKey])" 256 <view v-if="activeTab==0&&(configuredActions||nextStepMap[orderDetail.taskKey])"
257 class="fixed-bottom-btn-wrap order-action-bar"> 257 class="fixed-bottom-btn-wrap order-action-bar">
258 - <!-- 已配置工作流动作:每行最多 3 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->  
259 - <view v-if="hasConfiguredActions" class="order-action-row"> 258 + <!-- 已配置工作流动作:每行最多 5 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->
  259 + <view v-if="hasConfiguredActions" class="order-action-row"
  260 + :style="{'--cols': getActionRowCols(configuredActions.length)}">
260 <view 261 <view
261 v-for="action in configuredActions" 262 v-for="action in configuredActions"
262 :key="action.code" 263 :key="action.code"
@@ -264,8 +265,8 @@ @@ -264,8 +265,8 @@
264 @click.stop="handleUnifiedProcess(orderDetail, action)" 265 @click.stop="handleUnifiedProcess(orderDetail, action)"
265 >{{ action.name }}</view> 266 >{{ action.name }}</view>
266 </view> 267 </view>
267 - <!-- 未配置:沿用原有节点按钮(整行展示) -->  
268 - <view v-else class="order-action-row order-action-row--single"> 268 + <!-- 未配置:沿用原有节点按钮 -->
  269 + <view v-else class="order-action-row" :style="{'--cols': getActionRowCols(legacyActionCount)}">
269 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning" 270 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning"
270 @click.stop="handleUnifiedReject(orderDetail)">回退</view> 271 @click.stop="handleUnifiedReject(orderDetail)">回退</view>
271 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success" 272 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success"
@@ -381,7 +382,7 @@ import { @@ -381,7 +382,7 @@ import {
381 dcyUniversalApproval, 382 dcyUniversalApproval,
382 aiUniversalApproval 383 aiUniversalApproval
383 } from '@/api/regional-order-manage/regional-order-manage'; 384 } from '@/api/regional-order-manage/regional-order-manage';
384 -import {nextStepMap, buzStatusMap, calculateFormatTimeDiff, getActionButtonType, toWorkerImplementPage} from '@/common/utils/common' 385 +import {nextStepMap, buzStatusMap, calculateFormatTimeDiff, getActionButtonType, getActionRowCols, toWorkerImplementPage} from '@/common/utils/common'
385 import {getTaskActions} from '@/api/work-order-manage/work-order-manage'; 386 import {getTaskActions} from '@/api/work-order-manage/work-order-manage';
386 import {useUploadImgs} from '@/common/utils/useUploadImgs' 387 import {useUploadImgs} from '@/common/utils/useUploadImgs'
387 import { useUserStore } from '@/pinia/user'; 388 import { useUserStore } from '@/pinia/user';
@@ -392,7 +393,6 @@ const USER_ROLES = userStore.userInfo?.roles || []; @@ -392,7 +393,6 @@ const USER_ROLES = userStore.userInfo?.roles || [];
392 // ========== 页面通信事件通道 解决未定义BUG ========== 393 // ========== 页面通信事件通道 解决未定义BUG ==========
393 const eventChannel = ref<any>(null); 394 const eventChannel = ref<any>(null);
394 395
395 -  
396 // ========== 公共封装方法 (和列表页完全一致) ========== 396 // ========== 公共封装方法 (和列表页完全一致) ==========
397 /** 397 /**
398 * 统一提示方法 398 * 统一提示方法
@@ -593,15 +593,20 @@ const showRejectButton = computed(() =&gt; { @@ -593,15 +593,20 @@ const showRejectButton = computed(() =&gt; {
593 const hasConfiguredActions = computed(() => 593 const hasConfiguredActions = computed(() =>
594 Array.isArray(configuredActions.value) && configuredActions.value.length > 0) 594 Array.isArray(configuredActions.value) && configuredActions.value.length > 0)
595 595
596 -/** 底部操作栏行数:详情内容据此预留底部间距,避免按钮遮挡内容 */ 596 +/** 未配置统一动作时的按钮数量:主按钮 + 可选的回退/重新提交 */
  597 +const legacyActionCount = computed(() => {
  598 + let count = 1
  599 + if (showRejectButton.value) count++
  600 + if (nextStepMap[orderDetail.value.taskKey]?.renewShow) count++
  601 + return count
  602 +})
  603 +
  604 +/** 底部操作栏行数:详情内容据此预留底部间距,避免按钮遮挡内容(每行最多 5 个) */
597 const actionBarRows = computed(() => { 605 const actionBarRows = computed(() => {
598 if (hasConfiguredActions.value) { 606 if (hasConfiguredActions.value) {
599 - return Math.ceil(configuredActions.value.length / 3) 607 + return Math.ceil(configuredActions.value.length / 5)
600 } 608 }
601 - let rows = 1  
602 - if (showRejectButton.value) rows++  
603 - if (nextStepMap[orderDetail.value.taskKey]?.renewShow) rows++  
604 - return rows 609 + return 1
605 }) 610 })
606 611
607 /** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */ 612 /** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
@@ -1173,7 +1178,7 @@ onShow(() =&gt; {}); @@ -1173,7 +1178,7 @@ onShow(() =&gt; {});
1173 } 1178 }
1174 1179
1175 // 底部动作按钮:动作多时自动换行 1180 // 底部动作按钮:动作多时自动换行
1176 -// 底部操作栏:白底 + 顶部投影,按钮每行最多 3 个,避免多动作时整屏遮挡工单详情 1181 +// 底部操作栏:白底 + 顶部投影,按钮每行最多 5 个,避免多动作时整屏遮挡工单详情
1177 .order-action-bar { 1182 .order-action-bar {
1178 background-color: #fff; 1183 background-color: #fff;
1179 box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06); 1184 box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
@@ -1183,17 +1188,16 @@ onShow(() =&gt; {}); @@ -1183,17 +1188,16 @@ onShow(() =&gt; {});
1183 } 1188 }
1184 1189
1185 .order-action-row { 1190 .order-action-row {
1186 - display: flex;  
1187 - flex-wrap: wrap;  
1188 - margin: -6rpx; 1191 + display: grid;
  1192 + grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr));
  1193 + column-gap: 12rpx;
  1194 + row-gap: 12rpx;
1189 } 1195 }
1190 1196
1191 .order-action-btn { 1197 .order-action-btn {
1192 box-sizing: border-box; 1198 box-sizing: border-box;
1193 - width: calc((100% - 36rpx) / 3);  
1194 height: 68rpx; 1199 height: 68rpx;
1195 line-height: 68rpx; 1200 line-height: 68rpx;
1196 - margin: 6rpx;  
1197 padding: 0 8rpx; 1201 padding: 0 8rpx;
1198 border-radius: 8rpx; 1202 border-radius: 8rpx;
1199 font-size: 26rpx; 1203 font-size: 26rpx;
@@ -1204,17 +1208,13 @@ onShow(() =&gt; {}); @@ -1204,17 +1208,13 @@ onShow(() =&gt; {});
1204 text-overflow: ellipsis; 1208 text-overflow: ellipsis;
1205 } 1209 }
1206 1210
1207 -// 未配置统一动作时按钮整行展示,保持原有观感  
1208 -.order-action-row--single .order-action-btn {  
1209 - width: 100%;  
1210 -}  
1211 - 1211 +/* 按动作编码配色:通过/实施/结束类动作绿色,退回类橙色 */
1212 .order-action-btn--primary { 1212 .order-action-btn--primary {
1213 - background-color: #3c9cff; 1213 + background-color: #3b9dff;
1214 } 1214 }
1215 1215
1216 .order-action-btn--success { 1216 .order-action-btn--success {
1217 - background-color: #5ac725; 1217 + background-color: #078d0a;
1218 } 1218 }
1219 1219
1220 .order-action-btn--warning { 1220 .order-action-btn--warning {
pages-sub/problem/work-order-manage/index.vue
@@ -101,7 +101,8 @@ @@ -101,7 +101,8 @@
101 <view class="u-line-1 u-body-value">{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view> 101 <view class="u-line-1 u-body-value">{{ timeFormat(item.createTime, 'yyyy-mm-dd hh:MM:ss') }}</view>
102 </view> 102 </view>
103 <!-- 操作按钮行 --> 103 <!-- 操作按钮行 -->
104 - <view class="u-body-item task-btn-row mt-20"> 104 + <view class="u-body-item task-btn-row mt-20"
  105 + :style="{'--cols': getActionRowCols(actionBtnCount(item))}">
105 <!-- 已配置工作流动作:按配置逐个渲染按钮,点击直接执行对应动作,不再弹「请选择操作」 --> 106 <!-- 已配置工作流动作:按配置逐个渲染按钮,点击直接执行对应动作,不再弹「请选择操作」 -->
106 <template v-if="hasConfiguredActions(item)"> 107 <template v-if="hasConfiguredActions(item)">
107 <view 108 <view
@@ -110,7 +111,7 @@ @@ -110,7 +111,7 @@
110 :class="['task-btn', 'task-btn--' + getActionButtonType(action.code)]" 111 :class="['task-btn', 'task-btn--' + getActionButtonType(action.code)]"
111 @click.stop="handleUnifiedProcess(item, action)" 112 @click.stop="handleUnifiedProcess(item, action)"
112 >{{ action.name }}</view> 113 >{{ action.name }}</view>
113 - <view class="task-btn task-btn--info" @click.stop="handleDetail(item)">详情</view> 114 + <view class="task-btn task-btn--primary" @click.stop="handleDetail(item)">详情</view>
114 </template> 115 </template>
115 <!-- 未配置:沿用原有节点按钮 --> 116 <!-- 未配置:沿用原有节点按钮 -->
116 <template v-else> 117 <template v-else>
@@ -120,7 +121,7 @@ @@ -120,7 +121,7 @@
120 @click.stop="handleRenew(item)">重新提交</view> 121 @click.stop="handleRenew(item)">重新提交</view>
121 <view class="task-btn task-btn--primary" 122 <view class="task-btn task-btn--primary"
122 @click.stop="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</view> 123 @click.stop="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</view>
123 - <view class="task-btn task-btn--info" @click.stop="handleDetail(item)">详情</view> 124 + <view class="task-btn task-btn--primary" @click.stop="handleDetail(item)">详情</view>
124 </template> 125 </template>
125 </view> 126 </view>
126 </view> 127 </view>
@@ -298,7 +299,7 @@ import { @@ -298,7 +299,7 @@ import {
298 } from '@/api/work-order-manage/work-order-manage' 299 } from '@/api/work-order-manage/work-order-manage'
299 // 从用户store获取角色信息 300 // 从用户store获取角色信息
300 import { useUserStore } from '@/pinia/user'; 301 import { useUserStore } from '@/pinia/user';
301 -import { nextStepMap, buzStatusMap, getActionButtonType, toWorkerImplementPage } from '@/common/utils/common' 302 +import { nextStepMap, buzStatusMap, getActionButtonType, getActionRowCols, toWorkerImplementPage } from '@/common/utils/common'
302 // 引入图片上传组合式函数(与参考页面一致) 303 // 引入图片上传组合式函数(与参考页面一致)
303 import { useUploadImgs } from '@/common/utils/useUploadImgs' 304 import { useUploadImgs } from '@/common/utils/useUploadImgs'
304 305
@@ -346,7 +347,6 @@ const rejectImgs = useUploadImgs({ @@ -346,7 +347,6 @@ const rejectImgs = useUploadImgs({
346 fieldName: 'rejectImgs' // 自定义字段名 347 fieldName: 'rejectImgs' // 自定义字段名
347 }) 348 })
348 349
349 -  
350 // ========== 验收弹窗相关状态(含图片上传) ========== 350 // ========== 验收弹窗相关状态(含图片上传) ==========
351 const acceptModalShow = ref(false); // 验收弹窗显示开关 351 const acceptModalShow = ref(false); // 验收弹窗显示开关
352 const acceptRadioValue = ref('0'); // 单选框值,默认0(通过) 352 const acceptRadioValue = ref('0'); // 单选框值,默认0(通过)
@@ -389,7 +389,6 @@ const openMapNav = (item) =&gt; { @@ -389,7 +389,6 @@ const openMapNav = (item) =&gt; {
389 // }); 389 // });
390 }; 390 };
391 391
392 -  
393 // 分页查询列表 392 // 分页查询列表
394 const queryList = async (pageNo, pageSize) => { 393 const queryList = async (pageNo, pageSize) => {
395 try { 394 try {
@@ -550,6 +549,17 @@ const getProcessButtonText = (item) =&gt; { @@ -550,6 +549,17 @@ const getProcessButtonText = (item) =&gt; {
550 const hasConfiguredActions = (item) => 549 const hasConfiguredActions = (item) =>
551 Array.isArray(item?.configuredActions) && item.configuredActions.length > 0 550 Array.isArray(item?.configuredActions) && item.configuredActions.length > 0
552 551
  552 +/** 操作按钮行按钮数量:单个占一半宽度,多个等分,最多 5 个一行 */
  553 +const actionBtnCount = (item) => {
  554 + if (hasConfiguredActions(item)) {
  555 + return item.configuredActions.length + 1 // 配置动作 + 详情
  556 + }
  557 + let count = 2 // 主按钮 + 详情
  558 + if (showRejectButton(item)) count++
  559 + if (nextStepMap[item.taskKey]?.renewShow) count++
  560 + return count
  561 +}
  562 +
553 /** 待办-处理工单:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */ 563 /** 待办-处理工单:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */
554 const handleUnifiedProcess = async (item, action = null) => { 564 const handleUnifiedProcess = async (item, action = null) => {
555 const actions = Array.isArray(item?.configuredActions) 565 const actions = Array.isArray(item?.configuredActions)
@@ -859,11 +869,12 @@ onUnload(() =&gt; { @@ -859,11 +869,12 @@ onUnload(() =&gt; {
859 border-radius: 12rpx; 869 border-radius: 12rpx;
860 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); 870 box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04);
861 } 871 }
862 -// 卡片操作按钮:自动换行、右对齐,动作多时每行 3~4 个,不再整行铺满 872 +// 卡片操作按钮:单个占页面一半宽度(左对齐),多个等分,每行最多 5 个,超出自动换行
863 .task-btn-row { 873 .task-btn-row {
864 - display: flex;  
865 - flex-wrap: wrap;  
866 - justify-content: flex-end; 874 + display: grid;
  875 + grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr));
  876 + column-gap: 12rpx;
  877 + row-gap: 10rpx;
867 margin-bottom: -10rpx; 878 margin-bottom: -10rpx;
868 } 879 }
869 880
@@ -871,20 +882,23 @@ onUnload(() =&gt; { @@ -871,20 +882,23 @@ onUnload(() =&gt; {
871 box-sizing: border-box; 882 box-sizing: border-box;
872 height: 56rpx; 883 height: 56rpx;
873 line-height: 56rpx; 884 line-height: 56rpx;
874 - padding: 0 24rpx;  
875 - margin: 0 0 10rpx 12rpx; 885 + padding: 0 12rpx;
876 border-radius: 8rpx; 886 border-radius: 8rpx;
877 font-size: 24rpx; 887 font-size: 24rpx;
878 color: #fff; 888 color: #fff;
  889 + text-align: center;
879 white-space: nowrap; 890 white-space: nowrap;
  891 + overflow: hidden;
  892 + text-overflow: ellipsis;
880 } 893 }
881 894
  895 +/* 按动作编码配色:通过/实施/结束类动作绿色,退回类橙色 */
882 .task-btn--primary { 896 .task-btn--primary {
883 - background-color: #3c9cff; 897 + background-color: #3b9dff;
884 } 898 }
885 899
886 .task-btn--success { 900 .task-btn--success {
887 - background-color: #5ac725; 901 + background-color: #078d0a;
888 } 902 }
889 903
890 .task-btn--warning { 904 .task-btn--warning {
@@ -899,8 +913,6 @@ onUnload(() =&gt; { @@ -899,8 +913,6 @@ onUnload(() =&gt; {
899 background-color: #909399; 913 background-color: #909399;
900 } 914 }
901 915
902 -  
903 -  
904 // 回退modal样式 916 // 回退modal样式
905 .reject-modal-content { 917 .reject-modal-content {
906 width: 100%; 918 width: 100%;
pages-sub/problem/work-order-manage/order-detail.vue
@@ -116,7 +116,6 @@ @@ -116,7 +116,6 @@
116 </template> 116 </template>
117 </up-cell> 117 </up-cell>
118 118
119 -  
120 119
121 <up-cell title="重点巡检区域" :value="orderDetail.keyInspection==0?'否':'是'" align="middle"></up-cell> 120 <up-cell title="重点巡检区域" :value="orderDetail.keyInspection==0?'否':'是'" align="middle"></up-cell>
122 121
@@ -237,7 +236,7 @@ @@ -237,7 +236,7 @@
237 <view class="step-content-wrap"> 236 <view class="step-content-wrap">
238 <!-- 1. 原标题内容:节点名称 + 操作人 --> 237 <!-- 1. 原标题内容:节点名称 + 操作人 -->
239 <view class="step-title"> 238 <view class="step-title">
240 - {{ item.name ? item.name.replace('大区经理', '业务调度员') : item.name }} 239 + {{ item.name }}
241 </view> 240 </view>
242 241
243 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) --> 242 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) -->
@@ -294,8 +293,9 @@ @@ -294,8 +293,9 @@
294 <!-- activeTab==0的时候才出现, 也就是待办 --> 293 <!-- activeTab==0的时候才出现, 也就是待办 -->
295 <view v-if="activeTab==0&&(configuredActions||nextStepMap[orderDetail.taskKey])" 294 <view v-if="activeTab==0&&(configuredActions||nextStepMap[orderDetail.taskKey])"
296 class="fixed-bottom-btn-wrap order-action-bar"> 295 class="fixed-bottom-btn-wrap order-action-bar">
297 - <!-- 已配置工作流动作:每行最多 3 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->  
298 - <view v-if="hasConfiguredActions" class="order-action-row"> 296 + <!-- 已配置工作流动作:每行最多 5 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->
  297 + <view v-if="hasConfiguredActions" class="order-action-row"
  298 + :style="{'--cols': getActionRowCols(configuredActions.length)}">
299 <view 299 <view
300 v-for="action in configuredActions" 300 v-for="action in configuredActions"
301 :key="action.code" 301 :key="action.code"
@@ -303,8 +303,8 @@ @@ -303,8 +303,8 @@
303 @click.stop="handleUnifiedProcess(orderDetail, action)" 303 @click.stop="handleUnifiedProcess(orderDetail, action)"
304 >{{ action.name }}</view> 304 >{{ action.name }}</view>
305 </view> 305 </view>
306 - <!-- 未配置:沿用原有节点按钮(整行展示) -->  
307 - <view v-else class="order-action-row order-action-row--single"> 306 + <!-- 未配置:沿用原有节点按钮 -->
  307 + <view v-else class="order-action-row" :style="{'--cols': getActionRowCols(legacyActionCount)}">
308 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning" 308 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning"
309 @click.stop="handleUnifiedReject(orderDetail)">回退</view> 309 @click.stop="handleUnifiedReject(orderDetail)">回退</view>
310 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success" 310 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success"
@@ -418,7 +418,7 @@ import { @@ -418,7 +418,7 @@ import {
418 getTaskActions 418 getTaskActions
419 } from '@/api/work-order-manage/work-order-manage'; 419 } from '@/api/work-order-manage/work-order-manage';
420 import {getWorkRecordValues} from '@/api/common' 420 import {getWorkRecordValues} from '@/api/common'
421 -import {nextStepMap, buzStatusMap, calculateFormatTimeDiff, getActionButtonType, toWorkerImplementPage} from '@/common/utils/common' 421 +import {nextStepMap, buzStatusMap, calculateFormatTimeDiff, getActionButtonType, getActionRowCols, toWorkerImplementPage} from '@/common/utils/common'
422 // 引入图片上传组合式函数 422 // 引入图片上传组合式函数
423 import {useUploadImgs} from '@/common/utils/useUploadImgs' 423 import {useUploadImgs} from '@/common/utils/useUploadImgs'
424 424
@@ -813,15 +813,20 @@ const showRejectButton = computed(() =&gt; { @@ -813,15 +813,20 @@ const showRejectButton = computed(() =&gt; {
813 const hasConfiguredActions = computed(() => 813 const hasConfiguredActions = computed(() =>
814 Array.isArray(configuredActions.value) && configuredActions.value.length > 0) 814 Array.isArray(configuredActions.value) && configuredActions.value.length > 0)
815 815
816 -/** 底部操作栏行数:详情内容据此预留底部间距,避免按钮遮挡内容 */ 816 +/** 未配置统一动作时的按钮数量:主按钮 + 可选的回退/重新提交 */
  817 +const legacyActionCount = computed(() => {
  818 + let count = 1
  819 + if (showRejectButton.value) count++
  820 + if (nextStepMap[orderDetail.value.taskKey]?.renewShow) count++
  821 + return count
  822 +})
  823 +
  824 +/** 底部操作栏行数:详情内容据此预留底部间距,避免按钮遮挡内容(每行最多 5 个) */
817 const actionBarRows = computed(() => { 825 const actionBarRows = computed(() => {
818 if (hasConfiguredActions.value) { 826 if (hasConfiguredActions.value) {
819 - return Math.ceil(configuredActions.value.length / 3) 827 + return Math.ceil(configuredActions.value.length / 5)
820 } 828 }
821 - let rows = 1  
822 - if (showRejectButton.value) rows++  
823 - if (nextStepMap[orderDetail.value.taskKey]?.renewShow) rows++  
824 - return rows 829 + return 1
825 }) 830 })
826 831
827 /** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */ 832 /** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
@@ -1261,7 +1266,7 @@ onShow(() =&gt; { @@ -1261,7 +1266,7 @@ onShow(() =&gt; {
1261 } 1266 }
1262 1267
1263 // 底部动作按钮:动作多时自动换行 1268 // 底部动作按钮:动作多时自动换行
1264 -// 底部操作栏:白底 + 顶部投影,按钮每行最多 3 个,避免多动作时整屏遮挡工单详情 1269 +// 底部操作栏:白底 + 顶部投影,按钮每行最多 5 个,避免多动作时整屏遮挡工单详情
1265 .order-action-bar { 1270 .order-action-bar {
1266 background-color: #fff; 1271 background-color: #fff;
1267 box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06); 1272 box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.06);
@@ -1271,17 +1276,16 @@ onShow(() =&gt; { @@ -1271,17 +1276,16 @@ onShow(() =&gt; {
1271 } 1276 }
1272 1277
1273 .order-action-row { 1278 .order-action-row {
1274 - display: flex;  
1275 - flex-wrap: wrap;  
1276 - margin: -6rpx; 1279 + display: grid;
  1280 + grid-template-columns: repeat(var(--cols, 5), minmax(0, 1fr));
  1281 + column-gap: 12rpx;
  1282 + row-gap: 12rpx;
1277 } 1283 }
1278 1284
1279 .order-action-btn { 1285 .order-action-btn {
1280 box-sizing: border-box; 1286 box-sizing: border-box;
1281 - width: calc((100% - 36rpx) / 3);  
1282 height: 68rpx; 1287 height: 68rpx;
1283 line-height: 68rpx; 1288 line-height: 68rpx;
1284 - margin: 6rpx;  
1285 padding: 0 8rpx; 1289 padding: 0 8rpx;
1286 border-radius: 8rpx; 1290 border-radius: 8rpx;
1287 font-size: 26rpx; 1291 font-size: 26rpx;
@@ -1292,17 +1296,13 @@ onShow(() =&gt; { @@ -1292,17 +1296,13 @@ onShow(() =&gt; {
1292 text-overflow: ellipsis; 1296 text-overflow: ellipsis;
1293 } 1297 }
1294 1298
1295 -// 未配置统一动作时按钮整行展示,保持原有观感  
1296 -.order-action-row--single .order-action-btn {  
1297 - width: 100%;  
1298 -}  
1299 - 1299 +/* 按动作编码配色:通过/实施/结束类动作绿色,退回类橙色 */
1300 .order-action-btn--primary { 1300 .order-action-btn--primary {
1301 - background-color: #3c9cff; 1301 + background-color: #3b9dff;
1302 } 1302 }
1303 1303
1304 .order-action-btn--success { 1304 .order-action-btn--success {
1305 - background-color: #5ac725; 1305 + background-color: #078d0a;
1306 } 1306 }
1307 1307
1308 .order-action-btn--warning { 1308 .order-action-btn--warning {