fix: stabilize workflow action buttons

This commit is contained in:
caoqianming 2026-07-27 13:31:30 +08:00
parent 5b007a536d
commit 3dc25fef2a
3 changed files with 108 additions and 38 deletions

View File

@ -188,6 +188,12 @@ export default {
return await http.get( `${config.API_URL}/wf/ticket/${id}/transitions/`);
}
},
ticketAvailableActions: {
name: "获取当前用户可执行的工单操作",
req: async function(id){
return await http.get(`${config.API_URL}/wf/ticket/${id}/available_actions/`);
}
},
dutyAgg: {
url: `${config.API_URL}/wf/ticket/duty_agg/`,
name: "待办审批聚合",

View File

@ -1,4 +1,12 @@
<template>
<el-button
v-if="needAccept"
type="success"
:loading="isAccepting"
:disabled="isAccepting"
@click="acceptTicket"
style="margin-right: 2px"
>接单</el-button>
<span v-if="actionShow"><el-button
v-for="item in transitions"
:key="item.id"
@ -17,10 +25,9 @@
</el-dialog>
</template>
<script setup>
import { ref, reactive, onMounted, defineEmits,watch } from 'vue'
import { ref, defineEmits, watch } from 'vue'
import { ElMessage } from 'element-plus'
import API from '@/api';
import TOOL from "@/utils/tool.js";
const props = defineProps({
@ -34,44 +41,64 @@ const props = defineProps({
const workflow = ref(null);
const transitions = ref([]);
let lastInitTicketId = null;
const tryInit = () => {
// ticket_ ticket_.id
let lastInitKey = null;
let requestVersion = 0;
const getInitKey = () => {
if (props.ticket_ && props.ticket_.id) {
if (lastInitTicketId !== props.ticket_.id) {
lastInitTicketId = props.ticket_.id;
init();
}
return;
return [
'ticket',
props.ticket_.id,
props.ticket_.state,
JSON.stringify(props.ticket_.participant),
props.ticket_.update_time,
].join(':');
}
// ticket_退 workflow_key
if (props.workflow_key) {
if (lastInitTicketId !== '__wf_key__:' + props.workflow_key) {
lastInitTicketId = '__wf_key__:' + props.workflow_key;
init();
}
return `workflow:${props.workflow_key}`;
}
return null;
};
const tryInit = () => {
const initKey = getInitKey();
if (initKey && lastInitKey !== initKey) {
lastInitKey = initKey;
init();
}
};
onMounted(() => { tryInit(); });
watch(() => props.ticket_, () => { tryInit(); }, { deep: true });
watch(() => props.workflow_key, () => { tryInit(); });
watch(
() => [
props.ticket_?.id,
props.ticket_?.state,
props.ticket_?.participant,
props.ticket_?.update_time,
props.workflow_key,
],
tryInit,
{ deep: true, immediate: true },
);
const ticketId = ref(null);
const actionShow = ref(false);
const needAccept = ref(false);
const init = async () => {
const currentRequestVersion = ++requestVersion;
actionShow.value = false;
needAccept.value = false;
transitions.value = [];
if (props.ticket_ && props.ticket_.id) {
ticketId.value = props.ticket_.id;
const isParticipant =
(props.ticket_.participant_type === 1 && props.ticket_.participant === currentUser.value) ||
(props.ticket_.participant_type === 2 && props.ticket_.participant.includes(currentUser.value))
if (isParticipant) {
actionShow.value = true;
transitions.value = await API.wf.ticket.ticketTransitions.req(ticketId.value);
const actionInfo = await API.wf.ticket.ticketAvailableActions.req(ticketId.value);
if (currentRequestVersion !== requestVersion) {
return;
}
needAccept.value = actionInfo.need_accept;
actionShow.value = actionInfo.permission;
transitions.value = actionInfo.transitions;
}else if (props.workflow_key !=null && props.workflow_key != undefined) {
let res = await API.wf.workflow.initkey.req(props.workflow_key);
if (currentRequestVersion !== requestVersion) {
return;
}
actionShow.value = true
transitions.value = res.transitions;
workflow.value = res.workflow
@ -79,11 +106,21 @@ const init = async () => {
ElMessage.error("缺少workflow_key或ticketId");
}
}
const currentUser = ref(TOOL.data.get("USER_INFO").id)
const isSaveing = ref(false);
const isAccepting = ref(false);
const emit = defineEmits(["success"]);
const acceptTicket = async () => {
isAccepting.value = true;
try {
await API.wf.ticket.ticketAccept.req(ticketId.value, {});
ElMessage.success("接单成功");
lastInitKey = null;
await init();
} finally {
isAccepting.value = false;
}
};
const handleTransition = (item) => {
currentTransitionId.value = item.id;
if (item.attribute_type != 1) {

View File

@ -316,6 +316,14 @@
</div>
<div style="display: flex; justify-content: space-between">
<div>
<el-button
v-if="needAccept"
type="success"
:loading="acceptLoading"
:disabled="acceptLoading"
@click="handleAccept"
>接单</el-button
>
<el-button
type="primary"
@click="addNode"
@ -628,6 +636,8 @@ export default {
dosOption: [],
handoverItem:{},
submitLoading: false,
acceptLoading: false,
needAccept: false,
userId: this.$TOOL.data.get("USER_INFO").id,
isOwn: false,
isDuty: false,
@ -760,6 +770,7 @@ export default {
getticketItem() {
let that = this;
that.mainLoading = true;
that.isDuty = false;
that.$API.wf.ticket.ticketItem.req(that.ticketId).then((res) => {
that.mainLoading = false;
that.ticketDetail = res;
@ -791,11 +802,11 @@ export default {
if (this.ticketDetail.create_by == this.userId) {
this.isOwn = true;
}
let participant = this.ticketDetail.participant;
if (
participant == this.userId ||
participant.indexOf(this.userId) > -1
) {
const participant = this.ticketDetail.participant;
const participants = Array.isArray(participant)
? participant
: [participant];
if (participants.map(String).includes(String(this.userId))) {
this.isDuty = true;
}
}).catch((e) => {
@ -806,21 +817,37 @@ export default {
getBtns() {
let that = this;
that.audit_imgs_show = false;
that.$API.wf.ticket.ticketTransitions.req(that.ticketId).then((res) => {
that.operationBtn = res;
that.audit_work_show = false;
that.needAccept = false;
that.$API.wf.ticket.ticketAvailableActions.req(that.ticketId).then((res) => {
that.operationBtn = res.transitions;
that.needAccept = res.need_accept;
if (res.permission || res.need_accept) {
that.isDuty = true;
}
console.log("operationBtn", that.operationBtn);
if(res.length>0){
for (let i = 0; i < res.length; i++) {
if(res[i].on_submit_func=="apps.opm.services.check_opl_audit_imgs"){
if(that.operationBtn.length>0){
for (let i = 0; i < that.operationBtn.length; i++) {
if(that.operationBtn[i].on_submit_func=="apps.opm.services.check_opl_audit_imgs"){
that.audit_imgs_show = true;
}
if(res[i].on_submit_func=="apps.opm.services.check_opl_work_imgs"){
if(that.operationBtn[i].on_submit_func=="apps.opm.services.check_opl_work_imgs"){
that.audit_work_show = true;
}
}
}
});
},
handleAccept() {
this.acceptLoading = true;
this.$API.wf.ticket.ticketAccept.req(this.ticketId, {}).then(() => {
this.$message.success("接单成功");
this.getticketItem();
this.getBtns();
}).finally(() => {
this.acceptLoading = false;
});
},
//访
getVisit() {
this.$API.vm.visit.read.req(this.projectId).then((res) => {