Commit ea8ea9498e03e45193aa84199db9e58a16ca7cb3

Authored by 刘淇
1 parent b10b29b6

优化

pages-sub/problem/regional-order-manage/order-detail.vue
1 <template> 1 <template>
2 <view class="page-container"> 2 <view class="page-container">
3 <!-- 页面级加载组件 --> 3 <!-- 页面级加载组件 -->
4 - <up-loading-page  
5 - v-if="loading"  
6 - :loading="true"  
7 - title="加载中..."  
8 - color="#2563EB"  
9 - ></up-loading-page> 4 + <up-loading-page v-if="loading" :loading="true" title="加载中..." color="#2563EB"></up-loading-page>
10 5
11 <!-- 主内容容器 --> 6 <!-- 主内容容器 -->
12 <view v-else class="main-content" :class="'pb-rows-' + actionBarRows"> 7 <view v-else class="main-content" :class="'pb-rows-' + actionBarRows">
13 <!-- 顶部固定Tabs --> 8 <!-- 顶部固定Tabs -->
14 <up-sticky :bgColor="'#fff'"> 9 <up-sticky :bgColor="'#fff'">
15 - <up-tabs  
16 - v-model="activeTopTab"  
17 - :list="topTabList"  
18 - :scrollable="false"  
19 - sticky  
20 - active-color="#2563EB"  
21 - inactive-color="#606266"  
22 - class="top-tabs"  
23 - @click="activeTopTabClick"  
24 - lineWidth="65"  
25 - ></up-tabs> 10 + <up-tabs v-model="activeTopTab" :list="topTabList" :scrollable="false" sticky active-color="#2563EB"
  11 + inactive-color="#606266" class="top-tabs" @click="activeTopTabClick" lineWidth="65"></up-tabs>
26 </up-sticky> 12 </up-sticky>
27 13
28 <!-- 顶部Tab内容区 --> 14 <!-- 顶部Tab内容区 -->
@@ -76,21 +62,16 @@ @@ -76,21 +62,16 @@
76 </up-cell> 62 </up-cell>
77 63
78 <!-- 紧急程度 --> 64 <!-- 紧急程度 -->
79 - <up-cell  
80 - title="紧急程度:"  
81 - :value="uni.$dict.getDictLabel('workorder_pressing_type', orderDetail.pressingType) || '--'"  
82 - align="middle"  
83 - ></up-cell> 65 + <up-cell title="紧急程度:"
  66 + :value="uni.$dict.getDictLabel('workorder_pressing_type', orderDetail.pressingType) || '--'"
  67 + align="middle"></up-cell>
84 68
85 <!-- 提交人 --> 69 <!-- 提交人 -->
86 <up-cell title="提交人:" :value="orderDetail.userName || '--'" align="middle"></up-cell> 70 <up-cell title="提交人:" :value="orderDetail.userName || '--'" align="middle"></up-cell>
87 71
88 <!-- 提交时间 --> 72 <!-- 提交时间 -->
89 - <up-cell  
90 - title="提交时间:"  
91 - :value="timeFormat(orderDetail.createTime, 'yyyy-mm-dd hh:MM:ss') || '--'"  
92 - align="middle"  
93 - ></up-cell> 73 + <up-cell title="提交时间:" :value="timeFormat(orderDetail.createTime, 'yyyy-mm-dd hh:MM:ss') || '--'"
  74 + align="middle"></up-cell>
94 75
95 <!-- 处理结果 --> 76 <!-- 处理结果 -->
96 <up-cell v-if="orderDetail.handleResult"> 77 <up-cell v-if="orderDetail.handleResult">
@@ -106,38 +87,25 @@ @@ -106,38 +87,25 @@
106 <up-cell title="问题照片"> 87 <up-cell title="问题照片">
107 <template #value> 88 <template #value>
108 <view class="cell-content-wrap"> 89 <view class="cell-content-wrap">
109 - <up-album  
110 - v-if="!!orderDetail.problemsImgs?.length"  
111 - :urls="orderDetail.problemsImgs.slice(0, 3)"  
112 - :singleSize="70"  
113 - :multipleSize="70"  
114 - :preview-full-image="true"  
115 - ></up-album> 90 + <up-album v-if="!!orderDetail.problemsImgs?.length" :urls="orderDetail.problemsImgs.slice(0, 3)"
  91 + :singleSize="70" :multipleSize="70" :preview-full-image="true"></up-album>
116 <text v-else class="empty-text">暂无问题照片</text> 92 <text v-else class="empty-text">暂无问题照片</text>
117 </view> 93 </view>
118 </template> 94 </template>
119 </up-cell> 95 </up-cell>
120 96
121 <!-- 希望完成时间 --> 97 <!-- 希望完成时间 -->
122 - <up-cell  
123 - v-if="orderDetail.expectedFinishDate"  
124 - title="希望完成时间:"  
125 - :value="timeFormat(orderDetail.expectedFinishDate, 'yyyy-mm-dd hh:MM:ss')"  
126 - align="middle"  
127 - :border="false"  
128 - ></up-cell>  
129 -  
130 - <up-cell  
131 - v-if="orderDetail.finishDate"  
132 - title="工单完结时间:"  
133 - :value="timeFormat(orderDetail.finishDate, 'yyyy-mm-dd hh:MM:ss')"  
134 - align="middle"  
135 - :border="false"  
136 - ></up-cell> 98 + <up-cell v-if="orderDetail.expectedFinishDate" title="希望完成时间:"
  99 + :value="timeFormat(orderDetail.expectedFinishDate, 'yyyy-mm-dd hh:MM:ss')" align="middle"
  100 + :border="false"></up-cell>
  101 +
  102 + <up-cell v-if="orderDetail.finishDate" title="工单完结时间:"
  103 + :value="timeFormat(orderDetail.finishDate, 'yyyy-mm-dd hh:MM:ss')" align="middle"
  104 + :border="false"></up-cell>
