270 lines
8.8 KiB
Vue
270 lines
8.8 KiB
Vue
<script setup lang="ts">
|
|
import { onMounted, ref, computed } from "vue";
|
|
import { useQuasar } from "quasar";
|
|
|
|
import { useCounterMixin } from "@/stores/mixin";
|
|
import http from "@/plugins/http";
|
|
import config from "@/app.config";
|
|
|
|
import type { Permission } from "@/components/Workflow/interface/index/Main";
|
|
import type { DataListState } from "@/components/Workflow/interface/response/Main";
|
|
|
|
import DialogSelectPerson from "@/components/Workflow/DialogSelectPerson.vue";
|
|
|
|
const $q = useQuasar();
|
|
const { dialogConfirm, showLoader, hideLoader, messageError } =
|
|
useCounterMixin();
|
|
|
|
const { id, sysName } = defineProps({
|
|
id: { type: String, require: true },
|
|
sysName: { type: String, require: true },
|
|
});
|
|
|
|
const rejectName = computed(() =>
|
|
sysName && ["SYS_RESIGN", "SYS_RESIGN_EMP"].includes(sysName)
|
|
? "ยับยั้ง"
|
|
: "ไม่อนุมัติ"
|
|
);
|
|
|
|
const stateId = ref<string>(""); //id state ปัจุบัน
|
|
const state = ref<number>(1); //state ปัจุบัน
|
|
const isPermission = ref<boolean>(true); //การเข้าถึง Workflow
|
|
const KeycloakId = ref<string>("");
|
|
const isLoading = ref<boolean>(false); //สถานะการโหลดข้อมูล
|
|
|
|
const permission = ref<Permission>({
|
|
isChangeState: false, //ส่งไปยังผู้บังคับบัญชา/ผู้มีอำนาจ
|
|
isOperate: false, //เปลี่ยนสถานะ (state) เอกสารได้
|
|
isView: false, //ดูเอกสารได้
|
|
isUpdate: false, //แก้ไขเอกสารได้
|
|
isDelete: false, //ลบเอกสารได้ (ถ้ามี)
|
|
isCancel: false, //ลบเอกสารได้ (ถ้ามี)
|
|
isSing: false,
|
|
});
|
|
|
|
const modalSelectPerson = ref<boolean>(false); //เลือกรายชื่อ ส่งไปผู้บังคับบัญชา/ผู้มีอำนาจ
|
|
const typeSelectPerson = ref<string>("");
|
|
const itemState = ref<DataListState[]>([]);
|
|
|
|
/** ฟังก์ชันเรียกข้อมูล Workflow ที่อยู่ปัจุบัน*/
|
|
async function fetchCheckState() {
|
|
isLoading.value = true;
|
|
await http
|
|
.post(config.API.workflow + `check-user-now`, {
|
|
refId: id,
|
|
system: sysName,
|
|
})
|
|
.then(async (res) => {
|
|
await fetchData();
|
|
const data = await res.data.result;
|
|
stateId.value = data.stateId;
|
|
state.value =
|
|
data.stateNo === itemState.value.length
|
|
? data.stateNo + 1
|
|
: data.stateNo;
|
|
permission.value = {
|
|
isChangeState: data.can_change_state,
|
|
isOperate: data.can_operate,
|
|
isView: data.can_view,
|
|
isUpdate: data.can_update,
|
|
isDelete: data.can_delete,
|
|
isCancel: data.can_cancel,
|
|
isSing: data.can_sing,
|
|
};
|
|
KeycloakId.value = data.keycloakId;
|
|
})
|
|
.catch(() => {
|
|
isPermission.value = false;
|
|
})
|
|
.finally(() => {
|
|
isLoading.value = false;
|
|
});
|
|
}
|
|
|
|
/** ฟังก์ชันเรียกข้อมูล Workflow ทั้งหมด*/
|
|
async function fetchData() {
|
|
await http
|
|
.post(config.API.workflow + `check-state-all`, {
|
|
refId: id,
|
|
system: sysName,
|
|
})
|
|
.then(async (res) => {
|
|
const data = await res.data.result;
|
|
itemState.value = data;
|
|
})
|
|
.catch((err) => {
|
|
messageError($q, err);
|
|
});
|
|
}
|
|
|
|
/** ฟังก์ชันยืนยันการ NextStep*/
|
|
function onChangeState() {
|
|
dialogConfirm($q, async () => {
|
|
showLoader();
|
|
await http
|
|
.post(config.API.workflow + `state-next`, {
|
|
refId: id,
|
|
system: sysName,
|
|
})
|
|
.then(async () => {
|
|
await fetchCheckState();
|
|
})
|
|
.catch((err) => {
|
|
messageError($q, err);
|
|
})
|
|
.finally(() => {
|
|
hideLoader();
|
|
});
|
|
});
|
|
}
|
|
|
|
onMounted(async () => {
|
|
await fetchCheckState();
|
|
});
|
|
|
|
defineExpose({
|
|
permission,
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<q-card bordered class="row col-12" v-if="isPermission">
|
|
<div class="bg-grey-1 q-pa-sm col-12 row items-center">
|
|
<div class="q-pl-sm text-weight-bold text-dark">สถานะการดำเนินเรื่อง</div>
|
|
</div>
|
|
<div class="col-12"><q-separator /></div>
|
|
<q-card-section class="col-12 q-px-lg q-py-md" v-if="isLoading">
|
|
<q-timeline color="primary">
|
|
<q-timeline-entry
|
|
v-for="(step, index) in 4"
|
|
:key="index"
|
|
:icon="`mdi-numeric-${index + 1}`"
|
|
color="grey-4"
|
|
>
|
|
<template #title>
|
|
<q-skeleton type="rect" width="150px" height="20px" />
|
|
</template>
|
|
</q-timeline-entry>
|
|
</q-timeline>
|
|
</q-card-section>
|
|
|
|
<q-card-section v-else>
|
|
<div class="q-px-lg q-py-md">
|
|
<q-timeline color="primary">
|
|
<q-timeline-entry
|
|
v-for="(step, index) in itemState"
|
|
:key="index"
|
|
:title="step.stateName"
|
|
:icon="
|
|
state === index + 1
|
|
? 'mdi-pencil'
|
|
: state > index + 1
|
|
? 'done'
|
|
: `mdi-numeric-${index + 1}`
|
|
"
|
|
:color="state < index + 1 ? 'grey-4' : ''"
|
|
>
|
|
<!-- Darft -->
|
|
<div class="row q-col-gutter-sm" v-if="state === 1 && index === 0">
|
|
<div>
|
|
<q-btn
|
|
v-if="permission.isChangeState"
|
|
@click.prevent="onChangeState"
|
|
label="ดำเนินการต่อ"
|
|
color="primary"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Operate -->
|
|
<div
|
|
class="q-col-gutter-sm"
|
|
v-if="index > 0 && index < itemState.length - 1 && state > index"
|
|
>
|
|
<div v-if="step.stateUserComments.length !== 0">
|
|
<q-list bordered separator style="min-width: 20vw">
|
|
<q-item
|
|
v-for="(item, index) in step.stateUserComments"
|
|
:key="index"
|
|
>
|
|
<q-item-section>
|
|
<q-item-label
|
|
>{{
|
|
`${item.prefix}${item.firstName} ${item.lastName}`
|
|
}}
|
|
</q-item-label>
|
|
<q-item-label caption lines="2">{{
|
|
item.isReasonSetting ? item.reason : ""
|
|
}}</q-item-label>
|
|
</q-item-section>
|
|
|
|
<q-item-section side top>
|
|
<q-item-label
|
|
:class="
|
|
!item.isApprove && !item.isAccept
|
|
? 'text-red'
|
|
: 'text-green'
|
|
"
|
|
>
|
|
{{
|
|
item.isAcceptSetting
|
|
? item.isAccept
|
|
? "รับทราบ"
|
|
: ""
|
|
: item.isApproveSetting
|
|
? item.isApprove === true
|
|
? "อนุมัติ"
|
|
: item.isApprove === false
|
|
? `${rejectName}`
|
|
: ""
|
|
: ""
|
|
}}
|
|
</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</div>
|
|
|
|
<div v-if="state === index + 1" class="row q-gutter-x-sm">
|
|
<q-btn
|
|
v-if="permission.isOperate"
|
|
@click.prevent="
|
|
(modalSelectPerson = true), (typeSelectPerson = 'operate')
|
|
"
|
|
label="ส่งไปยังผู้บังคับบัญชา"
|
|
color="public"
|
|
/>
|
|
|
|
<q-btn
|
|
v-if="permission.isSing"
|
|
@click.prevent="
|
|
(modalSelectPerson = true), (typeSelectPerson = 'sign')
|
|
"
|
|
label="ส่งไปยังผู้มีอำนาจ"
|
|
color="public"
|
|
/>
|
|
</div>
|
|
|
|
<div v-if="permission.isChangeState && state === index + 1">
|
|
<q-btn
|
|
@click.prevent="onChangeState"
|
|
label="ดำเนินการต่อ"
|
|
color="primary"
|
|
/>
|
|
</div>
|
|
</div>
|
|
</q-timeline-entry>
|
|
</q-timeline>
|
|
</div>
|
|
</q-card-section>
|
|
</q-card>
|
|
|
|
<DialogSelectPerson
|
|
v-model:modal="modalSelectPerson"
|
|
:state-id="stateId"
|
|
:fetch-data="fetchCheckState"
|
|
:type="typeSelectPerson"
|
|
:sys-name="sysName"
|
|
:keycloak-id="KeycloakId"
|
|
/>
|
|
</template>
|