Commit 397b30ae6a39cfd4ad6c271fe9e1c4d4f3b5f329

Authored by 王彪总
1 parent 3c73dfc0

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

pages-sub/problem/regional-order-manage/index.vue
... ... @@ -108,9 +108,9 @@
108 108  
109 109 <!-- 待办工单(0) 保留原来的操作按钮区 不变 -->
110 110 <view v-if="activeTab === 0" class="u-body-item u-body-item-btn-wrap u-flex common-justify-between common-item-center mt-20">
111   - <up-button type="warning" size="large" @click="handleUnifiedReject(item)" v-show="nextStepMap[item.taskKey].backShow">回退</up-button>
  111 + <up-button type="warning" size="large" @click="handleUnifiedReject(item)" v-show="showRejectButton(item)">回退</up-button>
112 112 <up-button type="success" size="large" @click="handleRenew(item)" v-show="nextStepMap[item.taskKey].renewShow">重新提交</up-button>
113   - <up-button type="primary" size="large" @click="handleUnifiedProcess(item)">{{ nextStepMap[item.taskKey].btnText }}</up-button>
  113 + <up-button type="primary" size="large" @click="handleUnifiedProcess(item)">{{ getProcessButtonText(item) }}</up-button>
114 114 <up-button type="info" size="large" @click="handleDetail(item)">详情</up-button>
115 115 </view>
116 116  
... ... @@ -366,6 +366,10 @@ const queryList = async (pageNo, pageSize) =&gt; {
366 366 if (activeTab.value === 0) res = await todoBuzSimplePage(params);
367 367 else if (activeTab.value === 2) res = await myBuzSimplePage(params);
368 368 else res = await doneBuzSimplePage(params);
  369 + // 待办列表:预取各任务的统一动作配置,供底部按钮显隐使用
  370 + if (activeTab.value === 0) {
  371 + await attachConfiguredActions(res?.list);
  372 + }
369 373 pagingHandle('complete', res?.list || [], res?.total || 0);
370 374 } catch (error) {
371 375 console.error('加载工单失败:', error);
... ... @@ -440,9 +444,39 @@ const queryUnifiedActions = async (item) =&gt; {
440 444 return null
441 445 }
442 446  
  447 +/** 待办列表:批量预取统一动作配置,挂在行数据上供按钮显隐复用 */
  448 +const attachConfiguredActions = async (list) => {
  449 + if (!Array.isArray(list) || list.length === 0) return
  450 + await Promise.all(list.map(async (item) => {
  451 + item.configuredActions = await queryUnifiedActions(item)
  452 + }))
  453 +}
  454 +
  455 +/** 驳回类动作编码:只有配置了这些动作,才展示「回退」按钮 */
  456 +const REJECT_ACTION_CODES = ['REJECT', 'RETURN', 'RETURN_PREV']
  457 +
  458 +/** 回退按钮显隐:已配置统一动作时以配置为准,未配置时沿用原有节点规则 */
  459 +const showRejectButton = (item) => {
  460 + if (Array.isArray(item?.configuredActions)) {
  461 + return item.configuredActions.some((action) => REJECT_ACTION_CODES.includes(action.code))
  462 + }
  463 + return !!nextStepMap[item.taskKey]?.backShow
  464 +}
  465 +
  466 +/** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
  467 +const getProcessButtonText = (item) => {
  468 + const actions = item?.configuredActions
  469 + if (Array.isArray(actions) && actions.length > 0) {
  470 + return actions[0].name || actions[0].code
  471 + }
  472 + return nextStepMap[item.taskKey]?.btnText
  473 +}
  474 +
443 475 /** 待办-处理工单:已配置统一动作时走新逻辑,否则回退原有处理 */
444 476 const handleUnifiedProcess = async (item) => {
445   - const actions = await queryUnifiedActions(item)
  477 + const actions = Array.isArray(item?.configuredActions)
  478 + ? item.configuredActions
  479 + : await queryUnifiedActions(item)
446 480 if (actions) {
447 481 unifiedActionsRef.value?.open(item, actions)
448 482 return
... ... @@ -452,7 +486,9 @@ const handleUnifiedProcess = async (item) =&gt; {
452 486  
453 487 /** 待办-回退:已配置统一动作时走新逻辑,否则回退原有弹窗 */
454 488 const handleUnifiedReject = async (item) => {
455   - const actions = await queryUnifiedActions(item)
  489 + const actions = Array.isArray(item?.configuredActions)
  490 + ? item.configuredActions
  491 + : await queryUnifiedActions(item)
456 492 if (actions) {
457 493 const rejectActions = actions.filter((action) =>
458 494 ['REJECT', 'RETURN', 'RETURN_PREV'].includes(action.code)
... ...
pages-sub/problem/regional-order-manage/list-detail.vue
... ... @@ -229,7 +229,7 @@
229 229 type="warning"
230 230 size="normal"
231 231 @click="handleReject(orderDetail)"
232   - v-show="nextStepMap[orderDetail.taskKey].backShow"
  232 + v-show="showRejectButton"
233 233 >回退</up-button>
234 234 <up-button
235 235 type="success"
... ... @@ -238,7 +238,7 @@
238 238 v-show="nextStepMap[orderDetail.taskKey].renewShow"
239 239 >重新提交</up-button>
240 240 <up-button type="primary" size="normal" @click="handleProcess(orderDetail)">
241   - {{ nextStepMap[orderDetail.taskKey].btnText }}
  241 + {{ processButtonText }}
242 242 </up-button>
243 243 </view>
244 244 </view>
... ... @@ -326,10 +326,11 @@
326 326 </template>
327 327  
328 328 <script setup lang="ts">
329   -import { ref } from 'vue'
  329 +import { ref, computed } from 'vue'
330 330 import { onLoad } from '@dcloudio/uni-app'
331 331 import { timeFormat } from '@/uni_modules/uview-plus'
332 332 import { getApprovalDetail,workOrderDetailByID } from '@/api/regional-order-manage/regional-order-manage'
  333 +import { getTaskActions } from '@/api/work-order-manage/work-order-manage'
333 334  
334 335 import { nextStepMap, calculateFormatTimeDiff } from '@/common/utils/common'
335 336 import { useUploadImgs } from '@/common/utils/useUploadImgs'
... ... @@ -484,6 +485,44 @@ const getCurrentStepIndex = () =&gt; {
484 485 return activityNodes.length
485 486 }
486 487  
  488 +// ========== 统一节点动作(工作流配置化) ==========
  489 +/** 当前任务已配置的统一动作;null 表示未配置(回退原有按钮逻辑) */
  490 +const configuredActions = ref<any>(null)
  491 +
  492 +/** 查询当前任务是否已配置统一动作;未配置或接口异常时返回 null */
  493 +const queryUnifiedActions = async (taskId: any) => {
  494 + if (!taskId) return null
  495 + try {
  496 + const data = await getTaskActions(taskId)
  497 + if (data && data.configured && Array.isArray(data.actions) && data.actions.length > 0) {
  498 + return data.actions
  499 + }
  500 + } catch (e) {
  501 + console.warn('查询统一节点动作失败,回退原有逻辑', e)
  502 + }
  503 + return null
  504 +}
  505 +
  506 +/** 驳回类动作编码:只有配置了这些动作,才展示「回退」按钮 */
  507 +const REJECT_ACTION_CODES = ['REJECT', 'RETURN', 'RETURN_PREV']
  508 +
  509 +/** 回退按钮显隐:已配置统一动作时以配置为准,未配置时沿用原有节点规则 */
  510 +const showRejectButton = computed(() => {
  511 + if (Array.isArray(configuredActions.value)) {
  512 + return configuredActions.value.some((action: any) => REJECT_ACTION_CODES.includes(action.code))
  513 + }
  514 + return !!nextStepMap[orderDetail.value.taskKey]?.backShow
  515 +})
  516 +
  517 +/** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
  518 +const processButtonText = computed(() => {
  519 + const actions = configuredActions.value
  520 + if (Array.isArray(actions) && actions.length > 0) {
  521 + return actions[0].name || actions[0].code
  522 + }
  523 + return nextStepMap[orderDetail.value.taskKey]?.btnText
  524 +})
  525 +
487 526 /**
488 527 * 核心:工单详情接口 workOrderDetailByID
489 528 * @param id 上一页传递的工单ID
... ... @@ -494,6 +533,8 @@ const DetailQuery = async (id: string | number) =&gt; {
494 533 loading.value = true
495 534 const res = await workOrderDetailByID({ id })
496 535 if (res) {
  536 + // 待办详情:预取当前任务的统一动作配置,用于底部按钮显隐
  537 + configuredActions.value = activeTab.value === '0' ? await queryUnifiedActions(res.taskId) : null
497 538 orderDetail.value = res
498 539 currentImgList.value = orderDetail.value.startImgs
499 540 // 赋值流程实例ID,供流程节点接口使用
... ...
pages-sub/problem/regional-order-manage/order-detail.vue
... ... @@ -256,7 +256,7 @@
256 256 <view v-if="activeTab==0&&nextStepMap[orderDetail.taskKey]" class="fixed-bottom-btn-wrap">
257 257 <view class="u-body-item u-flex common-justify-between common-item-center ">
258 258 <up-button type="warning" size="normal" @click="handleReject(orderDetail)"
259   - v-show="nextStepMap[orderDetail.taskKey].backShow">回退
  259 + v-show="showRejectButton">回退
260 260 </up-button>
261 261  
262 262 <up-button type="success" size="normal" @click="handleRenew(orderDetail)"
... ... @@ -264,7 +264,7 @@
264 264 </up-button>
265 265  
266 266 <up-button type="primary" size="normal" @click="handleProcess(orderDetail)">{{
267   - nextStepMap[orderDetail.taskKey].btnText
  267 + processButtonText
268 268 }}
269 269 </up-button>
270 270  
... ... @@ -375,6 +375,7 @@ import {
375 375 aiUniversalApproval
376 376 } from '@/api/regional-order-manage/regional-order-manage';
377 377 import {nextStepMap, buzStatusMap, calculateFormatTimeDiff} from '@/common/utils/common'
  378 +import {getTaskActions} from '@/api/work-order-manage/work-order-manage';
378 379 import {useUploadImgs} from '@/common/utils/useUploadImgs'
379 380 import { useUserStore } from '@/pinia/user';
380 381  
... ... @@ -552,6 +553,44 @@ const getCurrentStepIndex = () =&gt; {
552 553 return activityNodes.length;
553 554 }
554 555  
  556 +// ========== 统一节点动作(工作流配置化) ==========
  557 +/** 当前任务已配置的统一动作;null 表示未配置(回退原有按钮逻辑) */
  558 +const configuredActions = ref<any>(null)
  559 +
  560 +/** 查询当前任务是否已配置统一动作;未配置或接口异常时返回 null */
  561 +const queryUnifiedActions = async (taskIdStr: string) => {
  562 + if (!taskIdStr) return null
  563 + try {
  564 + const data = await getTaskActions(taskIdStr)
  565 + if (data && data.configured && Array.isArray(data.actions) && data.actions.length > 0) {
  566 + return data.actions
  567 + }
  568 + } catch (e) {
  569 + console.warn('查询统一节点动作失败,回退原有逻辑', e)
  570 + }
  571 + return null
  572 +}
  573 +
  574 +/** 驳回类动作编码:只有配置了这些动作,才展示「回退」按钮 */
  575 +const REJECT_ACTION_CODES = ['REJECT', 'RETURN', 'RETURN_PREV']
  576 +
  577 +/** 回退按钮显隐:已配置统一动作时以配置为准,未配置时沿用原有节点规则 */
  578 +const showRejectButton = computed(() => {
  579 + if (Array.isArray(configuredActions.value)) {
  580 + return configuredActions.value.some((action: any) => REJECT_ACTION_CODES.includes(action.code))
  581 + }
  582 + return !!nextStepMap[orderDetail.value.taskKey]?.backShow
  583 +})
  584 +
  585 +/** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
  586 +const processButtonText = computed(() => {
  587 + const actions = configuredActions.value
  588 + if (Array.isArray(actions) && actions.length > 0) {
  589 + return actions[0].name || actions[0].code
  590 + }
  591 + return nextStepMap[orderDetail.value.taskKey]?.btnText
  592 +})
  593 +
555 594 /**
556 595 * 获取工单详情
557 596 */
... ... @@ -560,6 +599,8 @@ const DetailQuery = async (taskIdStr: string) =&gt; {
560 599 try {
561 600 loading.value = true;
562 601 const tabType = Number(activeTab.value);
  602 + // 待办详情:与详情请求并行预取当前任务的统一动作配置,用于底部按钮显隐
  603 + const actionPromise = tabType === 0 ? queryUnifiedActions(taskIdStr) : Promise.resolve(null);
563 604 let res: any;
564 605 // 0-待办 1-已办 2-我发起的任务
565 606 if (tabType === 0) {
... ... @@ -574,6 +615,7 @@ const DetailQuery = async (taskIdStr: string) =&gt; {
574 615 }
575 616  
576 617 if (res) {
  618 + configuredActions.value = await actionPromise;
577 619 orderDetail.value = res;
578 620 currentImgList.value = orderDetail.value.startImgs
579 621 }
... ...
pages-sub/problem/work-order-manage/index.vue
... ... @@ -103,7 +103,7 @@
103 103 <!-- 操作按钮行 -->
104 104 <view class="u-body-item u-body-item-btn-wrap u-flex common-justify-between common-item-center mt-20">
105 105 <up-button type="warning" size="large" @click="handleUnifiedReject(item)"
106   - v-show="nextStepMap[item.taskKey].backShow">回退
  106 + v-show="showRejectButton(item)">回退
107 107 </up-button>
108 108  
109 109 <up-button type="success" size="large" @click="handleRenew(item)"
... ... @@ -111,7 +111,7 @@
111 111 </up-button>
112 112  
113 113 <up-button type="primary" size="large" @click="handleUnifiedProcess(item)">{{
114   - nextStepMap[item.taskKey].btnText
  114 + getProcessButtonText(item)
115 115 }}
116 116 </up-button>
117 117 <up-button type="info" size="large" @click="handleDetail(item)">详情</up-button>
... ... @@ -404,6 +404,10 @@ const queryList = async (pageNo, pageSize) =&gt; {
404 404 // 已办工单
405 405 res = await doneBuzSimplePage(apiParams);
406 406 }
  407 + // 待办列表:预取各任务的统一动作配置,供底部按钮显隐使用
  408 + if (activeTab.value == 0) {
  409 + await attachConfiguredActions(res.list);
  410 + }
407 411 // 适配z-paging分页
408 412 paging.value.complete(res.list, res.total);
409 413 } catch (error) {
... ... @@ -507,9 +511,39 @@ const queryUnifiedActions = async (item) =&gt; {
507 511 return null
508 512 }
509 513  
  514 +/** 待办列表:批量预取统一动作配置,挂在行数据上供按钮显隐复用 */
  515 +const attachConfiguredActions = async (list) => {
  516 + if (!Array.isArray(list) || list.length === 0) return
  517 + await Promise.all(list.map(async (item) => {
  518 + item.configuredActions = await queryUnifiedActions(item)
  519 + }))
  520 +}
  521 +
  522 +/** 驳回类动作编码:只有配置了这些动作,才展示「回退」按钮 */
  523 +const REJECT_ACTION_CODES = ['REJECT', 'RETURN', 'RETURN_PREV']
  524 +
  525 +/** 回退按钮显隐:已配置统一动作时以配置为准,未配置时沿用原有节点规则 */
  526 +const showRejectButton = (item) => {
  527 + if (Array.isArray(item?.configuredActions)) {
  528 + return item.configuredActions.some((action) => REJECT_ACTION_CODES.includes(action.code))
  529 + }
  530 + return !!nextStepMap[item.taskKey]?.backShow
  531 +}
  532 +
  533 +/** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
  534 +const getProcessButtonText = (item) => {
  535 + const actions = item?.configuredActions
  536 + if (Array.isArray(actions) && actions.length > 0) {
  537 + return actions[0].name || actions[0].code
  538 + }
  539 + return nextStepMap[item.taskKey]?.btnText
  540 +}
  541 +
510 542 /** 待办-处理工单:已配置统一动作时走新逻辑,否则回退原有处理 */
511 543 const handleUnifiedProcess = async (item) => {
512   - const actions = await queryUnifiedActions(item)
  544 + const actions = Array.isArray(item?.configuredActions)
  545 + ? item.configuredActions
  546 + : await queryUnifiedActions(item)
513 547 if (actions) {
514 548 unifiedActionsRef.value?.open(item, actions)
515 549 return
... ... @@ -519,7 +553,9 @@ const handleUnifiedProcess = async (item) =&gt; {
519 553  
520 554 /** 待办-回退:已配置统一动作时走新逻辑,否则回退原有弹窗 */
521 555 const handleUnifiedReject = async (item) => {
522   - const actions = await queryUnifiedActions(item)
  556 + const actions = Array.isArray(item?.configuredActions)
  557 + ? item.configuredActions
  558 + : await queryUnifiedActions(item)
523 559 if (actions) {
524 560 const rejectActions = actions.filter((action) =>
525 561 ['REJECT', 'RETURN', 'RETURN_PREV'].includes(action.code)
... ...
pages-sub/problem/work-order-manage/order-detail.vue
... ... @@ -259,7 +259,7 @@
259 259 <view v-if="activeTab==0&&nextStepMap[orderDetail.taskKey]" class="fixed-bottom-btn-wrap">
260 260 <view class="u-body-item u-flex common-justify-between common-item-center ">
261 261 <up-button type="warning" size="normal" @click="handleUnifiedReject(orderDetail)"
262   - v-show="nextStepMap[orderDetail.taskKey].backShow">回退
  262 + v-show="showRejectButton">回退
263 263 </up-button>
264 264  
265 265 <up-button type="success" size="normal" @click="handleRenew(orderDetail)"
... ... @@ -267,7 +267,7 @@
267 267 </up-button>
268 268  
269 269 <up-button type="primary" size="normal" @click="handleUnifiedProcess(orderDetail)">{{
270   - nextStepMap[orderDetail.taskKey].btnText
  270 + processButtonText
271 271 }}
272 272 </up-button>
273 273 </view>
... ... @@ -365,7 +365,7 @@
365 365 </template>
366 366  
367 367 <script setup lang="ts">
368   -import {ref, watch} from 'vue';
  368 +import {ref, computed, watch} from 'vue';
369 369 import {onLoad, onShow} from '@dcloudio/uni-app';
370 370 import {timeFormat} from '@/uni_modules/uview-plus';
371 371 import {
... ... @@ -513,6 +513,8 @@ const DetailQuery = async (taskIdStr: string) =&gt; {
513 513 loading.value = true;
514 514 // 转换activeTab为数字类型,避免类型不一致导致接口调用失败
515 515 const tabType = Number(activeTab.value);
  516 + // 待办详情:与详情请求并行预取当前任务的统一动作配置,用于底部按钮显隐
  517 + const actionPromise = tabType === 0 ? queryUnifiedActions({taskId: taskIdStr}) : Promise.resolve(null);
516 518 let res: any;
517 519 // 0-待办 1-已办 2-我发起的任务
518 520 if (tabType === 0) {
... ... @@ -528,6 +530,7 @@ const DetailQuery = async (taskIdStr: string) =&gt; {
528 530  
529 531 // 覆盖工单详情数据
530 532 if (res) {
  533 + configuredActions.value = await actionPromise;
531 534 orderDetail.value = res;
532 535 currentImgList.value = orderDetail.value.startImgs
533 536 }
... ... @@ -705,6 +708,29 @@ const confirmReject = async () =&gt; {
705 708 // ========== 统一节点动作(工作流配置化) ==========
706 709 const unifiedActionsRef = ref(null)
707 710  
  711 +/** 当前任务已配置的统一动作;null 表示未配置(回退原有按钮逻辑) */
  712 +const configuredActions = ref<any>(null)
  713 +
  714 +/** 驳回类动作编码:只有配置了这些动作,才展示「回退」按钮 */
  715 +const REJECT_ACTION_CODES = ['REJECT', 'RETURN', 'RETURN_PREV']
  716 +
  717 +/** 回退按钮显隐:已配置统一动作时以配置为准,未配置时沿用原有节点规则 */
  718 +const showRejectButton = computed(() => {
  719 + if (Array.isArray(configuredActions.value)) {
  720 + return configuredActions.value.some((action: any) => REJECT_ACTION_CODES.includes(action.code))
  721 + }
  722 + return !!nextStepMap[orderDetail.value.taskKey]?.backShow
  723 +})
  724 +
  725 +/** 主按钮文案:已配置统一动作时取配置的动作名称,未配置时沿用原有节点规则 */
  726 +const processButtonText = computed(() => {
  727 + const actions = configuredActions.value
  728 + if (Array.isArray(actions) && actions.length > 0) {
  729 + return actions[0].name || actions[0].code
  730 + }
  731 + return nextStepMap[orderDetail.value.taskKey]?.btnText
  732 +})
  733 +
708 734 /** 查询当前任务是否已配置统一动作;未配置或接口异常时返回 null,回退原有逻辑 */
709 735 const queryUnifiedActions = async (item: any) => {
710 736 if (!item || !item.taskId) return null
... ... @@ -721,7 +747,9 @@ const queryUnifiedActions = async (item: any) =&gt; {
721 747  
722 748 /** 处理工单:已配置统一动作时走新逻辑,否则回退原有处理 */
723 749 const handleUnifiedProcess = async (item: any) => {
724   - const actions = await queryUnifiedActions(item)
  750 + const actions = Array.isArray(configuredActions.value)
  751 + ? configuredActions.value
  752 + : await queryUnifiedActions(item)
725 753 if (actions) {
726 754 unifiedActionsRef.value?.open(item, actions)
727 755 return
... ... @@ -731,7 +759,9 @@ const handleUnifiedProcess = async (item: any) =&gt; {
731 759  
732 760 /** 回退:已配置统一动作时走新逻辑,否则回退原有弹窗 */
733 761 const handleUnifiedReject = async (item: any) => {
734   - const actions = await queryUnifiedActions(item)
  762 + const actions = Array.isArray(configuredActions.value)
  763 + ? configuredActions.value
  764 + : await queryUnifiedActions(item)
735 765 if (actions) {
736 766 const rejectActions = actions.filter((action: any) =>
737 767 ['REJECT', 'RETURN', 'RETURN_PREV'].includes(action.code)
... ...