137 </up-cell-group> 105 </up-cell-group>
138 106
139 <!-- 图片分类Tabs区块 --> 107 <!-- 图片分类Tabs区块 -->
140 - <view class="img-tabs-block" v-if="orderDetail.startImgs.length>0"> 108 + <view class="img-tabs-block" v-if="orderDetail.startImgs.length > 0">
141 <up-cell-group :border="false"> 109 <up-cell-group :border="false">
142 <up-cell> 110 <up-cell>
143 <template #title> 111 <template #title>
@@ -146,32 +114,20 @@ @@ -146,32 +114,20 @@
146 <template #value> 114 <template #value>
147 <view class="common-text-color up-line-1"> 115 <view class="common-text-color up-line-1">
148 {{ 116 {{
149 - Array.isArray(orderDetail.coHandlersName) && orderDetail.coHandlersName.length > 0 ? orderDetail.coHandlersName.join(',') : '--' 117 + Array.isArray(orderDetail.coHandlersName) && orderDetail.coHandlersName.length > 0 ?
  118 + orderDetail.coHandlersName.join(',') : '--'
150 }} 119 }}
151 </view> 120 </view>
152 </template> 121 </template>
153 </up-cell> 122 </up-cell>
154 </up-cell-group> 123 </up-cell-group>
155 - <up-tabs  
156 - @change='imgTabChange'  
157 - v-model="activeImgTab"  
158 - :list="imgTabList"  
159 - :scrollable="false"  
160 - active-color="#2563EB"  
161 - inactive-color="#606266"  
162 - class="img-tabs"  
163 - ></up-tabs> 124 + <up-tabs @change='imgTabChange' v-model="activeImgTab" :list="imgTabList" :scrollable="false"
  125 + active-color="#2563EB" inactive-color="#606266" class="img-tabs"></up-tabs>
164 126
165 <!-- 图片Tab内容区 --> 127 <!-- 图片Tab内容区 -->
166 <view class="img-tab-content"> 128 <view class="img-tab-content">
167 - <up-album  
168 - v-if="currentImgList.length"  
169 - :urls="currentImgList.slice(0, 3)"  
170 - :singleSize="70"  
171 - :multipleSize="70"  
172 - :preview-full-image="true"  
173 - class="img-album custom-album"  
174 - ></up-album> 129 + <up-album v-if="currentImgList.length" :urls="currentImgList.slice(0, 3)" :singleSize="70"
  130 + :multipleSize="70" :preview-full-image="true" class="img-album custom-album"></up-album>
175 <text v-else class="empty-img-text">养护员未上传图片</text> 131 <text v-else class="empty-img-text">养护员未上传图片</text>
176 </view> 132 </view>
177 </view> 133 </view>
@@ -180,20 +136,11 @@ @@ -180,20 +136,11 @@
180 <!-- 2. 流程节点Tab --> 136 <!-- 2. 流程节点Tab -->
181 <view v-show="activeTopTab == 1" class="process-content"> 137 <view v-show="activeTopTab == 1" class="process-content">
182 <!-- 竖向步骤条:动态绑定current属性 --> 138 <!-- 竖向步骤条:动态绑定current属性 -->
183 - <up-steps  
184 - v-if="processData.activityNodes && processData.activityNodes.length"  
185 - :list="processData.activityNodes"  
186 - :current="getCurrentStepIndex()"  
187 - direction="column"  
188 - active-color="#2563EB"  
189 - inactive-color="#909399"  
190 - class="vertical-steps"  
191 - > 139 + <up-steps v-if="processData.activityNodes && processData.activityNodes.length"
  140 + :list="processData.activityNodes" :current="getCurrentStepIndex()" direction="column" active-color="#2563EB"
  141 + inactive-color="#909399" class="vertical-steps">
192 <template> 142 <template>
193 - <up-steps-item  
194 - v-for="(item, index) in processData.activityNodes"  
195 - :key="`${item.id}_${index}`"  
196 - > 143 + <up-steps-item v-for="(item, index) in processData.activityNodes" :key="`${item.id}_${index}`">
197 <!-- 唯一自定义模板:content,包含标题、描述、相册所有内容 --> 144 <!-- 唯一自定义模板:content,包含标题、描述、相册所有内容 -->
198 <template #content> 145 <template #content>
199 <view class="step-content-wrap"> 146 <view class="step-content-wrap">
@@ -204,9 +151,10 @@ @@ -204,9 +151,10 @@
204 151
205 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) --> 152 <!-- 2. 原描述内容:时间 + 处理说明(最多200字) -->
206 <view class="step-desc"> 153 <view class="step-desc">
207 - <view class="operator-name up-line-1" v-if="item.tasks"> 154 + <view class="operator-name up-line-1" v-if="item.tasks">
208 处理人: 155 处理人:
209 - <text>{{ item.tasks?.map(itemName => itemName.assigneeUser?.nickname).filter(Boolean).join(',') }}</text> 156 + <text>{{item.tasks?.map(itemName => itemName.assigneeUser?.nickname).filter(Boolean).join(',')
  157 + }}</text>
210 </view> 158 </view>
211 <!-- 时间行 --> 159 <!-- 时间行 -->
212 <view class="time-line"> 160 <view class="time-line">
@@ -215,7 +163,7 @@ @@ -215,7 +163,7 @@
215 <text v-else-if="item.status === 1" class="processing-tag">(处理中)</text> 163 <text v-else-if="item.status === 1" class="processing-tag">(处理中)</text>
216 </view> 164 </view>
217 165
218 - <view class="reason-line up-line-1" v-if="index!==0&&item.endTime"> 166 + <view class="reason-line up-line-1" v-if="index !== 0 && item.endTime">
219 总耗时:{{ calculateFormatTimeDiff(item.startTime, item.endTime) }} 167 总耗时:{{ calculateFormatTimeDiff(item.startTime, item.endTime) }}
220 </view> 168 </view>
221 169
@@ -228,13 +176,9 @@ @@ -228,13 +176,9 @@
228 <!-- 3. 原相册内容:预留up-album --> 176 <!-- 3. 原相册内容:预留up-album -->
229 <view class="step-album-wrap"> 177 <view class="step-album-wrap">
230 <up-album 178 <up-album
231 - v-if="item.tasks && item.tasks[0]?.attattmentUrls && item.tasks[0].attattmentUrls.length"  
232 - :urls="item.tasks[0].attattmentUrls.slice(0, 3)"  
233 - :singleSize="70"  
234 - :multipleSize="70"  
235 - :preview-full-image="true"  
236 - class="step-album"  
237 - ></up-album> 179 + v-if="item.tasks && item.tasks[0]?.attattmentUrls && item.tasks[0].attattmentUrls.length"
  180 + :urls="item.tasks[0].attattmentUrls.slice(0, 3)" :singleSize="70" :multipleSize="70"
  181 + :preview-full-image="true" class="step-album"></up-album>
