Commit 1f1f236ca4c36b6c01fa9a32556b45b0002fb726
1 parent
5059c4dd
工单详情
Showing
5 changed files
with
355 additions
and
96 deletions
api/work-order-manage/work-order-manage.js
| 1 | import { post, get, put } from '@/common/utils/request'; | 1 | import { post, get, put } from '@/common/utils/request'; |
| 2 | 2 | ||
| 3 | -// /app-api/bpm/garden/workorder/getApprovalDetail 获得审批详情 | ||
| 4 | 3 | ||
| 5 | 4 | ||
| 6 | // /app-api/bpm/garden/workorder/approve 验收通过调用此接口、巡查员结束工单也调用此接口 | 5 | // /app-api/bpm/garden/workorder/approve 验收通过调用此接口、巡查员结束工单也调用此接口 |
| @@ -8,6 +7,15 @@ import { post, get, put } from '@/common/utils/request'; | @@ -8,6 +7,15 @@ import { post, get, put } from '@/common/utils/request'; | ||
| 8 | 7 | ||
| 9 | 8 | ||
| 10 | /** | 9 | /** |
| 10 | + * 获得审批详情 流程节点 | ||
| 11 | + * @returns {Promise} | ||
| 12 | + */ | ||
| 13 | +export const getApprovalDetail = (params) => { | ||
| 14 | + return get('/app-api/bpm/garden/workorder/getApprovalDetail',params); | ||
| 15 | +}; | ||
| 16 | + | ||
| 17 | + | ||
| 18 | +/** | ||
| 11 | * 养护员工单实施页面提交接口 | 19 | * 养护员工单实施页面提交接口 |
| 12 | * @returns {Promise} | 20 | * @returns {Promise} |
| 13 | */ | 21 | */ |
common/utils/common.js
| @@ -18,4 +18,11 @@ export const nextStepMap = { | @@ -18,4 +18,11 @@ export const nextStepMap = { | ||
| 18 | operateTypeNoPass: 230, // 养护组长验收不通过:230 | 18 | operateTypeNoPass: 230, // 养护组长验收不通过:230 |
| 19 | backShow:false | 19 | backShow:false |
| 20 | }, | 20 | }, |
| 21 | + ylInspector:{ | ||
| 22 | + name: '巡查员验收', | ||
| 23 | + btnText:'验收', | ||
| 24 | + operateTypePass: 140, //巡查员验收通过: 140 | ||
| 25 | + operateTypeNoPass: 240, // 巡查员验收不通过:230 | ||
| 26 | + backShow:false | ||
| 27 | + } | ||
| 21 | } | 28 | } |
| 22 | \ No newline at end of file | 29 | \ No newline at end of file |
pages-sub/problem/work-order-manage/add-maintain-order.vue
| @@ -448,7 +448,7 @@ const submitWorkOrder = async () => { | @@ -448,7 +448,7 @@ const submitWorkOrder = async () => { | ||
| 448 | const submitData = { | 448 | const submitData = { |
| 449 | taskId: workOrderForm.taskId, | 449 | taskId: workOrderForm.taskId, |
| 450 | taskKey:'ylWorker', | 450 | taskKey:'ylWorker', |
| 451 | - operateType:nextStepMap['ylWorker'].operateType, | 451 | + operateType:nextStepMap['ylWorker'].operateTypePass, |
| 452 | workerDataId:Number(workOrderForm.workerDataId), | 452 | workerDataId:Number(workOrderForm.workerDataId), |
| 453 | // nextStepMap | 453 | // nextStepMap |
| 454 | handleResult: workOrderForm.reason.trim(), | 454 | handleResult: workOrderForm.reason.trim(), |
pages-sub/problem/work-order-manage/index.vue
| @@ -10,7 +10,6 @@ | @@ -10,7 +10,6 @@ | ||
| 10 | active-color="#1989fa" | 10 | active-color="#1989fa" |
| 11 | inactive-color="#666" | 11 | inactive-color="#666" |
| 12 | font-size="30rpx" | 12 | font-size="30rpx" |
| 13 | - | ||
| 14 | @click="handleTabChange" | 13 | @click="handleTabChange" |
| 15 | /> | 14 | /> |
| 16 | 15 | ||
| @@ -52,7 +51,6 @@ | @@ -52,7 +51,6 @@ | ||
| 52 | v-model="orderList" | 51 | v-model="orderList" |
| 53 | @query="queryList" | 52 | @query="queryList" |
| 54 | :auto-show-system-loading="true" | 53 | :auto-show-system-loading="true" |
| 55 | - | ||
| 56 | > | 54 | > |
| 57 | <template #empty> | 55 | <template #empty> |
| 58 | <empty-view/> | 56 | <empty-view/> |
| @@ -102,7 +100,9 @@ | @@ -102,7 +100,9 @@ | ||
| 102 | <up-button type="warning" size="mini" @click="handleReject(item)" | 100 | <up-button type="warning" size="mini" @click="handleReject(item)" |
| 103 | v-show="nextStepMap[item.taskKey].backShow">回退 | 101 | v-show="nextStepMap[item.taskKey].backShow">回退 |
| 104 | </up-button> | 102 | </up-button> |
| 105 | - <up-button type="primary" size="mini" @click="handleProcess(item)">{{ nextStepMap[item.taskKey].btnText }} | 103 | + <up-button type="primary" size="mini" @click="handleProcess(item)">{{ |
| 104 | + nextStepMap[item.taskKey].btnText | ||
| 105 | + }} | ||
| 106 | </up-button> | 106 | </up-button> |
| 107 | <up-button type="info" size="mini" @click="handleDetail(item)">详情</up-button> | 107 | <up-button type="info" size="mini" @click="handleDetail(item)">详情</up-button> |
| 108 | </view> | 108 | </view> |
| @@ -174,7 +174,7 @@ | @@ -174,7 +174,7 @@ | ||
| 174 | placeholder="请输入回退原因(必填)" | 174 | placeholder="请输入回退原因(必填)" |
| 175 | :required="true" | 175 | :required="true" |
| 176 | maxlength="-1" | 176 | maxlength="-1" |
| 177 | - rows="4" | 177 | + rows="6" |
| 178 | class="mt-20" | 178 | class="mt-20" |
| 179 | /> | 179 | /> |
| 180 | <view class="upload-wrap mt-20"> | 180 | <view class="upload-wrap mt-20"> |
| @@ -194,6 +194,41 @@ | @@ -194,6 +194,41 @@ | ||
| 194 | </view> | 194 | </view> |
| 195 | </view> | 195 | </view> |
| 196 | </up-popup> | 196 | </up-popup> |
| 197 | + | ||
| 198 | + <!-- 新增:养护组长验收弹窗 up-modal --> | ||
| 199 | + <up-modal | ||
| 200 | + :show="acceptModalShow" | ||
| 201 | + title="验收" | ||
| 202 | + :closeOnClickOverlay="false" | ||
| 203 | + :showConfirmButton="true" | ||
| 204 | + :showCancelButton="true" | ||
| 205 | + @cancel="acceptModalShow=false" | ||
| 206 | + @confirm="handleAcceptModalConfirm" | ||
| 207 | + > | ||
| 208 | + <view class="accept-modal-content"> | ||
| 209 | + <!-- 第一行:单选框(通过/不通过,默认通过) --> | ||
| 210 | + <view class="radio-group-wrap"> | ||
| 211 | + <up-radio-group v-model="acceptRadioValue"> | ||
| 212 | + <up-radio name="0" label="通过"></up-radio> | ||
| 213 | + <up-radio name="1" label="不通过"></up-radio> | ||
| 214 | + </up-radio-group> | ||
| 215 | + </view> | ||
| 216 | + | ||
| 217 | + <!-- 第二行:必填textarea,最多200字 --> | ||
| 218 | + <view class="textarea-wrap mt-30"> | ||
| 219 | + <up-textarea | ||
| 220 | + v-model.trim="acceptReason" | ||
| 221 | + placeholder="请输入验收原因(必填,最多200字)" | ||
| 222 | + :required="true" | ||
| 223 | + maxlength="200" | ||
| 224 | + rows="5" | ||
| 225 | + count | ||
| 226 | + /> | ||
| 227 | + </view> | ||
| 228 | + | ||
| 229 | + | ||
| 230 | + </view> | ||
| 231 | + </up-modal> | ||
| 197 | </view> | 232 | </view> |
| 198 | </template> | 233 | </template> |
| 199 | 234 | ||
| @@ -201,7 +236,12 @@ | @@ -201,7 +236,12 @@ | ||
| 201 | import { ref, computed } from 'vue'; | 236 | import { ref, computed } from 'vue'; |
| 202 | import { onReady, onShow } from '@dcloudio/uni-app'; | 237 | import { onReady, onShow } from '@dcloudio/uni-app'; |
| 203 | import { timeFormat } from '@/uni_modules/uview-plus'; | 238 | import { timeFormat } from '@/uni_modules/uview-plus'; |
| 204 | -import { myBuzSimplePage, todoBuzSimplePage, doneBuzSimplePage } from '@/api/work-order-manage/work-order-manage' | 239 | +import { |
| 240 | + myBuzSimplePage, | ||
| 241 | + todoBuzSimplePage, | ||
| 242 | + doneBuzSimplePage, | ||
| 243 | + universalApproval | ||
| 244 | +} from '@/api/work-order-manage/work-order-manage' | ||
| 205 | // 假设从用户store获取角色信息 | 245 | // 假设从用户store获取角色信息 |
| 206 | import { useUserStore } from '@/pinia/user'; | 246 | import { useUserStore } from '@/pinia/user'; |
| 207 | import { nextStepMap } from '@/common/utils/common' | 247 | import { nextStepMap } from '@/common/utils/common' |
| @@ -239,6 +279,11 @@ const rejectFileList = ref([]); | @@ -239,6 +279,11 @@ const rejectFileList = ref([]); | ||
| 239 | const currentRejectItem = ref(null); | 279 | const currentRejectItem = ref(null); |
| 240 | // 上传地址(根据实际接口配置) | 280 | // 上传地址(根据实际接口配置) |
| 241 | const uploadUrl = ref('https://xxx.com/upload'); | 281 | const uploadUrl = ref('https://xxx.com/upload'); |
| 282 | +// ========== 新增:养护组长验收弹窗相关状态 ========== | ||
| 283 | +const acceptModalShow = ref(false); // 验收弹窗显示开关 | ||
| 284 | +const acceptRadioValue = ref('0'); // 单选框值,默认0(通过) | ||
| 285 | +const acceptReason = ref(''); // 验收原因 | ||
| 286 | +const currentAcceptItem = ref(null); // 当前验收的工单项 | ||
| 242 | // 分页查询列表 | 287 | // 分页查询列表 |
| 243 | const queryList = async (pageNo, pageSize) => { | 288 | const queryList = async (pageNo, pageSize) => { |
| 244 | try { | 289 | try { |
| @@ -289,12 +334,12 @@ const handleSearch = (val) => { | @@ -289,12 +334,12 @@ const handleSearch = (val) => { | ||
| 289 | const handleDetail = (item) => { | 334 | const handleDetail = (item) => { |
| 290 | // 0-待办 1我发起的- 2-已办 | 335 | // 0-待办 1我发起的- 2-已办 |
| 291 | uni.navigateTo({ | 336 | uni.navigateTo({ |
| 292 | - url: `/pages-sub/problem/work-order-manage/order-detail?taskId=${item.taskId}&activeTab=${activeTab.value}` | 337 | + url: `/pages-sub/problem/work-order-manage/order-detail?taskId=${item.taskId}&activeTab=${activeTab.value}&processInstanceId=${item.processInstanceId}` |
| 293 | }); | 338 | }); |
| 294 | }; | 339 | }; |
| 295 | // 待办-处理工单 | 340 | // 待办-处理工单 |
| 296 | const handleProcess = async (item) => { | 341 | const handleProcess = async (item) => { |
| 297 | - console.log(nextStepMap) | 342 | + console.log(nextStepMap[item.taskKey].name) |
| 298 | try { | 343 | try { |
| 299 | if (nextStepMap[item.taskKey].name == '养护组长分配') { | 344 | if (nextStepMap[item.taskKey].name == '养护组长分配') { |
| 300 | uni.navigateTo({ | 345 | uni.navigateTo({ |
| @@ -306,6 +351,24 @@ const handleProcess = async (item) => { | @@ -306,6 +351,24 @@ const handleProcess = async (item) => { | ||
| 306 | url: `/pages-sub/problem/work-order-manage/add-maintain-order?taskId=${item.taskId}&id=${item.id}&orderNo=${item.orderNo}` | 351 | url: `/pages-sub/problem/work-order-manage/add-maintain-order?taskId=${item.taskId}&id=${item.id}&orderNo=${item.orderNo}` |
| 307 | }) | 352 | }) |
| 308 | } | 353 | } |
| 354 | + // 养护组长验收 - 打开弹窗 | ||
| 355 | + if (nextStepMap[item.taskKey].name == '养护组长验收') { | ||
| 356 | + console.log('123') | ||
| 357 | + currentAcceptItem.value = item; // 存储当前工单信息 | ||
| 358 | + acceptReason.value = ''; // 清空上次的验收原因 | ||
| 359 | + acceptRadioValue.value = '0'; // 重置默认选中“通过” | ||
| 360 | + acceptModalShow.value = true; // 显示验收弹窗 | ||
| 361 | + } | ||
| 362 | + | ||
| 363 | + // 巡查员验收 - 打开弹窗 | ||
| 364 | + if (nextStepMap[item.taskKey].name == '巡查员验收') { | ||
| 365 | + console.log('456') | ||
| 366 | + currentAcceptItem.value = item; // 存储当前工单信息 | ||
| 367 | + acceptReason.value = ''; // 清空上次的验收原因 | ||
| 368 | + acceptRadioValue.value = '0'; // 重置默认选中“通过” | ||
| 369 | + acceptModalShow.value = true; // 显示验收弹窗 | ||
| 370 | + } | ||
| 371 | + | ||
| 309 | } catch (error) { | 372 | } catch (error) { |
| 310 | console.error('处理工单失败:', error); | 373 | console.error('处理工单失败:', error); |
| 311 | uni.showToast({title: '处理失败,请重试', icon: 'none'}); | 374 | uni.showToast({title: '处理失败,请重试', icon: 'none'}); |
| @@ -357,6 +420,58 @@ const handleAfterRead = (file) => { | @@ -357,6 +420,58 @@ const handleAfterRead = (file) => { | ||
| 357 | const handleDeleteFile = (index) => { | 420 | const handleDeleteFile = (index) => { |
| 358 | rejectFileList.value.splice(index, 1); | 421 | rejectFileList.value.splice(index, 1); |
| 359 | }; | 422 | }; |
| 423 | +// ========== 新增:养护组长验收弹窗事件 ========== | ||
| 424 | +// 验收弹窗 - 取消按钮 | ||
| 425 | +const handleAcceptModalCancel = () => { | ||
| 426 | + acceptModalShow.value = false; | ||
| 427 | + acceptReason.value = ''; // 清空验收原因 | ||
| 428 | +}; | ||
| 429 | +// 验收弹窗 - 确定按钮(含表单校验) | ||
| 430 | +const handleAcceptModalConfirm = async () => { | ||
| 431 | + // 1. 校验验收原因是否为空 | ||
| 432 | + if (!acceptReason.value.trim()) { | ||
| 433 | + uni.showToast({title: '请填写验收原因', icon: 'none', duration: 2000}); | ||
| 434 | + return; | ||
| 435 | + } | ||
| 436 | + // 2. 校验验收原因长度(虽textarea已限制maxlength,此处做兜底校验) | ||
| 437 | + if (acceptReason.value.length > 200) { | ||
| 438 | + uni.showToast({title: '验收原因最多200字', icon: 'none', duration: 2000}); | ||
| 439 | + return; | ||
| 440 | + } | ||
| 441 | + try { | ||
| 442 | + // 3. 调用验收接口 | ||
| 443 | + console.log(currentAcceptItem.value) | ||
| 444 | + let postData = {} | ||
| 445 | + if(currentAcceptItem.value.taskKey == 'ylTeamLeaderConfirm'){ // 养护组长验收 | ||
| 446 | + postData = { | ||
| 447 | + "taskKey": "ylTeamLeaderConfirm", | ||
| 448 | + "taskId": currentAcceptItem.value.taskId, | ||
| 449 | + "operateType": acceptRadioValue.value == 0 ? nextStepMap['ylTeamLeaderConfirm'].operateTypePass : nextStepMap['ylTeamLeaderConfirm'].operateTypeNoPass, | ||
| 450 | + "reason": acceptReason.value.trim() | ||
| 451 | + } | ||
| 452 | + } | ||
| 453 | + if(currentAcceptItem.value.taskKey == 'ylInspector'){ // 巡查员验收 | ||
| 454 | + postData = { | ||
| 455 | + "taskKey": "ylTeamLeaderConfirm", | ||
| 456 | + "taskId": currentAcceptItem.value.taskId, | ||
| 457 | + "operateType": acceptRadioValue.value == 0 ? nextStepMap['ylTeamLeaderConfirm'].operateTypePass : nextStepMap['ylTeamLeaderConfirm'].operateTypeNoPass, | ||
| 458 | + "reason": acceptReason.value.trim(), | ||
| 459 | + "agree":acceptRadioValue.value | ||
| 460 | + } | ||
| 461 | + } | ||
| 462 | + | ||
| 463 | + const acceptRes = await universalApproval(postData); | ||
| 464 | + // 4. 操作成功处理 | ||
| 465 | + uni.showToast({title: '提交成功', icon: 'success', duration: 1500}); | ||
| 466 | + acceptModalShow.value = false; | ||
| 467 | + acceptReason.value = ''; // 清空验收原因 | ||
| 468 | + paging.value?.reload(); // 刷新工单列表 | ||
| 469 | + } catch (error) { | ||
| 470 | + // 5. 操作失败处理 | ||
| 471 | + console.error('养护组长验收失败:', error); | ||
| 472 | + uni.showToast({title: '验收提交失败,请重试', icon: 'none', duration: 2000}); | ||
| 473 | + } | ||
| 474 | +}; | ||
| 360 | // 页面初始化 | 475 | // 页面初始化 |
| 361 | onShow(() => { | 476 | onShow(() => { |
| 362 | // 初始化加载列表 | 477 | // 初始化加载列表 |
| @@ -401,5 +516,28 @@ onShow(() => { | @@ -401,5 +516,28 @@ onShow(() => { | ||
| 401 | } | 516 | } |
| 402 | } | 517 | } |
| 403 | 518 | ||
| 519 | +// 新增:养护组长验收弹窗样式 | ||
| 520 | +.accept-modal-content { | ||
| 521 | + width: 100%; | ||
| 522 | + box-sizing: border-box; | ||
| 523 | +} | ||
| 524 | + | ||
| 525 | +.radio-group-wrap { | ||
| 526 | + display: flex; | ||
| 527 | + align-items: center; | ||
| 528 | + gap: 40rpx; // 单选框之间的间距 | ||
| 529 | + font-size: 28rpx; | ||
| 530 | + margin-bottom: 20rpx; | ||
| 531 | +} | ||
| 532 | + | ||
| 533 | +.textarea-wrap { | ||
| 534 | + width: 100%; | ||
| 535 | +} | ||
| 404 | 536 | ||
| 537 | +.modal-btn-wrap { | ||
| 538 | + display: flex; | ||
| 539 | + align-items: center; | ||
| 540 | + justify-content: flex-end; | ||
| 541 | + padding-right: 10rpx; | ||
| 542 | +} | ||
| 405 | </style> | 543 | </style> |
| 406 | \ No newline at end of file | 544 | \ No newline at end of file |
pages-sub/problem/work-order-manage/order-detail.vue
| @@ -26,31 +26,33 @@ | @@ -26,31 +26,33 @@ | ||
| 26 | <view class="tab-content"> | 26 | <view class="tab-content"> |
| 27 | <!-- 1. 工单详情Tab --> | 27 | <!-- 1. 工单详情Tab --> |
| 28 | <view v-show="activeTopTab == 0" class="detail-content"> | 28 | <view v-show="activeTopTab == 0" class="detail-content"> |
| 29 | - <up-cell-group :border="false" class="detail-cell-group"> | 29 | + <up-cell-group :border="false" class="detail-cell-group"> |
| 30 | <!-- 工单编号 --> | 30 | <!-- 工单编号 --> |
| 31 | <up-cell title="工单编号" :value="orderDetail.orderNo || '--'" align="middle"></up-cell> | 31 | <up-cell title="工单编号" :value="orderDetail.orderNo || '--'" align="middle"></up-cell> |
| 32 | - <!-- 工单位置 --> | ||
| 33 | - | ||
| 34 | - <up-cell align="middle"> | ||
| 35 | 32 | ||
| 33 | + <!-- 工单位置 --> | ||
| 34 | + <up-cell align="middle"> | ||
| 36 | <template #title> | 35 | <template #title> |
| 37 | - <view style="min-width: 200rpx">工单位置</view> | 36 | + <view style="min-width: 200rpx">工单位置</view> |
| 38 | </template> | 37 | </template> |
| 39 | <template #value> | 38 | <template #value> |
| 40 | <view class="common-text-color up-line-1">{{ orderDetail.roadName || '--' }}</view> | 39 | <view class="common-text-color up-line-1">{{ orderDetail.roadName || '--' }}</view> |
| 41 | </template> | 40 | </template> |
| 42 | </up-cell> | 41 | </up-cell> |
| 42 | + | ||
| 43 | <!-- 工单名称 --> | 43 | <!-- 工单名称 --> |
| 44 | <up-cell title="工单名称" :value="orderDetail.orderName || '--'" align="middle"></up-cell> | 44 | <up-cell title="工单名称" :value="orderDetail.orderName || '--'" align="middle"></up-cell> |
| 45 | + | ||
| 45 | <!-- 情况描述 --> | 46 | <!-- 情况描述 --> |
| 46 | - <up-cell > | 47 | + <up-cell> |
| 47 | <template #title> | 48 | <template #title> |
| 48 | - <view style="min-width: 200rpx">情况描述</view> | 49 | + <view style="min-width: 200rpx">情况描述</view> |
| 49 | </template> | 50 | </template> |
| 50 | <template #value> | 51 | <template #value> |
| 51 | <view class="common-text-color up-line-1">{{ orderDetail.remark || '--' }}</view> | 52 | <view class="common-text-color up-line-1">{{ orderDetail.remark || '--' }}</view> |
| 52 | </template> | 53 | </template> |
| 53 | </up-cell> | 54 | </up-cell> |
| 55 | + | ||
| 54 | <!-- 紧急程度 --> | 56 | <!-- 紧急程度 --> |
| 55 | <up-cell | 57 | <up-cell |
| 56 | title="紧急程度" | 58 | title="紧急程度" |
| @@ -58,6 +60,29 @@ | @@ -58,6 +60,29 @@ | ||
| 58 | align="middle" | 60 | align="middle" |
| 59 | ></up-cell> | 61 | ></up-cell> |
| 60 | 62 | ||
| 63 | + <!-- 提交人 --> | ||
| 64 | + <up-cell title="提交人" :value="orderDetail.userName || '--'" align="middle"></up-cell> | ||
| 65 | + | ||
| 66 | + <!-- 提交时间 --> | ||
| 67 | + <up-cell | ||
| 68 | + title="提交时间" | ||
| 69 | + :value="timeFormat(orderDetail.createTime, 'yyyy-mm-dd hh:MM:ss') || '--'" | ||
| 70 | + align="middle" | ||
| 71 | + ></up-cell> | ||
| 72 | + | ||
| 73 | + <!-- 处理结果 --> | ||
| 74 | + <up-cell> | ||
| 75 | + <template #title> | ||
| 76 | + <view style="min-width: 200rpx">处理结果</view> | ||
| 77 | + </template> | ||
| 78 | + <template #value> | ||
| 79 | + <view class="common-text-color up-line-1">{{ orderDetail.handleResult || '--' }}</view> | ||
| 80 | + </template> | ||
| 81 | + </up-cell> | ||
| 82 | + | ||
| 83 | + <!-- 街道名称 --> | ||
| 84 | + <up-cell title="街道名称" :value="orderDetail.streetName || '--'" align="middle"></up-cell> | ||
| 85 | + | ||
| 61 | <!-- 问题照片 --> | 86 | <!-- 问题照片 --> |
| 62 | <up-cell title="问题照片"> | 87 | <up-cell title="问题照片"> |
| 63 | <template #value> | 88 | <template #value> |
| @@ -72,48 +97,49 @@ | @@ -72,48 +97,49 @@ | ||
| 72 | </view> | 97 | </view> |
| 73 | </template> | 98 | </template> |
| 74 | </up-cell> | 99 | </up-cell> |
| 100 | + | ||
| 75 | <!-- 希望完成时间 --> | 101 | <!-- 希望完成时间 --> |
| 76 | <up-cell | 102 | <up-cell |
| 77 | title="希望完成时间" | 103 | title="希望完成时间" |
| 78 | - :value="timeFormat(orderDetail.finishDate, 'yyyy-mm-dd hh:MM:ss') || '--'" | 104 | + :value="orderDetail.finishDate === 0 ? '未设置' : timeFormat(orderDetail.finishDate, 'yyyy-mm-dd hh:MM:ss')" |
| 79 | align="middle" | 105 | align="middle" |
| 80 | :border="false" | 106 | :border="false" |
| 81 | ></up-cell> | 107 | ></up-cell> |
| 82 | </up-cell-group> | 108 | </up-cell-group> |
| 83 | 109 | ||
| 84 | - | ||
| 85 | <!-- 图片分类Tabs区块 --> | 110 | <!-- 图片分类Tabs区块 --> |
| 86 | -<!-- <view class="img-tabs-block">--> | ||
| 87 | -<!-- <up-tabs--> | ||
| 88 | -<!-- v-model="activeImgTab"--> | ||
| 89 | -<!-- :list="imgTabList"--> | ||
| 90 | -<!-- :scrollable="false"--> | ||
| 91 | -<!-- active-color="#3c9cff"--> | ||
| 92 | -<!-- inactive-color="#666"--> | ||
| 93 | -<!-- class="img-tabs"--> | ||
| 94 | -<!-- ></up-tabs>--> | ||
| 95 | - | ||
| 96 | -<!-- <!– 图片Tab内容区 –>--> | ||
| 97 | -<!-- <view class="img-tab-content">--> | ||
| 98 | -<!-- <up-album--> | ||
| 99 | -<!-- v-if="getCurrentImgList().length"--> | ||
| 100 | -<!-- :urls="getCurrentImgList().slice(0, 3)"--> | ||
| 101 | -<!-- singleSize="100"--> | ||
| 102 | -<!-- :preview-full-image="true"--> | ||
| 103 | -<!-- class="img-album"--> | ||
| 104 | -<!-- ></up-album>--> | ||
| 105 | -<!-- <text v-else class="empty-img-text">暂无{{ imgTabList[activeImgTab].name }}图片</text>--> | ||
| 106 | -<!-- </view>--> | ||
| 107 | -<!-- </view>--> | 111 | + <view class="img-tabs-block"> |
| 112 | + <up-tabs | ||
| 113 | + @change = 'imgTabChange' | ||
| 114 | + v-model="activeImgTab" | ||
| 115 | + :list="imgTabList" | ||
| 116 | + :scrollable="false" | ||
| 117 | + active-color="#3c9cff" | ||
| 118 | + inactive-color="#666" | ||
| 119 | + class="img-tabs" | ||
| 120 | + ></up-tabs> | ||
| 121 | + | ||
| 122 | + <!-- 图片Tab内容区 --> | ||
| 123 | + <view class="img-tab-content"> | ||
| 124 | + <up-album | ||
| 125 | + v-if="currentImgList.length" | ||
| 126 | + :urls="currentImgList.slice(0, 3)" | ||
| 127 | + singleSize="80" | ||
| 128 | + multipleSize="80" | ||
| 129 | + :preview-full-image="true" | ||
| 130 | + class="img-album" | ||
| 131 | + ></up-album> | ||
| 132 | + <text v-else class="empty-img-text">暂无图片</text> | ||
| 133 | + </view> | ||
| 134 | + </view> | ||
| 108 | </view> | 135 | </view> |
| 109 | 136 | ||
| 110 | <!-- 2. 流程节点Tab --> | 137 | <!-- 2. 流程节点Tab --> |
| 111 | <view v-show="activeTopTab == 1" class="process-content"> | 138 | <view v-show="activeTopTab == 1" class="process-content"> |
| 112 | - <up-empty | ||
| 113 | - mode="data" | ||
| 114 | - | ||
| 115 | - ></up-empty> | ||
| 116 | - <!-- 可根据实际需求补充流程节点展示逻辑 --> | 139 | +<!-- <up-empty--> |
| 140 | +<!-- mode="data"--> | ||
| 141 | +<!-- ></up-empty>--> | ||
| 142 | +<!-- <!– 可根据实际需求补充流程节点展示逻辑 –>--> | ||
| 117 | </view> | 143 | </view> |
| 118 | </view> | 144 | </view> |
| 119 | </view> | 145 | </view> |
| @@ -124,7 +150,7 @@ | @@ -124,7 +150,7 @@ | ||
| 124 | import { ref, computed } from 'vue'; | 150 | import { ref, computed } from 'vue'; |
| 125 | import { onLoad, onShow } from '@dcloudio/uni-app'; | 151 | import { onLoad, onShow } from '@dcloudio/uni-app'; |
| 126 | import { timeFormat } from '@/uni_modules/uview-plus'; | 152 | import { timeFormat } from '@/uni_modules/uview-plus'; |
| 127 | -import { getMyTaskDetail, getDoneTaskDetail, getTodoTaskDetail } from '@/api/work-order-manage/work-order-manage'; | 153 | +import { getMyTaskDetail, getDoneTaskDetail, getTodoTaskDetail, getApprovalDetail } from '@/api/work-order-manage/work-order-manage'; |
| 128 | 154 | ||
| 129 | // 状态管理 | 155 | // 状态管理 |
| 130 | const loading = ref(true); | 156 | const loading = ref(true); |
| @@ -137,9 +163,16 @@ const topTabList = ref([ | @@ -137,9 +163,16 @@ const topTabList = ref([ | ||
| 137 | { name: '流程节点' } | 163 | { name: '流程节点' } |
| 138 | ]); | 164 | ]); |
| 139 | 165 | ||
| 140 | -const activeTopTabClick = (item)=>{ | 166 | +const activeTopTabClick = async (item: any) => { |
| 141 | console.log(item) | 167 | console.log(item) |
| 142 | activeTopTab.value = item.index | 168 | activeTopTab.value = item.index |
| 169 | + if(activeTopTab.value ==1){ | ||
| 170 | + let getData = { | ||
| 171 | + processInstanceId:processInstanceId.value, | ||
| 172 | + } | ||
| 173 | + const res = await getApprovalDetail(getData) | ||
| 174 | + console.log(res) | ||
| 175 | + } | ||
| 143 | } | 176 | } |
| 144 | 177 | ||
| 145 | // 图片分类Tab列表(带角标配置) | 178 | // 图片分类Tab列表(带角标配置) |
| @@ -151,42 +184,100 @@ const imgTabList = ref([ | @@ -151,42 +184,100 @@ const imgTabList = ref([ | ||
| 151 | { name: '材料' } | 184 | { name: '材料' } |
| 152 | ]); | 185 | ]); |
| 153 | 186 | ||
| 154 | -// 工单详情数据 | ||
| 155 | -const orderDetail = ref({}); | 187 | +// 工单详情数据(初始化赋值,可被接口数据覆盖) |
| 188 | +const orderDetail = ref<any>({ | ||
| 189 | + id: 0, | ||
| 190 | + busiLine: '', | ||
| 191 | + orderNo: '', | ||
| 192 | + orderName: '', | ||
| 193 | + sourceId: 0, | ||
| 194 | + sourceName: '', | ||
| 195 | + roadId: 0, | ||
| 196 | + roadName: '', | ||
| 197 | + streetId: '', | ||
| 198 | + streetName: '', | ||
| 199 | + curingLevelId: 0, | ||
| 200 | + curingLevelName: '', | ||
| 201 | + commitDate: 0, | ||
| 202 | + finishDate: 0, | ||
| 203 | + pressingType: 0, | ||
| 204 | + userId: 0, | ||
| 205 | + userName: '', | ||
| 206 | + companyId: 0, | ||
| 207 | + latLonType: 0, | ||
| 208 | + lat: 0, | ||
| 209 | + lon: 0, | ||
| 210 | + lonLatAddress: '', | ||
| 211 | + thirdWorkNo: '', | ||
| 212 | + thirdPushState: 0, | ||
| 213 | + buzStatus: null, | ||
| 214 | + status: 0, | ||
| 215 | + processInstanceId: '', | ||
| 216 | + remark: '', | ||
| 217 | + handleResult: '', | ||
| 218 | + createTime: 0, | ||
| 219 | + fileNames: null, | ||
| 220 | + coHandlers: null, | ||
| 221 | + coHandlersName: null, | ||
| 222 | + companyName: null, | ||
| 223 | + userMobile: null, | ||
| 224 | + taskId: '', | ||
| 225 | + taskName: '', | ||
| 226 | + taskKey: '', | ||
| 227 | + processDefinitionName: '', | ||
| 228 | + startTime: 0, | ||
| 229 | + endTime: 0, | ||
| 230 | + key_: '', | ||
| 231 | + problemsImgs: [], | ||
| 232 | + startImgs: [], | ||
| 233 | + processingImgs: [], | ||
| 234 | + endImgs: [], | ||
| 235 | + personImgs: [], | ||
| 236 | + materialImgs: [] | ||
| 237 | +}); | ||
| 156 | 238 | ||
| 157 | /** | 239 | /** |
| 158 | - * 获取当前激活的图片列表 | 240 | + * 当前激活的图片列表(无需函数调用,直接访问) |
| 159 | */ | 241 | */ |
| 160 | -const getCurrentImgList = computed(() => { | ||
| 161 | - const tabKeyMap = ['startImgs', 'processingImgs', 'endImgs', 'personImgs', 'materialImgs']; | ||
| 162 | - return orderDetail[tabKeyMap[activeImgTab.value]] || []; | ||
| 163 | -}); | 242 | +const currentImgList = ref([]) |
| 243 | + | ||
| 244 | +const tabKeyMap = ['startImgs', 'processingImgs', 'endImgs', 'personImgs', 'materialImgs']; | ||
| 245 | +const imgTabChange = (({index})=>{ | ||
| 246 | + console.log(index) | ||
| 247 | + const currentKey = tabKeyMap[index] | ||
| 248 | + console.log(currentKey) | ||
| 249 | + console.log(orderDetail.value[currentKey]) | ||
| 250 | + currentImgList.value = orderDetail.value[currentKey] | ||
| 251 | +}) | ||
| 252 | + | ||
| 164 | 253 | ||
| 165 | /** | 254 | /** |
| 166 | * 获取工单详情 | 255 | * 获取工单详情 |
| 167 | */ | 256 | */ |
| 168 | -const DetailQuery = async (taskIdStr) => { | ||
| 169 | - console.log(taskIdStr) | 257 | +const DetailQuery = async (taskIdStr: string) => { |
| 258 | + console.log('当前工单ID:', taskIdStr) | ||
| 170 | try { | 259 | try { |
| 171 | loading.value = true; | 260 | loading.value = true; |
| 172 | - if(activeTab.value==0){ | ||
| 173 | - | ||
| 174 | - const res = await getTodoTaskDetail({ taskId:taskIdStr }); | ||
| 175 | - orderDetail.value = res | 261 | + // 转换activeTab为数字类型,避免类型不一致导致接口调用失败 |
| 262 | + const tabType = Number(activeTab.value); | ||
| 263 | + let res: any; | ||
| 264 | + | ||
| 265 | + if (tabType === 0) { | ||
| 266 | + res = await getTodoTaskDetail({ taskId: taskIdStr }); | ||
| 267 | + } else if (tabType === 1) { | ||
| 268 | + res = await getMyTaskDetail({ taskId: taskIdStr }); | ||
| 269 | + } else if (tabType === 2) { | ||
| 270 | + res = await getDoneTaskDetail({ taskId: taskIdStr }); | ||
| 271 | + } else { | ||
| 272 | + uni.showToast({ title: '无效的工单类型', icon: 'none' }); | ||
| 273 | + return; | ||
| 176 | } | 274 | } |
| 177 | - if(activeTab.value==1){ | ||
| 178 | - | ||
| 179 | - const res = await getMyTaskDetail({ taskId: taskIdStr }); | ||
| 180 | - orderDetail.value = res | ||
| 181 | 275 | ||
| 276 | + // 覆盖工单详情数据 | ||
| 277 | + if (res) { | ||
| 278 | + orderDetail.value = res; | ||
| 279 | + currentImgList.value = orderDetail.value.startImgs | ||
| 182 | } | 280 | } |
| 183 | - if(activeTab.value==2){ | ||
| 184 | - | ||
| 185 | - const res = await getDoneTaskDetail({ taskId: taskIdStr }); | ||
| 186 | - orderDetail.value = res | ||
| 187 | - } | ||
| 188 | - | ||
| 189 | - | ||
| 190 | } catch (error) { | 281 | } catch (error) { |
| 191 | console.error('获取工单详情失败:', error); | 282 | console.error('获取工单详情失败:', error); |
| 192 | uni.showToast({ title: '加载失败,请重试', icon: 'none' }); | 283 | uni.showToast({ title: '加载失败,请重试', icon: 'none' }); |
| @@ -195,28 +286,33 @@ const DetailQuery = async (taskIdStr) => { | @@ -195,28 +286,33 @@ const DetailQuery = async (taskIdStr) => { | ||
| 195 | } | 286 | } |
| 196 | }; | 287 | }; |
| 197 | 288 | ||
| 198 | -// 页面加载 | 289 | +// 页面加载参数 |
| 199 | const taskId = ref('') | 290 | const taskId = ref('') |
| 200 | const activeTab = ref('') | 291 | const activeTab = ref('') |
| 201 | -onLoad((options) => { | ||
| 202 | - console.log(options) | ||
| 203 | - const { taskId: taskIdOpt, activeTab: activeTabOpt } = options; | ||
| 204 | - // 0-待办 1我发起的- 2-已办 | ||
| 205 | - console.log(taskIdOpt) | ||
| 206 | - taskId.value = taskIdOpt | ||
| 207 | - activeTab.value = activeTabOpt | 292 | +const processInstanceId = ref('') |
| 293 | +onLoad((options: any) => { | ||
| 294 | + console.log('页面入参:', options) | ||
| 295 | + const { taskId: taskIdOpt, activeTab: activeTabOpt, processInstanceId:processInstanceIdOpt } = options; | ||
| 296 | + // 0-待办 1-我发起的 2-已办 | ||
| 297 | + taskId.value = taskIdOpt || ''; | ||
| 298 | + activeTab.value = activeTabOpt || '0'; | ||
| 299 | + processInstanceId.value = processInstanceIdOpt ; | ||
| 300 | +}); | ||
| 208 | 301 | ||
| 302 | +onShow(() => { | ||
| 303 | + if (taskId.value) { | ||
| 304 | + DetailQuery(taskId.value); | ||
| 305 | + } else { | ||
| 306 | + loading.value = false; | ||
| 307 | + uni.showToast({ title: '缺少工单ID参数', icon: 'none' }); | ||
| 308 | + } | ||
| 209 | }); | 309 | }); |
| 210 | -onShow(()=>{ | ||
| 211 | - DetailQuery(taskId.value) | ||
| 212 | -}) | ||
| 213 | </script> | 310 | </script> |
| 214 | 311 | ||
| 215 | <style scoped lang="scss"> | 312 | <style scoped lang="scss"> |
| 216 | // 全局样式 | 313 | // 全局样式 |
| 217 | .page-container { | 314 | .page-container { |
| 218 | min-height: 100vh; | 315 | min-height: 100vh; |
| 219 | - | ||
| 220 | } | 316 | } |
| 221 | 317 | ||
| 222 | // 主内容容器 | 318 | // 主内容容器 |
| @@ -238,18 +334,17 @@ onShow(()=>{ | @@ -238,18 +334,17 @@ onShow(()=>{ | ||
| 238 | .detail-content { | 334 | .detail-content { |
| 239 | .detail-cell-group { | 335 | .detail-cell-group { |
| 240 | background-color: #fff; | 336 | background-color: #fff; |
| 241 | - | ||
| 242 | margin-bottom: 20rpx; | 337 | margin-bottom: 20rpx; |
| 243 | } | 338 | } |
| 244 | 339 | ||
| 245 | - | ||
| 246 | .cell-content-wrap { | 340 | .cell-content-wrap { |
| 247 | - //display: flex; | ||
| 248 | - //flex-wrap: wrap; | ||
| 249 | - //gap: 12rpx; | 341 | + // 保持原有样式,兼容up-album布局 |
| 250 | } | 342 | } |
| 251 | 343 | ||
| 252 | - | 344 | + .empty-text { |
| 345 | + color: #999; | ||
| 346 | + font-size: 26rpx; | ||
| 347 | + } | ||
| 253 | } | 348 | } |
| 254 | 349 | ||
| 255 | // 图片分类Tabs区块 | 350 | // 图片分类Tabs区块 |
| @@ -258,13 +353,13 @@ onShow(()=>{ | @@ -258,13 +353,13 @@ onShow(()=>{ | ||
| 258 | border-radius: 12rpx; | 353 | border-radius: 12rpx; |
| 259 | padding: 16rpx; | 354 | padding: 16rpx; |
| 260 | 355 | ||
| 261 | - // 图片Tabs样式(平均分配空间) | ||
| 262 | - .img-tabs { | ||
| 263 | - --u-tabs-item-flex: 1; // 平均分配空间 | ||
| 264 | - --u-tabs-item-font-size: 26rpx; | ||
| 265 | - --u-tabs-item-height: 72rpx; | ||
| 266 | - margin-bottom: 16rpx; | ||
| 267 | - } | 356 | + //// 图片Tabs样式(平均分配空间) |
| 357 | + //.img-tabs { | ||
| 358 | + // --u-tabs-item-flex: 1; // 平均分配空间 | ||
| 359 | + // --u-tabs-item-font-size: 26rpx; | ||
| 360 | + // --u-tabs-item-height: 72rpx; | ||
| 361 | + // margin-bottom: 16rpx; | ||
| 362 | + //} | ||
| 268 | 363 | ||
| 269 | // 图片内容区 | 364 | // 图片内容区 |
| 270 | .img-tab-content { | 365 | .img-tab-content { |
| @@ -278,11 +373,22 @@ onShow(()=>{ | @@ -278,11 +373,22 @@ onShow(()=>{ | ||
| 278 | width: 100%; | 373 | width: 100%; |
| 279 | } | 374 | } |
| 280 | 375 | ||
| 376 | + .empty-img-text { | ||
| 377 | + height: 100px; | ||
| 378 | + line-height: 100px; | ||
| 379 | + color: #999; | ||
| 380 | + font-size: 28rpx; | ||
| 381 | + } | ||
| 281 | } | 382 | } |
| 282 | } | 383 | } |
| 283 | 384 | ||
| 284 | // 流程节点空状态 | 385 | // 流程节点空状态 |
| 285 | .process-content { | 386 | .process-content { |
| 387 | + display: flex; | ||
| 388 | + justify-content: center; | ||
| 389 | + align-items: center; | ||
| 390 | + min-height: 400rpx; | ||
| 391 | + | ||
| 286 | .empty-process { | 392 | .empty-process { |
| 287 | margin-top: 100rpx; | 393 | margin-top: 100rpx; |
| 288 | } | 394 | } |