API workflow

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-10-16 18:10:55 +07:00
parent e9d68b67a4
commit 079a1c1972
5 changed files with 190 additions and 90 deletions

View file

@ -4,6 +4,7 @@ const metadata = `${env.API_URI}/org/metadata/`;
const org = `${env.API_URI}/org`;
const profileOrg = `${env.API_URI}/org/profile`;
const report = `${env.API_URI}/report/profile/`;
const workflow = `${env.API_URI}/org/workflow`;
export default {
profilePosition: () => `${org}/profile/keycloak/position`,
@ -82,4 +83,9 @@ export default {
*/
requestEdit: `${profileOrg}/edit/`,
developmentUser: `${profileOrg}/development/user`,
/**
* workflow
*/
workflow: `${workflow}/`,
};

View file

@ -3,20 +3,28 @@ import { ref, watch } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import type { QTableProps } from "quasar";
import DialogHeader from "@/components/DialogHeader.vue";
const $q = useQuasar();
const { dialogConfirm } = useCounterMixin();
const { dialogConfirm, showLoader, hideLoader, messageError } =
useCounterMixin();
const modal = defineModel<boolean>("modal", { required: true });
const { stateId, fetchData } = defineProps({
stateId: { type: String, require: true },
fetchData: { type: Function, require: true },
});
/** table*/
const selected = ref<any[]>([]);
const rows = ref<any[]>([
{
id: "1",
fullName: "นายศรัณย์ ศิลาดี",
position: "นักบริหาร",
posType: "บริหาร(สูง)",
@ -62,14 +70,34 @@ const columns = ref<QTableProps["columns"]>([
},
]);
const isAcknowledge = ref<boolean>(false);
const isConsider = ref<boolean>(false);
const isComment = ref<boolean>(false);
const isAcceptSetting = ref<boolean>(false);
const isApproveSetting = ref<boolean>(false);
const isReasonSetting = ref<boolean>(false);
function fetchLists() {}
function onSubmit() {
dialogConfirm($q, () => {});
dialogConfirm($q, async () => {
showLoader();
await http
.post(config.API.workflow + `add-step`, {
stateId: stateId,
profileId: selected.value[0].id,
isAcceptSetting: isAcceptSetting.value,
isApproveSetting: isApproveSetting.value,
isReasonSetting: isReasonSetting.value,
})
.then(async () => {
await fetchData?.();
onCloseModal();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
});
}
function onCloseModal() {
@ -146,26 +174,28 @@ watch(modal, (val) => {
keep-color
color="primary"
dense
v-model="isAcknowledge"
v-model="isAcceptSetting"
label="ให้เลือกรับทราบ"
@update:model-value="(isConsider = false), (isComment = false)"
@update:model-value="
(isApproveSetting = false), (isReasonSetting = false)
"
/>
</div>
<div v-if="!isAcknowledge">
<div v-if="!isAcceptSetting">
<q-checkbox
dense
keep-color
color="primary"
v-model="isConsider"
v-model="isApproveSetting"
label="ให้เลือกพิจารณา (อนุมัติ/ไม่อนุมัติ)"
/>
</div>
<div v-if="!isAcknowledge">
<div v-if="!isAcceptSetting">
<q-checkbox
dense
keep-color
color="primary"
v-model="isComment"
v-model="isReasonSetting"
label="ให้แสดงความเห็นในเอกสาร"
/>
</div>
@ -181,7 +211,7 @@ watch(modal, (val) => {
type="submit"
:disable="
selected.length === 0 ||
(!isAcknowledge && !isConsider && !isComment)
(!isAcceptSetting && !isApproveSetting && !isReasonSetting)
"
>
</q-btn>

View file

@ -3,74 +3,102 @@ import { onMounted, ref } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import type { DataListState } from "@/components/Workflow/interface/response/Main";
import DialogSelectPerson from "@/components/Workflow/DialogSelectPerson.vue";
import DialogApprove from "@/components/Workflow/DialogApprove.vue";
const $q = useQuasar();
const { dialogConfirm } = useCounterMixin();
const { dialogConfirm, showLoader, hideLoader, messageError } =
useCounterMixin();
const { id, sysName } = defineProps({
id: { type: String, require: true },
sysName: { type: String, require: true },
});
const state = ref<number>(1);
const isChangeState = ref<boolean>(false);
const isOperate = ref<boolean>(false);
const stateId = ref<string>(""); //id state
const state = ref<number>(1); //state
const rowsOperate = ref<any[]>([
{
fullName: "ชื่อนาม - สกุล",
comment: "ความเห็น",
position: " บริหาร - ต้น ",
status: "อนุมัติ",
},
]);
const modalSelectPerson = ref<boolean>(false);
const modalApprove = ref<boolean>(false);
const isChangeState = ref<boolean>(false); ///
const isOperate = ref<boolean>(true); // (state)
const isView = ref<boolean>(true); //
const isUpdate = ref<boolean>(true); //
const isDelete = ref<boolean>(true); // ()
const isCancel = ref<boolean>(true); // ()
const itemState = ref<any[]>([
{
stateNo: 1,
stateName: "Darft",
},
{
stateNo: 2,
stateName: "Operate",
},
{
stateNo: 3,
stateName: "Finish",
},
]);
const modalSelectPerson = ref<boolean>(false); // /
const itemState = ref<DataListState[]>([]);
function fetchData() {
console.log(id, sysName);
const data = {
stateNo: 1,
step: 1,
can_view: true,
can_update: true,
can_operate: true,
can_change_state: true,
can_delete: false,
can_cancel: false,
};
state.value = data.stateNo;
isChangeState.value = data.can_change_state;
isOperate.value = data.can_operate;
/** ฟังก์ชันเรียกข้อมูล 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);
});
}
function onConfirmDraft() {
dialogConfirm($q, () => {
state.value++;
/** ฟังก์ชันเรียกข้อมูล Workflow ที่อยู่ปัจุบัน*/
async function fetchCheckState() {
await http
.post(config.API.workflow + `check-user-now`, {
refId: id,
system: sysName,
})
.then(async (res) => {
const data = await res.data.result;
stateId.value = data.stateId;
state.value = data.stateNo;
isChangeState.value = data.can_change_state;
isOperate.value = data.can_operate;
isView.value = data.can_view;
isUpdate.value = data.can_update;
isDelete.value = data.can_delete;
isCancel.value = data.can_cancel;
})
.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 Promise.all([fetchData(), fetchCheckState()]);
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
});
}
onMounted(() => {
fetchData();
/** ฟังก์ชันเรียกใช้งานฟังก์ชัน fetchData, fetchCheckState*/
async function fetchAllFunction() {
await Promise.all([fetchData(), fetchCheckState()]);
}
onMounted(async () => {
await fetchAllFunction();
});
</script>
@ -78,12 +106,6 @@ onMounted(() => {
<q-card bordered class="row col-12">
<div class="bg-grey-1 q-pa-sm col-12 row items-center">
<div class="q-pl-sm text-weight-bold text-dark">Workflow</div>
<q-space />
<!-- <q-btn
@click.prevent="modalApprove = true"
label="DialogApprove"
color="public"
/> -->
</div>
<div class="col-12"><q-separator /></div>
<q-card-section>
@ -103,14 +125,11 @@ onMounted(() => {
:color="state < index + 1 ? 'grey-4' : ''"
>
<!-- Darft -->
<div
class="row q-col-gutter-sm"
v-if="step.stateName === 'Darft' && state === 1"
>
<div class="row q-col-gutter-sm" v-if="state === 1">
<div>
<q-btn
v-if="isChangeState"
@click.prevent="onConfirmDraft"
@click.prevent="onChangeState"
label="Next Step"
color="primary"
/>
@ -120,31 +139,44 @@ onMounted(() => {
<!-- Operate -->
<div
class="q-col-gutter-sm"
v-if="step.stateName === 'Operate' && state > 1"
v-if="index > 0 && index < itemState.length - 1 && state > index"
>
<div>
<div v-if="step.stateUserComments.length !== 0">
<q-list bordered separator style="min-width: 20vw">
<q-item v-for="(item, index) in rowsOperate" :key="index">
<q-item
v-for="(item, index) in step.stateUserComments"
:key="index"
>
<q-item-section>
<q-item-label
>{{ item.fullName }}
{{ `(${item.position})` }}</q-item-label
>
>{{ item.createdFullName }}
<!-- {{ `(${item.position})` }} -->
</q-item-label>
<q-item-label caption lines="2">{{
item.comment
item.isReasonSetting ? item.reason : ""
}}</q-item-label>
</q-item-section>
<q-item-section side top>
<q-item-label class="text-green">
{{ item.status }}</q-item-label
{{
item.isAcceptSetting
? item.isAccept
? "รับทราบ"
: ""
: item.isApproveSetting
? item.isApprove
? "อนุมันติ"
: ""
: ""
}}</q-item-label
>
</q-item-section>
</q-item>
</q-list>
</div>
<div v-if="isOperate && state === 2">
<div v-if="isOperate">
<q-btn
@click.prevent="modalSelectPerson = true"
label="ส่งไปผู้บังคับบัญชา/ผู้มีอำนาจ"
@ -152,9 +184,9 @@ onMounted(() => {
/>
</div>
<div v-if="isChangeState && state === 2">
<div v-if="isChangeState">
<q-btn
@click.prevent="onConfirmDraft"
@click.prevent="onChangeState"
label="Next Step"
color="primary"
/>
@ -166,7 +198,9 @@ onMounted(() => {
</q-card-section>
</q-card>
<DialogSelectPerson v-model:modal="modalSelectPerson" />
<DialogApprove v-model:modal="modalApprove" />
<DialogSelectPerson
v-model:modal="modalSelectPerson"
:state-id="stateId"
:fetch-data="fetchAllFunction"
/>
</template>

View file

@ -0,0 +1,27 @@
interface DataListState {
stateId: string;
stateName: string;
stateNo: number;
stateUserComments: StateUserComments[];
}
interface StateUserComments {
createdAt: string;
createdFullName: string;
createdUserId: string;
id: string;
isAccept: boolean | null;
isAcceptSetting: boolean | null;
isApprove: boolean | null;
isApproveSetting: boolean | null;
isReasonSetting: boolean | null;
lastUpdateFullName: string;
lastUpdateUserId: string;
lastUpdatedAt: string;
order: null;
profileId: string;
reason: string;
stateId: string;
}
export type { DataListState };

View file

@ -17,7 +17,11 @@ const router = useRouter();
const mixin = useCounterMixin();
const { success, messageError, showLoader, hideLoader, dialogConfirm } = mixin;
const id = ref<string>(""); //id path
const id = ref<string>(
router.currentRoute.value.name === "addTransfer"
? ""
: route.params.id.toString()
); //id path
const files = ref<any>(); //
const tranferOrg = ref<string>(""); //
const noteReason = ref<string>(""); //
@ -91,7 +95,6 @@ function fileOpen(url: string) {
*/
onMounted(() => {
if (route.params.id !== undefined) {
id.value = route.params.id.toString();
fecthDataTransfer(id.value);
}
});
@ -199,7 +202,7 @@ onMounted(() => {
<!-- Workflow -->
<div class="col-12" v-if="routeName != 'addTransfer'">
<Workflow :id="id" :sys-name="`transfer`" />
<Workflow :id="id" :sys-name="`PLACEMENT_TRANSFER`" />
</div>
</div>
</div>