238 </view> 182 </view>
239 </view> 183 </view>
240 </template> 184 </template>
@@ -243,87 +187,51 @@ @@ -243,87 +187,51 @@
243 </up-steps> 187 </up-steps>
244 188
245 <!-- 流程节点为空时的提示 --> 189 <!-- 流程节点为空时的提示 -->
246 - <up-empty  
247 - v-else  
248 - mode="data"  
249 - title="暂无流程节点数据"  
250 - class="empty-process"  
251 - ></up-empty> 190 + <up-empty v-else mode="data" title="暂无流程节点数据" class="empty-process"></up-empty>
252 </view> 191 </view>
253 </view> 192 </view>
254 </view> 193 </view>
255 194
256 <!-- activeTab==0的时候才出现, 也就是待办 --> 195 <!-- activeTab==0的时候才出现, 也就是待办 -->
257 - <view v-if="activeTab==0&&(configuredActions||nextStepMap[orderDetail.taskKey])"  
258 - class="fixed-bottom-btn-wrap order-action-bar"> 196 + <view v-if="activeTab == 0 && (configuredActions || nextStepMap[orderDetail.taskKey])"
  197 + class="fixed-bottom-btn-wrap order-action-bar">
259 <!-- 已配置工作流动作:每行最多 5 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 --> 198 <!-- 已配置工作流动作:每行最多 5 个、超出自动换行,点击直接执行对应动作,不再弹「请选择操作」 -->
260 <view v-if="hasConfiguredActions" class="order-action-row" 199 <view v-if="hasConfiguredActions" class="order-action-row"
261 - :style="{'--cols': getActionRowCols(configuredActions.length)}">  
262 - <view  
263 - v-for="action in configuredActions"  
264 - :key="action.code"  
265 - :class="['order-action-btn', 'order-action-btn--' + getActionButtonType(action.code, action.name)]"  
266 - @click.stop="handleUnifiedProcess(orderDetail, action)"  
267 - >{{ action.name }}</view> 200 + :style="{ '--cols': getActionRowCols(configuredActions.length) }">
  201 + <view v-for="action in configuredActions" :key="action.code"
  202 + :class="['order-action-btn', 'order-action-btn--' + getActionButtonType(action.code, action.name)]"
  203 + @click.stop="handleUnifiedProcess(orderDetail, action)">{{ action.name }}</view>
268 </view> 204 </view>
269 <!-- 未配置:沿用原有节点按钮 --> 205 <!-- 未配置:沿用原有节点按钮 -->
270 - <view v-else class="order-action-row" :style="{'--cols': getActionRowCols(legacyActionCount)}"> 206 + <view v-else class="order-action-row" :style="{ '--cols': getActionRowCols(legacyActionCount) }">
271 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning" 207 <view v-if="showRejectButton" class="order-action-btn order-action-btn--warning"
272 - @click.stop="handleUnifiedReject(orderDetail)">回退</view> 208 + @click.stop="handleUnifiedReject(orderDetail)">回退</view>
273 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success" 209 <view v-if="nextStepMap[orderDetail.taskKey]?.renewShow" class="order-action-btn order-action-btn--success"
274 - @click.stop="handleRenew(orderDetail)">重新提交</view>  
275 - <view class="order-action-btn order-action-btn--primary"  
276 - @click.stop="handleUnifiedProcess(orderDetail)">{{ processButtonText }}</view> 210 + @click.stop="handleRenew(orderDetail)">重新提交</view>
  211 + <view class="order-action-btn order-action-btn--primary" @click.stop="handleUnifiedProcess(orderDetail)">{{
  212 + processButtonText }}</view>
277 </view> 213 </view>
278 </view> 214 </view>
279 215
280 <!-- 回退原因弹窗(新增图片上传) --> 216 <!-- 回退原因弹窗(新增图片上传) -->
281 - <up-modal  
282 - :show="rejectModalShow"  
283 - title="回退原因"  
284 - :closeOnClickOverlay="false"  
285 - :showConfirmButton="true"  
286 - :showCancelButton="true"  
287 - @cancel="handleRejectModalCancel"  
288 - @confirm="confirmReject"  
289 - > 217 + <up-modal :show="rejectModalShow" title="回退原因" :closeOnClickOverlay="false" :showConfirmButton="true"
  218 + :showCancelButton="true" @cancel="handleRejectModalCancel" @confirm="confirmReject">
290 <view class="reject-modal-content"> 219 <view class="reject-modal-content">
291 - <up-textarea  
292 - v-model.trim="rejectReason"  
293 - placeholder="请输入回退原因(必填)"  
294 - rows="6"  
295 - :count="200"  
296 - maxlength="200"  
297 - class="reject-textarea"  
298 - /> 220 + <up-textarea v-model.trim="rejectReason" placeholder="请输入回退原因(必填)" rows="6" :count="200" maxlength="200"
  221 + class="reject-textarea" />
