Commit 9120066cfe0aed12a4ed7dfe25d6b4f1a3fac6c4
1 parent
5902ef3e
业务线 小程序不用写死,从后端接口获取
Showing
12 changed files
with
196 additions
and
131 deletions
App.vue
| @@ -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 = () => { | @@ -145,9 +145,18 @@ const handleAddReport = () => { | ||
| 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(() => { | @@ -348,13 +348,18 @@ onUnload(() => { | ||
| 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) => { | @@ -510,6 +511,16 @@ const getProcessButtonText = (item) => { | ||
| 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(() => { | @@ -749,11 +760,12 @@ onShow(() => { | ||
| 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(() => { | @@ -761,20 +773,23 @@ onShow(() => { | ||
| 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(() => { | @@ -789,7 +804,6 @@ onShow(() => { | ||
| 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) => { | @@ -491,6 +492,17 @@ const getProcessButtonText = (item) => { | ||
| 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) => { | @@ -576,7 +588,6 @@ const handleProcess = async (item) => { | ||
| 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(() => { | @@ -745,11 +756,12 @@ onLoad(() => { | ||
| 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(() => { | @@ -757,20 +769,23 @@ onLoad(() => { | ||
| 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(() => { | @@ -785,7 +800,6 @@ onLoad(() => { | ||
| 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 '@/uni_modules/uview-plus' | @@ -337,7 +338,7 @@ import { timeFormat } from '@/uni_modules/uview-plus' | ||
| 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(() => { | @@ -523,15 +524,20 @@ const showRejectButton = computed(() => { | ||
| 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) => { | @@ -1025,8 +1031,7 @@ onLoad((options: any) => { | ||
| 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) => { | @@ -1035,18 +1040,17 @@ onLoad((options: any) => { | ||
| 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) => { | @@ -1057,17 +1061,13 @@ onLoad((options: any) => { | ||
| 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(() => { | @@ -593,15 +593,20 @@ const showRejectButton = computed(() => { | ||
| 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(() => {}); | @@ -1173,7 +1178,7 @@ onShow(() => {}); | ||
| 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(() => {}); | @@ -1183,17 +1188,16 @@ onShow(() => {}); | ||
| 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(() => {}); | @@ -1204,17 +1208,13 @@ onShow(() => {}); | ||
| 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) => { | @@ -389,7 +389,6 @@ const openMapNav = (item) => { | ||
| 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) => { | @@ -550,6 +549,17 @@ const getProcessButtonText = (item) => { | ||
| 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(() => { | @@ -859,11 +869,12 @@ onUnload(() => { | ||
| 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(() => { | @@ -871,20 +882,23 @@ onUnload(() => { | ||
| 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(() => { | @@ -899,8 +913,6 @@ onUnload(() => { | ||
| 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(() => { | @@ -813,15 +813,20 @@ const showRejectButton = computed(() => { | ||
| 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(() => { | @@ -1261,7 +1266,7 @@ onShow(() => { | ||
| 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(() => { | @@ -1271,17 +1276,16 @@ onShow(() => { | ||
| 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(() => { | @@ -1292,17 +1296,13 @@ onShow(() => { | ||
| 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 { |