数字督察一体化平台-前端
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

<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>