299 <!-- 新增:回退图片上传(选填) --> 222 <!-- 新增:回退图片上传(选填) -->
300 <view class="upload-wrap mt-20"> 223 <view class="upload-wrap mt-20">
301 <view class="upload-title">上传回退图片(选填)</view> 224 <view class="upload-title">上传回退图片(选填)</view>
302 - <up-upload  
303 - :file-list="rejectImgs.rawImgList.value || []"  
304 - @after-read="rejectImgs.uploadImgs"  
305 - @delete="rejectImgs.deleteImg"  
306 - multiple  
307 - width="70"  
308 - height="70"  
309 - :max-count="rejectImgs.uploadConfig.maxCount"  
310 - :upload-text="rejectImgs.uploadConfig.uploadText"  
311 - :size-type="rejectImgs.uploadConfig.sizeType"  
312 - /> 225 + <up-upload :file-list="rejectImgs.rawImgList.value || []" @after-read="rejectImgs.uploadImgs"
  226 + @delete="rejectImgs.deleteImg" multiple width="70" height="70" :max-count="rejectImgs.uploadConfig.maxCount"
  227 + :upload-text="rejectImgs.uploadConfig.uploadText" :size-type="rejectImgs.uploadConfig.sizeType" />
313 </view> 228 </view>
314 </view> 229 </view>
315 </up-modal> 230 </up-modal>
316 231
317 <!-- 验收弹窗(新增图片上传) --> 232 <!-- 验收弹窗(新增图片上传) -->
318 - <up-modal  
319 - :show="acceptModalShow"  
320 - title="验收"  
321 - :closeOnClickOverlay="false"  
322 - :showConfirmButton="true"  
323 - :showCancelButton="true"  
324 - @cancel="handleAcceptModalCancel"  
325 - @confirm="handleAcceptModalConfirm"  
326 - > 233 + <up-modal :show="acceptModalShow" title="验收" :closeOnClickOverlay="false" :showConfirmButton="true"
  234 + :showCancelButton="true" @cancel="handleAcceptModalCancel" @confirm="handleAcceptModalConfirm">
327 <view class="accept-modal-content"> 235 <view class="accept-modal-content">
328 <!-- 第一行:单选框(通过/不通过,默认通过) --> 236 <!-- 第一行:单选框(通过/不通过,默认通过) -->
329 <view class="radio-group-wrap"> 237 <view class="radio-group-wrap">
@@ -335,30 +243,16 @@ @@ -335,30 +243,16 @@
335 243
336 <!-- 第二行:必填textarea,最多200字 --> 244 <!-- 第二行:必填textarea,最多200字 -->
337 <view class="textarea-wrap mt-30"> 245 <view class="textarea-wrap mt-30">
338 - <up-textarea  
339 - v-model.trim="acceptReason"  
340 - placeholder="请输入验收原因(必填,最多200字)"  
341 - :required="true"  
342 - maxlength="200"  
343 - rows="5"  
344 - count  
345 - /> 246 + <up-textarea v-model.trim="acceptReason" placeholder="请输入验收原因(必填,最多200字)" :required="true" maxlength="200"
  247 + rows="5" count />
346 </view> 248 </view>
347 249
348 <!-- 新增:验收图片上传(选填) --> 250 <!-- 新增:验收图片上传(选填) -->
349 <view class="upload-wrap mt-20"> 251 <view class="upload-wrap mt-20">
350 <view class="upload-title">上传验收图片(选填)</view> 252 <view class="upload-title">上传验收图片(选填)</view>
351 - <up-upload  
352 - :file-list="acceptImgs.rawImgList.value || []"  
353 - @after-read="acceptImgs.uploadImgs"  
354 - @delete="acceptImgs.deleteImg"  
355 - multiple  
356 - width="70"  
357 - height="70"  
358 - :max-count="acceptImgs.uploadConfig.maxCount"  
359 - :upload-text="acceptImgs.uploadConfig.uploadText"  
360 - :size-type="acceptImgs.uploadConfig.sizeType"  
361 - /> 253 + <up-upload :file-list="acceptImgs.rawImgList.value || []" @after-read="acceptImgs.uploadImgs"
  254 + @delete="acceptImgs.deleteImg" multiple width="70" height="70" :max-count="acceptImgs.uploadConfig.maxCount"
  255 + :upload-text="acceptImgs.uploadConfig.uploadText" :size-type="acceptImgs.uploadConfig.sizeType" />
362 </view> 256 </view>
363 </view> 257 </view>
364 </up-modal> 258 </up-modal>
@@ -370,9 +264,9 @@ @@ -370,9 +264,9 @@
370 </template> 264 </template>
371 265
372 <script setup lang="ts"> 266 <script setup lang="ts">
373 -import {ref, computed} from 'vue';  
374 -import {onLoad, onShow} from '@dcloudio/uni-app';  
375 -import {timeFormat} from '@/uni_modules/uview-plus'; 267 +import { ref, computed } from 'vue';
  268 +import { onLoad, onShow } from '@dcloudio/uni-app';
  269 +import { timeFormat } from '@/uni_modules/uview-plus';
