You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
386 lines
13 KiB
386 lines
13 KiB
<template> |
|
<el-dialog |
|
:show-close="false" |
|
width="84vw" |
|
top="2vh" |
|
class="dialog-header-nopadding" |
|
style="--el-dialog-padding-primary: 10px; margin-bottom: 2vh" |
|
:lock-scroll="false" |
|
> |
|
<template #header="{ close }"> |
|
<header class="flex between v-center dialog-header"> |
|
<div class="ml-16"> |
|
<span class="mr-8 second">问题编号</span> |
|
<span>{{ id }}</span> |
|
</div> |
|
<div class="flex step-box"> |
|
<div |
|
class="step flex center v-center" |
|
v-for="(item, index) in dict.processingStatus" |
|
:key="index" |
|
:active="negative.processingStatus === item.dictValue" |
|
:completed=" |
|
index < |
|
dict.processingStatus.indexOf( |
|
negative.processingStatus |
|
) |
|
" |
|
> |
|
<span class="bloder">{{ index + 1 }}</span> |
|
<span>{{ item.remark }}</span> |
|
</div> |
|
</div> |
|
<div class="flex"> |
|
<el-button |
|
type="primary" |
|
size="large" |
|
:class="isFav ? 'fav-btn active' : 'fav-btn'" |
|
@click="handleFav" |
|
>{{ isFav ? "已收藏" : "收藏" }} |
|
<template #icon> |
|
<icon |
|
:name=" |
|
isFav |
|
? 'el-icon-StarFilled' |
|
: 'el-icon-star' |
|
" |
|
:size="22" |
|
/> |
|
</template> |
|
</el-button> |
|
<el-button |
|
link |
|
circle |
|
size="large" |
|
@click="close" |
|
class="close-btn" |
|
> |
|
<template #icon> |
|
<icon |
|
name="el-icon-close" |
|
:size="26" |
|
:color="'#fff'" |
|
/> |
|
</template> |
|
</el-button> |
|
</div> |
|
</header> |
|
</template> |
|
<main v-loading="loading"> |
|
<el-row style="height: 100%"> |
|
<el-col :span="5" style="height: 100%"> |
|
<div ref="leftContainerRef" class="left-container h100"> |
|
<template |
|
v-if=" |
|
negative.flowKey !== |
|
FlowNodeEnum.FIRST_DISTRIBUTE && |
|
negative.processingStatus !== |
|
ProcessingStatus.COMPLETED |
|
" |
|
> |
|
<negative-countdown |
|
v-model:time="remainingDuration" |
|
:max-time="maxDuration" |
|
:extensionDays="negative.extensionDays" |
|
/> |
|
</template> |
|
<negative-action-history /> |
|
</div> |
|
</el-col> |
|
<el-col :span="19" style="height: 100%"> |
|
<el-scrollbar max-height="100%" class="main-container"> |
|
<negative-sign-return-description /> |
|
<negative-apply-extension-description /> |
|
<negative-description /> |
|
<template |
|
v-if=" |
|
components.indexOf( |
|
'negative-verify-description' |
|
) > -1 |
|
" |
|
> |
|
<negative-verify-description /> |
|
</template> |
|
<template v-if="!disabled"> |
|
<template |
|
v-if=" |
|
components.indexOf('negative-distribute') > |
|
-1 |
|
" |
|
> |
|
<negative-distribute ref="componentRef" /> |
|
</template> |
|
<template |
|
v-if=" |
|
components.indexOf('negative-verify') > -1 |
|
" |
|
> |
|
<negative-verify |
|
ref="componentRef" |
|
@submit="handleSubmitExecute" |
|
/> |
|
</template> |
|
</template> |
|
<template v-if="approves.length"> |
|
<negative-approve-description /> |
|
</template> |
|
</el-scrollbar> |
|
</el-col> |
|
</el-row> |
|
</main> |
|
<footer class="flex between v-center"> |
|
<div style="min-height: 40px"> |
|
<!-- <el-button type="primary" plain size="large">打印</el-button> --> |
|
</div> |
|
<div v-if="!disabled"> |
|
<el-button |
|
size="large" |
|
v-for="item in flowActions" |
|
:key="item.actionKey" |
|
:type="item.buttonType" |
|
:plain="item.plain" |
|
@click="handleExecute(item)" |
|
:disabled=" |
|
loading || |
|
(!negative.extensionApplyFlag && |
|
(item.actionKey === |
|
FlowActionEnum.APPLY_COMPLETION || |
|
item.actionKey === |
|
FlowActionEnum.APPLY_EXTENSION || |
|
item.actionKey === |
|
FlowActionEnum.THREE_SIGN_RETURN)) |
|
" |
|
>{{ item.buttonLabel }}</el-button |
|
> |
|
</div> |
|
</footer> |
|
<template v-for="item in flowActions" :key="item.actionKey"> |
|
<template v-if="item.actionKey.includes('apply_completion')"> |
|
<negative-apply-completion |
|
:ref="(el) => setActionItemRef(item.actionKey, el)" |
|
@submit="handleSubmitExecute" |
|
/> |
|
</template> |
|
<template v-if="item.actionKey.includes('apply_extension')"> |
|
<negative-apply-extension |
|
:ref="(el) => setActionItemRef(item.actionKey, el)" |
|
@submit="handleSubmitExecute" |
|
/> |
|
</template> |
|
<template v-if="item.actionKey.includes('_approve')"> |
|
<negative-approve |
|
:ref="(el) => setActionItemRef(item.actionKey, el)" |
|
@submit="handleSubmitExecute" |
|
/> |
|
</template> |
|
<template v-if="item.actionKey.includes('_return')"> |
|
<negative-return |
|
:ref="(el) => setActionItemRef(item.actionKey, el)" |
|
@submit="handleSubmitExecute" |
|
/> |
|
</template> |
|
</template> |
|
</el-dialog> |
|
</template> |
|
<script lang="ts" setup> |
|
import { |
|
FlowActionEnum, |
|
FlowNodeEnum, |
|
ProcessingStatus, |
|
} from "@/enums/flowEnums"; |
|
import { getNegativeDetails, negativeExecute } from "@/api/work/negative"; |
|
import { addFav, delFav } from "@/api/work/fav"; |
|
import feedback from "@/utils/feedback"; |
|
import { getComponents } from "@/utils/flow"; |
|
import useCatchStore from "@/stores/modules/catch"; |
|
|
|
const dict = useCatchStore().getDicts(["processingStatus"]); |
|
|
|
const props = defineProps({ |
|
id: { |
|
type: String, |
|
required: true, |
|
}, |
|
disabled: { |
|
type: Boolean, |
|
default: true, |
|
}, |
|
}); |
|
|
|
const emit = defineEmits(["close", "change"]); |
|
|
|
const work = inject("work", null); |
|
|
|
const loading = ref(false); |
|
|
|
const negative = ref({}); |
|
const actionHistory = ref([]); |
|
const signReturns = ref([]); |
|
const approves = ref([]); |
|
const extensionApply = ref({}); |
|
provide("negative", negative); |
|
provide("actionHistory", actionHistory); |
|
provide("signReturns", signReturns); |
|
provide("approves", approves); |
|
provide("extensionApply", extensionApply); |
|
|
|
const isFav = ref(false); |
|
const remainingDuration = ref(0); |
|
const maxDuration = ref(0); |
|
const flowActions = ref([]); |
|
const components = ref([]); |
|
watch( |
|
() => props.id, |
|
() => { |
|
getDetails(); |
|
} |
|
); |
|
|
|
function getDetails() { |
|
loading.value = true; |
|
getNegativeDetails(props.id, work?.value.id).then((data) => { |
|
negative.value = data.negative; |
|
flowActions.value = data.flowActions; |
|
actionHistory.value = data.actionHistory; |
|
signReturns.value = data.signReturns; |
|
approves.value = data.approves; |
|
extensionApply.value = data.extensionApply || {}; |
|
isFav.value = data.isFav; |
|
remainingDuration.value = data.remainingDuration; |
|
console.log(remainingDuration.value); |
|
maxDuration.value = data.maxDuration; |
|
components.value = getComponents(data.flowNode?.flowKey); |
|
loading.value = false; |
|
}); |
|
} |
|
|
|
const componentRef = ref([]); |
|
const actionItemRefs = ref({}); |
|
const setActionItemRef = (actionKey, el) => { |
|
if (el) { |
|
actionItemRefs.value[actionKey] = el; |
|
} |
|
}; |
|
const activeAction = ref({}); |
|
async function handleExecute(action, data) { |
|
if (action.validateForm) { |
|
if (action.actionKey !== FlowActionEnum.SAVE) { |
|
try { |
|
data = await componentRef.value.validate(); |
|
} catch (e) { |
|
feedback.msgWarning("请检查输入项"); |
|
throw e; |
|
} |
|
} else { |
|
data = componentRef.value.getData(); |
|
} |
|
} |
|
if (action.openDialog) { |
|
actionItemRefs.value[action.actionKey].open(); |
|
activeAction.value = action; |
|
return; |
|
} |
|
loading.value = true; |
|
await negativeExecute(props.id, { |
|
workId: work?.value.id, |
|
actionKey: action.actionKey, |
|
nextFlowKey: action.nextFlowKey, |
|
actionName: action.actionName, |
|
data, |
|
}); |
|
feedback.msgSuccess("操作成功"); |
|
if (action.doClose) { |
|
emit("change"); |
|
emit("close"); |
|
return; |
|
} |
|
getDetails(); |
|
} |
|
|
|
async function handleSubmitExecute(data) { |
|
activeAction.value.openDialog = false; |
|
handleExecute(activeAction.value, data); |
|
} |
|
|
|
function handleFav() { |
|
if (isFav.value) { |
|
delFav(props.id); |
|
} else { |
|
addFav(props.id); |
|
} |
|
isFav.value = !isFav.value; |
|
} |
|
</script> |
|
<style lang="scss" scoped> |
|
.dialog-header { |
|
--dialog-header-font-color: #acb7ff; |
|
--dialog-header-font-size: 16px; |
|
background-color: var(--primary-color); |
|
color: #fff; |
|
padding: 1em; |
|
font-size: var(--dialog-header-font-size); |
|
.second { |
|
color: var(--dialog-header-font-color); |
|
} |
|
.step-box { |
|
.step { |
|
--setp-background-color: #3a4dc1; |
|
--setp-border-color: #4b60e4; |
|
--setp-font-color: var(--dialog-header-font-color); |
|
--setp-font-size: var(--dialog-header-font-size); |
|
padding-left: 30px; |
|
padding-right: 16px; |
|
&::after { |
|
display: none; |
|
} |
|
&:first-child { |
|
padding-left: 16px; |
|
} |
|
&[active="true"] { |
|
--setp-background-color: #ff4242; |
|
--setp-border-color: #ff7474; |
|
--setp-font-color: #fff; |
|
} |
|
.bloder { |
|
font-size: 24px; |
|
font-weight: 700; |
|
margin-right: 8px; |
|
} |
|
span { |
|
z-index: 2; |
|
} |
|
} |
|
} |
|
.fav-btn { |
|
--el-font-size-base: 18px; |
|
--el-button-bg-color: #283aac; |
|
--el-button-hover-bg-color: #c20921; |
|
--el-button-hover-border-color: #fa8695; |
|
&.active { |
|
--el-button-bg-color: #c20921; |
|
} |
|
&:focus { |
|
background-color: var(--el-button-bg-color); |
|
} |
|
} |
|
.close-btn:hover { |
|
:deep() { |
|
.el-icon { |
|
color: #c20921; |
|
} |
|
} |
|
} |
|
} |
|
main { |
|
height: calc(96vh - 180px); |
|
} |
|
.left-container { |
|
padding: 0 20px 0 40px; |
|
} |
|
.main-container { |
|
padding: 0 20px; |
|
} |
|
footer { |
|
padding: 10px 20px 0; |
|
} |
|
</style> |