376 import { 270 import {
377 getMyTaskDetail, 271 getMyTaskDetail,
378 getDoneTaskDetail, 272 getDoneTaskDetail,
@@ -383,9 +277,9 @@ import { @@ -383,9 +277,9 @@ import {
383 dcyUniversalApproval, 277 dcyUniversalApproval,
384 aiUniversalApproval 278 aiUniversalApproval
385 } from '@/api/regional-order-manage/regional-order-manage'; 279 } from '@/api/regional-order-manage/regional-order-manage';
386 -import {nextStepMap, buzStatusMap, calculateFormatTimeDiff, getActionButtonType, getActionRowCols, toWorkerImplementPage} from '@/common/utils/common'  
387 -import {getTaskActions} from '@/api/work-order-manage/work-order-manage';  
388 -import {useUploadImgs} from '@/common/utils/useUploadImgs' 280 +import { nextStepMap, buzStatusMap, calculateFormatTimeDiff, getActionButtonType, getActionRowCols, toWorkerImplementPage } from '@/common/utils/common'
  281 +import { getTaskActions } from '@/api/work-order-manage/work-order-manage';
  282 +import { useUploadImgs } from '@/common/utils/useUploadImgs'
389 import { useUserStore } from '@/pinia/user'; 283 import { useUserStore } from '@/pinia/user';
390 284
391 // ========== 全局实例 & 常量 ========== 285 // ========== 全局实例 & 常量 ==========
@@ -398,7 +292,7 @@ const eventChannel = ref&lt;any&gt;(null); @@ -398,7 +292,7 @@ const eventChannel = ref&lt;any&gt;(null);
398 /** 292 /**
399 * 统一提示方法 293 * 统一提示方法
400 */ 294 */
401 -const showToast = (title: string, icon: 'none'|'success'|'loading' = 'none', duration = 2000) => { 295 +const showToast = (title: string, icon: 'none' | 'success' | 'loading' = 'none', duration = 2000) => {
402 uni.showToast({ title, icon, duration }); 296 uni.showToast({ title, icon, duration });
403 }; 297 };
404 298
@@ -436,7 +330,7 @@ const callApprovalApi = async (params: any, taskKey: string) =&gt; { @@ -436,7 +330,7 @@ const callApprovalApi = async (params: any, taskKey: string) =&gt; {
436 if (USER_ROLES.includes('Inspector_global')) return await dcyUniversalApproval(params); 330 if (USER_ROLES.includes('Inspector_global')) return await dcyUniversalApproval(params);
437 if (USER_ROLES.includes('Inspector_global_leader')) return await dcyUniversalApproval(params); 331 if (USER_ROLES.includes('Inspector_global_leader')) return await dcyUniversalApproval(params);
438 if (USER_ROLES.includes('patrol_global')) return await qyUniversalApproval(params); 332 if (USER_ROLES.includes('patrol_global')) return await qyUniversalApproval(params);
439 - if (USER_ROLES.includes('AI_dispatcher')) return await aiUniversalApproval(params); 333 + if (USER_ROLES.includes('AI_dispatcher')) return await aiUniversalApproval(params);
440 // if (USER_ROLES.includes('AI_dispatcher')) return await aiUniversalApproval(params); 334 // if (USER_ROLES.includes('AI_dispatcher')) return await aiUniversalApproval(params);
441 throw new Error('未匹配到对应的审批接口,请检查角色或工单taskKey'); 335 throw new Error('未匹配到对应的审批接口,请检查角色或工单taskKey');
442 }; 336 };
@@ -447,7 +341,7 @@ const callApprovalApi = async (params: any, taskKey: string) =&gt; { @@ -447,7 +341,7 @@ const callApprovalApi = async (params: any, taskKey: string) =&gt; {
447 const navToOrderPage = (path: string, query = {}, events = {}) => { 341 const navToOrderPage = (path: string, query = {}, events = {}) => {
448 const queryStr = Object.keys(query).map(k => `${k}=${encodeURIComponent(query[k])}`).join('&'); 342 const queryStr = Object.keys(query).map(k => `${k}=${encodeURIComponent(query[k])}`).join('&');
449 const url = `${path}${queryStr ? '?' + queryStr : ''}`; 343 const url = `${path}${queryStr ? '?' + queryStr : ''}`;
450 - if(Object.keys(events).length) { 344 + if (Object.keys(events).length) {
451 uni.navigateTo({ url, events }); 345 uni.navigateTo({ url, events });
452 } else { 346 } else {
453 uni.redirectTo({ url }); 347 uni.redirectTo({ url });
@@ -461,8 +355,8 @@ const activeImgTab = ref(0); // 图片分类Tab激活索引 @@ -461,8 +355,8 @@ const activeImgTab = ref(0); // 图片分类Tab激活索引
461 355
462 // 顶部Tab列表 356 // 顶部Tab列表
463 const topTabList = ref([ 357 const topTabList = ref([
464 - {name: '工单详情'},  
465 - {name: '流程节点'} 358 + { name: '工单详情' },
  359 + { name: '流程节点' }
466 ]); 360 ]);
467 361
468 // 流程节点数据 362 // 流程节点数据
@@ -475,11 +369,11 @@ const processData = ref&lt;any&gt;({ @@ -475,11 +369,11 @@ const processData = ref&lt;any&gt;({
475 369
476 // 图片分类Tab列表 370 // 图片分类Tab列表
477 const imgTabList = ref([ 371 const imgTabList = ref([
478 - {name: '开始', badge: {isDot: true}},  
479 - {name: '进行中'},  
480 - {name: '结束', badge: {isDot: true}},  
481 - {name: '人员'},  
482 - {name: '材料'} 372 + { name: '开始', badge: { isDot: true } },
  373 + { name: '进行中' },
  374 + { name: '结束', badge: { isDot: true } },
  375 + { name: '人员' },
  376 + { name: '材料' }
483 ]); 377 ]);
484 378
485 // 工单详情数据 379 // 工单详情数据
@@ -537,7 +431,7 @@ const orderDetail = ref&lt;any&gt;({ @@ -537,7 +431,7 @@ const orderDetail = ref&lt;any&gt;({
537 431
538 const currentImgList = ref([]) 432 const currentImgList = ref([])
539 const tabKeyMap = ['startImgs', 'processingImgs', 'endImgs', 'personImgs', 'materialImgs']; 433 const tabKeyMap = ['startImgs', 'processingImgs', 'endImgs', 'personImgs', 'materialImgs'];
540 -const imgTabChange = (({index}: { index: number }) => { 434 +const imgTabChange = (({ index }: { index: number }) => {
541 const currentKey = tabKeyMap[index] 435 const currentKey = tabKeyMap[index]
542 currentImgList.value = orderDetail.value[currentKey] 436 currentImgList.value = orderDetail.value[currentKey]
543 }) 437 })
@@ -555,7 +449,7 @@ const getLimitReason = (reason: string | null | undefined) =&gt; { @@ -555,7 +449,7 @@ const getLimitReason = (reason: string | null | undefined) =&gt; {
555 * 动态获取当前步骤索引 449 * 动态获取当前步骤索引
556 */ 450 */
557 const getCurrentStepIndex = () => { 451 const getCurrentStepIndex = () => {
558 - const {activityNodes} = processData.value; 452 + const { activityNodes } = processData.value;
559 if (!activityNodes || !activityNodes.length) return 0; 453 if (!activityNodes || !activityNodes.length) return 0;
560 // return activityNodes.length - 1; 454 // return activityNodes.length - 1;
561 return activityNodes.length; 455 return activityNodes.length;
@@ -592,7 +486,7 @@ const showRejectButton = computed(() =&gt; { @@ -592,7 +486,7 @@ const showRejectButton = computed(() =&gt; {
592 486
593 /** 是否已配置统一动作(配置后按配置逐个渲染动作按钮) */ 487 /** 是否已配置统一动作(配置后按配置逐个渲染动作按钮) */
594 const hasConfiguredActions = computed(() => 488 const hasConfiguredActions = computed(() =>
595 - Array.isArray(configuredActions.value) && configuredActions.value.length > 0) 489 + Array.isArray(configuredActions.value) && configuredActions.value.length > 0)
596 490
597 /** 未配置统一动作时的按钮数量:主按钮 + 可选的回退/重新提交 */ 491 /** 未配置统一动作时的按钮数量:主按钮 + 可选的回退/重新提交 */
598 const legacyActionCount = computed(() => { 492 const legacyActionCount = computed(() => {
@@ -625,8 +519,8 @@ const unifiedActionsRef = ref&lt;any&gt;(null) @@ -625,8 +519,8 @@ const unifiedActionsRef = ref&lt;any&gt;(null)
625 /** 处理:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */ 519 /** 处理:已配置统一动作时直接执行点击的配置动作,否则回退原有处理 */
626 const handleUnifiedProcess = async (item: any, action: any = null) => { 520 const handleUnifiedProcess = async (item: any, action: any = null) => {
627 const actions = Array.isArray(configuredActions.value) 521 const actions = Array.isArray(configuredActions.value)
628 - ? configuredActions.value  
629 - : await queryUnifiedActions(item?.taskId) 522 + ? configuredActions.value
  523 + : await queryUnifiedActions(item?.taskId)
630 if (actions) { 524 if (actions) {
631 const target = action || actions[0] 525 const target = action || actions[0]
632 // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页; 526 // 实施动作要选作业类型、填动态字段、传五组照片,统一动作弹窗承载不了,进「作业填报」页;
@@ -644,11 +538,11 @@ const handleUnifiedProcess = async (item: any, action: any = null) =&gt; { @@ -644,11 +538,11 @@ const handleUnifiedProcess = async (item: any, action: any = null) =&gt; {
644 /** 回退:已配置统一动作时走统一接口,否则回退原有弹窗 */ 538 /** 回退:已配置统一动作时走统一接口,否则回退原有弹窗 */
645 const handleUnifiedReject = async (item: any) => { 539 const handleUnifiedReject = async (item: any) => {
646 const actions = Array.isArray(configuredActions.value) 540 const actions = Array.isArray(configuredActions.value)
647 - ? configuredActions.value  
648 - : await queryUnifiedActions(item?.taskId) 541 + ? configuredActions.value
  542 + : await queryUnifiedActions(item?.taskId)
649 if (actions) { 543 if (actions) {
650 const rejectActions = actions.filter((action: any) => 544 const rejectActions = actions.filter((action: any) =>
651 - REJECT_ACTION_CODES.includes(action.code) 545 + REJECT_ACTION_CODES.includes(action.code)
652 ) 546 )
653 if (rejectActions.length > 0) { 547 if (rejectActions.length > 0) {
654 unifiedActionsRef.value?.open(item, rejectActions) 548 unifiedActionsRef.value?.open(item, rejectActions)
@@ -681,13 +575,13 @@ const DetailQuery = async (taskIdStr: string) =&gt; { @@ -681,13 +575,13 @@ const DetailQuery = async (taskIdStr: string) =&gt; {
681 let res: any; 575 let res: any;
682 // 0-待办 1-已办 2-我发起的任务 576 // 0-待办 1-已办 2-我发起的任务
683 if (tabType === 0) { 577 if (tabType === 0) {
684 - res = await getTodoTaskDetail({taskId: taskIdStr}); 578 + res = await getTodoTaskDetail({ taskId: taskIdStr });
685 } else if (tabType === 2) { 579 } else if (tabType === 2) {
686 - res = await getMyTaskDetail({taskId: taskIdStr}); 580 + res = await getMyTaskDetail({ taskId: taskIdStr });
687 } else if (tabType === 1) { 581 } else if (tabType === 1) {
688 - res = await getDoneTaskDetail({taskId: taskIdStr}); 582 + res = await getDoneTaskDetail({ taskId: taskIdStr });
689 } else { 583 } else {
690 - uni.showToast({title: '无效的工单类型', icon: 'none'}); 584 + uni.showToast({ title: '无效的工单类型', icon: 'none' });
691 return; 585 return;
692 } 586 }
693 587
@@ -698,7 +592,7 @@ const DetailQuery = async (taskIdStr: string) =&gt; { @@ -698,7 +592,7 @@ const DetailQuery = async (taskIdStr: string) =&gt; {
698 } 592 }
699 } catch (error) { 593 } catch (error) {
700 console.error('获取工单详情失败:', error); 594 console.error('获取工单详情失败:', error);
701 - uni.showToast({title: '加载失败,请重试', icon: 'none'}); 595 + uni.showToast({ title: '加载失败,请重试', icon: 'none' });
702 } finally { 596 } finally {
703 loading.value = false; 597 loading.value = false;
704 } 598 }
@@ -770,8 +664,8 @@ const handleRenew = (item: any) =&gt; { @@ -770,8 +664,8 @@ const handleRenew = (item: any) =&gt; {
770 if (!tempKey) return; 664 if (!tempKey) return;
771 665
772 const pageUrl = USER_ROLES.includes('patrol_global') 666 const pageUrl = USER_ROLES.includes('patrol_global')
773 - ? '/pages-sub/problem/regional-order-manage/add-patrol-order'  
774 - : '/pages-sub/problem/regional-order-manage/add-order'; 667 + ? '/pages-sub/problem/regional-order-manage/add-patrol-order'
  668 + : '/pages-sub/problem/regional-order-manage/add-order';
775 669
776 navToOrderPage(pageUrl, { isRenew: 1, tempKey }); 670 navToOrderPage(pageUrl, { isRenew: 1, tempKey });
777 }; 671 };
@@ -801,7 +695,7 @@ const confirmReject = async () =&gt; { @@ -801,7 +695,7 @@ const confirmReject = async () =&gt; {
801 const item = currentRejectItem.value; 695 const item = currentRejectItem.value;
802 if (!item?.id) return showToast('工单信息异常'); 696 if (!item?.id) return showToast('工单信息异常');
803 697
804 - uni.showLoading({title: '提交中...', mask: true}); 698 + uni.showLoading({ title: '提交中...', mask: true });
805 try { 699 try {
806 const requestData = { 700 const requestData = {
807 "returnImgs": rejectImgs.getSuccessImgUrls(), 701 "returnImgs": rejectImgs.getSuccessImgUrls(),
@@ -831,7 +725,7 @@ const handleProcess = async (item: any) =&gt; { @@ -831,7 +725,7 @@ const handleProcess = async (item: any) =&gt; {
831 const stepName = nextStepMap[item.taskKey]?.name; 725 const stepName = nextStepMap[item.taskKey]?.name;
832 if (!stepName) return showToast('暂无处理权限或工单状态异常'); 726 if (!stepName) return showToast('暂无处理权限或工单状态异常');
833 727
834 - uni.showLoading({title: '处理中...', mask: true}); 728 + uni.showLoading({ title: '处理中...', mask: true });
835 try { 729 try {
836 // 大区经理分配 730 // 大区经理分配
837 if (stepName === '大区经理分配') { 731 if (stepName === '大区经理分配') {
@@ -851,10 +745,10 @@ const handleProcess = async (item: any) =&gt; { @@ -851,10 +745,10 @@ const handleProcess = async (item: any) =&gt; {
851 content: "请确定是否分配工单?", 745 content: "请确定是否分配工单?",
852 success: async (res) => { 746 success: async (res) => {
853 const postData = { 747 const postData = {
854 - taskKey: item.taskKey, taskId: item.taskId, operateType:60, workerDataId:item.id,  
855 - agree:0, reason:item.remark, roadId:item.roadId, roadName:item.roadName,  
856 - pressingType:item.pressingType, orderName:item.orderName,  
857 - expectedFinishDate: item.expectedFinishDate, busiLine:item.busiLine 748 + taskKey: item.taskKey, taskId: item.taskId, operateType: 60, workerDataId: item.id,
  749 + agree: 0, reason: item.remark, roadId: item.roadId, roadName: item.roadName,
  750 + pressingType: item.pressingType, orderName: item.orderName,
  751 + expectedFinishDate: item.expectedFinishDate, busiLine: item.busiLine
858 }; 752 };
859 await dcyUniversalApproval(postData); 753 await dcyUniversalApproval(postData);
860 showToast('分配成功', 'success'); 754 showToast('分配成功', 'success');
@@ -872,7 +766,7 @@ const handleProcess = async (item: any) =&gt; { @@ -872,7 +766,7 @@ const handleProcess = async (item: any) =&gt; {
872 content: "请确定是否分配工单?", 766 content: "请确定是否分配工单?",
873 success: async (res) => { 767 success: async (res) => {
874 if (res.confirm) { 768 if (res.confirm) {
875 - const postData = { taskKey: item.taskKey, taskId: item.taskId, operateType:40, workerDataId:item.id, agree:0, reason:item.remark, roadId:item.roadId, roadName:item.roadName, pressingType:item.pressingType, orderName:item.orderName, expectedFinishDate: item.expectedFinishDate, busiLine:item.busiLine }; 769 + const postData = { taskKey: item.taskKey, taskId: item.taskId, operateType: 40, workerDataId: item.id, agree: 0, reason: item.remark, roadId: item.roadId, roadName: item.roadName, pressingType: item.pressingType, orderName: item.orderName, expectedFinishDate: item.expectedFinishDate, busiLine: item.busiLine };
876 await aiUniversalApproval(postData); 770 await aiUniversalApproval(postData);
877 showToast('分配成功', 'success'); 771 showToast('分配成功', 'success');
878 eventChannel.value.emit('needRefresh'); 772 eventChannel.value.emit('needRefresh');
@@ -919,7 +813,7 @@ const handleProcess = async (item: any) =&gt; { @@ -919,7 +813,7 @@ const handleProcess = async (item: any) =&gt; {
919 operateType: 200, agree: 1, reason: 'AI工单派发人员结束工单' 813 operateType: 200, agree: 1, reason: 'AI工单派发人员结束工单'
920 }; 814 };
921 await callApprovalApi(requestData, item.taskKey); 815 await callApprovalApi(requestData, item.taskKey);
922 - uni.showToast({title: '结束成功', icon: 'success'}); 816 + uni.showToast({ title: '结束成功', icon: 'success' });
923 eventChannel.value.emit('needRefresh'); 817 eventChannel.value.emit('needRefresh');
924 uni.navigateBack({ delta: 1 }); 818 uni.navigateBack({ delta: 1 });
925 } 819 }
@@ -952,7 +846,7 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -952,7 +846,7 @@ const handleAcceptModalConfirm = async () =&gt; {
952 const item = currentAcceptItem.value; 846 const item = currentAcceptItem.value;
953 if (!item?.id) return showToast('工单信息异常'); 847 if (!item?.id) return showToast('工单信息异常');
954 848
955 - uni.showLoading({title: '提交中...', mask: true}); 849 + uni.showLoading({ title: '提交中...', mask: true });
956 try { 850 try {
957 let postData: any = {} 851 let postData: any = {}
958 if (item?.taskKey == 'ylTeamLeaderConfirm') { 852 if (item?.taskKey == 'ylTeamLeaderConfirm') {
@@ -980,7 +874,7 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -980,7 +874,7 @@ const handleAcceptModalConfirm = async () =&gt; {
980 showToast('提交成功', 'success'); 874 showToast('提交成功', 'success');
981 handleAcceptModalCancel(); 875 handleAcceptModalCancel();
982 eventChannel.value.emit('needRefresh'); 876 eventChannel.value.emit('needRefresh');
983 - uni.navigateBack({delta: 1}); 877 + uni.navigateBack({ delta: 1 });
984 } catch (error: any) { 878 } catch (error: any) {
985 console.error('验收失败:', error); 879 console.error('验收失败:', error);
986 showToast(error.msg || error.message || '验收提交失败,请重试'); 880 showToast(error.msg || error.message || '验收提交失败,请重试');
@@ -992,7 +886,7 @@ const handleAcceptModalConfirm = async () =&gt; { @@ -992,7 +886,7 @@ const handleAcceptModalConfirm = async () =&gt; {
992 // ========== 生命周期 ========== 886 // ========== 生命周期 ==========
993 onLoad((options: any) => { 887 onLoad((options: any) => {
994 console.log('页面入参:', options) 888 console.log('页面入参:', options)
995 - const {taskId: taskIdOpt, activeTab: activeTabOpt, processInstanceId: processInstanceIdOpt} = options; 889 + const { taskId: taskIdOpt, activeTab: activeTabOpt, processInstanceId: processInstanceIdOpt } = options;
996 taskId.value = taskIdOpt || ''; 890 taskId.value = taskIdOpt || '';
997 activeTab.value = activeTabOpt || '0'; 891 activeTab.value = activeTabOpt || '0';
998 processInstanceId.value = processInstanceIdOpt; 892 processInstanceId.value = processInstanceIdOpt;
@@ -1000,7 +894,7 @@ onLoad((options: any) =&gt; { @@ -1000,7 +894,7 @@ onLoad((options: any) =&gt; {
1000 DetailQuery(taskId.value); 894 DetailQuery(taskId.value);
1001 }); 895 });
1002 896
1003 -onShow(() => {}); 897 +onShow(() => { });
1004 </script> 898 </script>
1005 899
1006 <style scoped lang="scss"> 900 <style scoped lang="scss">
@@ -1017,8 +911,7 @@ onShow(() =&gt; {}); @@ -1017,8 +911,7 @@ onShow(() =&gt; {});
1017 } 911 }
1018 912
1019 // 顶部Tabs 913 // 顶部Tabs
1020 -.top-tabs {  
1021 -} 914 +.top-tabs {}
1022 915
1023 // Tab内容区:左右 24rpx 留白(设计稿 .body) 916 // Tab内容区:左右 24rpx 留白(设计稿 .body)
1024 .tab-content { 917 .tab-content {
@@ -1028,6 +921,7 @@ onShow(() =&gt; {}); @@ -1028,6 +921,7 @@ onShow(() =&gt; {});
1028 921
1029 // 工单详情内容 922 // 工单详情内容
1030 .detail-content { 923 .detail-content {
  924 +
1031 // 白色卡片:16rpx 圆角 + 卡片阴影(设计稿 .card) 925 // 白色卡片:16rpx 圆角 + 卡片阴影(设计稿 .card)
1032 .detail-cell-group { 926 .detail-cell-group {
1033 background-color: #ffffff; 927 background-color: #ffffff;
@@ -1037,8 +931,7 @@ onShow(() =&gt; {}); @@ -1037,8 +931,7 @@ onShow(() =&gt; {});
1037 overflow: hidden; 931 overflow: hidden;
1038 } 932 }
1039 933
1040 - .cell-content-wrap {  
1041 - } 934 + .cell-content-wrap {}
1042 935
1043 .empty-text { 936 .empty-text {
1044 color: #909399; 937 color: #909399;
@@ -1055,11 +948,10 @@ onShow(() =&gt; {}); @@ -1055,11 +948,10 @@ onShow(() =&gt; {});
1055 overflow: hidden; 948 overflow: hidden;
1056 949
1057 .img-tab-content { 950 .img-tab-content {
1058 - padding: 20rpx 15px ; 951 + padding: 20rpx 15px;
1059 text-align: center; 952 text-align: center;
1060 953
1061 - .img-album {  
1062 - } 954 + .img-album {}
1063 955
1064 .empty-img-text { 956 .empty-img-text {
1065 height: 75px; 957 height: 75px;
@@ -1126,8 +1018,7 @@ onShow(() =&gt; {}); @@ -1126,8 +1018,7 @@ onShow(() =&gt; {});
1126 .step-album-wrap { 1018 .step-album-wrap {
1127 padding: 10rpx 0; 1019 padding: 10rpx 0;
1128 1020
1129 - .step-album {  
1130 - } 1021 + .step-album {}
1131 1022
1132 .no-img-tip { 1023 .no-img-tip {
1133 font-size: 24rpx; 1024 font-size: 24rpx;
@@ -1186,6 +1077,7 @@ onShow(() =&gt; {}); @@ -1186,6 +1077,7 @@ onShow(() =&gt; {});
1186 .mt-30 { 1077 .mt-30 {
1187 margin-top: 30rpx; 1078 margin-top: 30rpx;
1188 } 1079 }
  1080 +
1189 // 针对 up-album 单图容器的样式 1081 // 针对 up-album 单图容器的样式
1190 :deep .u-album__row__wrapper image { 1082 :deep .u-album__row__wrapper image {
1191 width: 70px !important; 1083 width: 70px !important;