[Fix การลา] แก้ไขการยิง api ไป get ข้อมูลประเภทการลาและ position ในหน้ารายละเอียดการการลา และยกเลิกการลาให้เก็บใน store

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-07-14 14:56:21 +07:00
parent 6f7bdb91ee
commit 2d6e42170b
5 changed files with 264 additions and 188 deletions

View file

@ -50,6 +50,66 @@ interface DataRoleWorkflow {
isStaff: boolean;
}
interface DataProfilePosition {
amountSpecial: number;
avatar: string;
avatarName: string;
birthDate: string;
child1: string;
child1DnaId: string;
child1Id: string;
child1ShortName: string;
child2: string;
child2DnaId: string;
child2Id: string;
child2ShortName: string;
child3: string;
child3DnaId: string;
child3Id: string;
child3ShortName: string;
child4: string;
child4DnaId: string;
child4Id: null;
child4ShortName: string;
citizenId: string;
dateRetireLaw: string;
dateStart: string;
firstName: string;
isDirector: boolean;
isProbation: boolean;
keycloak: string;
lastName: string;
leaveDate: string;
node: number;
nodeDnaId: string;
nodeId: string;
nodeShortName: string;
posExecutiveId: string;
posExecutiveName: string;
posExecutivePriority: string;
posLevelId: string;
posLevelName: string;
posLevelRank: number;
posMaster: number;
posMasterNo: number;
posNo: string;
posTypeId: string;
posTypeName: string;
posTypeRank: number;
position: string;
positionArea: string;
positionExecutiveField: string;
prefix: string;
profileId: string;
profileType: string;
rank: string;
root: string;
rootDnaId: string;
rootId: string;
rootShortName: string;
salary: number;
}
export type {
ListMenu,
ChildLevelTree,
@ -57,4 +117,5 @@ export type {
DataPermissions,
DataRoles,
DataRoleWorkflow,
DataProfilePosition,
};

View file

@ -12,7 +12,8 @@ import { checkPermission } from "@/utils/permissions";
import { useRoleWorkflowDataStore } from "@/stores/roleWorkflow";
/** importType */
import type { FremData } from "@/modules/09_leave/interface/request/leave";
import type { DataProfilePosition } from "@/interface/response/main";
import type { FormData } from "@/modules/09_leave/interface/request/leave";
import type {
LeaveType,
SeqTypeRow,
@ -33,7 +34,6 @@ import FormLeaveToTraining from "@/modules/09_leave/components/05_Leave/formDeta
import FormLeaveToWorkInternational from "@/modules/09_leave/components/05_Leave/formDetail/formLeaveToWorkInternational.vue"; //
import FormSpouse from "@/modules/09_leave/components/05_Leave/formDetail/formSpouse.vue"; //
import FormVocationalRehabilitation from "@/modules/09_leave/components/05_Leave/formDetail/formVocationalRehabilitation.vue"; //
import WorkFlow from "@/components/Workflow/Main.vue";
import DialogAddCommander from "@/modules/09_leave/components/05_Leave/Dialog/DialogAddCommander.vue";
/** use */
@ -51,20 +51,20 @@ const {
const stores = useLeavelistDataStore();
const router = useRouter();
const route = useRoute();
const paramsId = route.params.id.toString();
const keycloakId = ref<string>("");
const keycloakUserId = ref<string>("");
const workflowRef = ref<any>(null);
const modalApprove = ref(false);
const statusCheck = ref<string>("");
const typeDocx = ref<string>("docx");
const typePdf = ref<string>("pdf");
const dialogTitle = ref<string>("อนุญาต");
const dialogLabel = ref<string>("เหตุผล");
const modalAdd = ref<boolean>(false);
const typeAdd = ref<string>("");
const paramsId = route.params.id.toString(); // ID
const keycloakId = ref<string>(""); // Keycloak ID
const keycloakUserId = ref<string>(""); // Keycloak User ID
const modalApprove = ref(false); // Modal
const statusCheck = ref<string>(""); //
const typeDocx = ref<string>("docx"); //
const typePdf = ref<string>("pdf"); //
const dialogTitle = ref<string>("อนุญาต"); // Title Dialog
const dialogLabel = ref<string>("เหตุผล"); // Label Dialog
const modalAdd = ref<boolean>(false); // Modal
const typeAdd = ref<string>(""); // COMMANDER, APPROVER
/** Form รายละเอียดข้อมูล*/
const formData = reactive<FremData>({
const formData = reactive<FormData>({
id: "", //Id
reasonCommander: "", //
reasonOligarch: "", //
@ -138,10 +138,14 @@ const formData = reactive<FremData>({
leaveRangeEnd: "",
});
const isOfficer = ref<boolean>(false);
const isStaff = ref<boolean>(false);
const isLoadData = ref<boolean>(false);
const checkForm = ref<string>(""); //
const leaveType = ref<LeaveType[]>([]); //
const isOfficer = ref<boolean>(false); // .
const isStaff = ref<boolean>(false); //
const isLoadData = ref<boolean>(false); //
const rows = ref<RowsType>();
//
const idCheck = computed(() => {
if (typeAdd.value == "COMMANDER") {
return rows.value?.commanders.map((items: SeqTypeRow) => items.profileId);
@ -150,6 +154,7 @@ const idCheck = computed(() => {
}
});
//
const approveCheck = computed(() => {
return (
rows.value?.commanders?.every(
@ -158,6 +163,7 @@ const approveCheck = computed(() => {
);
});
//
const approvePendingCheck = computed(() => {
const commanders = rows.value?.commanders || [];
const index = commanders.findIndex((c) => c.profileId === keycloakId.value);
@ -224,12 +230,11 @@ const columns = ref<QTableProps["columns"]>([
},
]);
/**
* Function fetch รายละเอยดของขอม
* งกนเรยกรายละเอยดของขอม
* @param paramsId ID จาก paramID
*/
async function fetchDetailLeave(paramsId: string) {
isLoadData.value = false;
showLoader();
await http
.get(config.API.leaveListById(paramsId))
.then(async (res) => {
@ -379,37 +384,26 @@ async function fetchDetailLeave(paramsId: string) {
};
isLoadData.value = true;
// await fetchOptionType();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
const leaveType = ref<LeaveType[]>();
/** ฟังก์ชันดึงประเภทการลา */
async function fetchOptionType() {
await http
.get(config.API.leaveType())
.then((res) => {
leaveType.value = res.data.result;
})
.catch((err) => {
messageError($q, err);
});
leaveType.value = await stores.leaveTypeList();
}
/**Status Form การลา*/
const checkForm = ref<string>("");
/**
* Function เชคประเภทการลา
* @param type บค
* งกนเชคประเภทการลา
* @param type บค ประเภทการลา
* @param formData บค FormData
*/
function checkLeaveType(leaveTypeId: string, formData: FremData) {
async function checkLeaveType(leaveTypeId: string, formData: FormData) {
if (leaveType.value) {
const filtertype: LeaveType | undefined = leaveType.value.find(
(e: any) => e.id === leaveTypeId
(e: LeaveType) => e.id === leaveTypeId
);
const type = filtertype?.code;
if (type === "LV-001" || type === "LV-002" || type === "LV-003") {
@ -445,7 +439,10 @@ function checkLeaveType(leaveTypeId: string, formData: FremData) {
}
}
/** Function dialog*/
/**
* งกนเป Modal
* @param data ประเภทของ Modal
*/
async function openModal(data: string) {
if (data === "approve") {
modalApprove.value = true;
@ -462,17 +459,10 @@ async function openModal(data: string) {
}
}
// /** function */
// function sendToCommand() {
// dialogConfirm(
// $q,
// async () => {},
// "",
// "?"
// );
// }
/** Function Save */
/**
* งกนบนทกขอมลการอน
* @param reason เหตผลในการอน
*/
function clickSave(reason: string) {
const body = {
reason: reason,
@ -493,7 +483,7 @@ function clickSave(reason: string) {
.catch((err) => {
messageError($q, err);
})
.finally(async () => {
.finally(() => {
hideLoader();
});
},
@ -560,6 +550,12 @@ function clickSave(reason: string) {
}
}
/**
* งกนดาวนโหลดไฟล
* @param id รหสการลา
* @param fileName อไฟล
* @param type ประเภทไฟล
*/
async function onClickDownloadFile(id: string, fileName: string, type: string) {
showLoader();
await http
@ -576,42 +572,49 @@ async function onClickDownloadFile(id: string, fileName: string, type: string) {
});
}
/**
* งกนจดรปแบบหมายเลข
* @param x หมายเลขทองการจดรปแบบ
* @returns หมายเลขทดรปแบบแล
*/
function formattedNumber(x: number) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
const isCheckData = computed(() => {
if (formData.reasonCommander !== "-" && formData.reasonOligarch !== "-") {
return true;
} else return false;
});
/**
* งกนเป Modal เพอเพมผงคบบญชา
* @param type ประเภทการเพ เช งคบบญชา, อำนาจ
*/
function onAddPerson(type: string) {
modalAdd.value = true;
typeAdd.value = type;
}
/** ฟังก์ชันส่งข้อมูลไปพิจารณา */
function onSend() {
dialogConfirm(
$q,
() => {
async () => {
showLoader();
http
await http
.get(config.API.sendApprove(paramsId))
.then(async (res) => {
.then(async () => {
await fetchDetailLeave(paramsId);
success($q, "ส่งไปพิจารณา");
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {});
.finally(() => {
hideLoader();
});
},
"ยืนยันการส่งไปพิจารณา",
"ต้องการส่งไปพิจารณาใช่หรือไม่"
);
}
/** ฟังก์ชันตรวจสอบสถานะเจ้าหน้าที่ */
async function checkOfficer() {
try {
const data = await fetchDataCheckIsoffice(
@ -628,30 +631,30 @@ async function checkOfficer() {
}
}
async function fetchKeycloakPosition() {
/** ฟังก์ชันดึงข้อมูลตำแหน่งจาก Keycloak */
async function fetchKeycloakPositionData() {
if (keycloakId.value == "") {
await http
.get(config.API.keycloakPosition())
.then(async (res) => {
const data = await res.data.result;
keycloakId.value = data.profileId;
})
.catch((err) => {
messageError($q, err);
});
const data: DataProfilePosition = await stores.fetchKeycloakPosition();
keycloakId.value = data?.profileId ?? "";
}
}
/** lifecycle hook */
onMounted(async () => {
if (paramsId) {
await Promise.all([
fetchOptionType(),
fetchKeycloakPosition(),
fetchDetailLeave(paramsId),
checkOfficer(),
]);
try {
showLoader();
await Promise.all([
fetchOptionType(),
fetchKeycloakPositionData(),
fetchDetailLeave(paramsId),
checkOfficer(),
]);
checkLeaveType(formData.leaveTypeId, formData);
await checkLeaveType(formData.leaveTypeId, formData);
} finally {
hideLoader();
}
}
});
</script>

View file

@ -8,16 +8,16 @@ import config from "@/app.config";
import genReport from "@/plugins/genreport";
import { useCounterMixin } from "@/stores/mixin";
import { useLeavelistDataStore } from "@/modules/09_leave/stores/LeaveStore";
import { checkPermission } from "@/utils/permissions";
import { useRoleWorkflowDataStore } from "@/stores/roleWorkflow";
/** importType */
import type { DataProfilePosition } from "@/interface/response/main";
import type {
LeaveType,
FormReject,
RowsType,
} from "@/modules/09_leave/interface/response/leave";
import type { FremData } from "@/modules/09_leave/interface/request/leave";
import type { FormData } from "@/modules/09_leave/interface/request/leave";
/** importForm*/
import DialogReason from "@/components/Dialogs/PopupReason.vue";
@ -56,21 +56,6 @@ const typeDocx = ref<string>("docx");
const typePdf = ref<string>("pdf");
const modalApprove = ref(false);
const dialogTitle = ref<string>("อนุญาต");
// const approveCheck = computed(() => {
// return (
// rows.value?.commanders?.every(
// (commander) => commander.approveStatus === "APPROVE"
// ) ?? false
// );
// });
/**
* consolelog ไวอน
*/
const filesUpload = ref<any>(null);
function upLoadFile() {
console.log("upload", filesUpload.value);
}
const rows = ref<RowsType>();
const statusCheck = ref<string>("");
@ -95,7 +80,7 @@ const formDataReject = reactive<FormReject>({
leaveDirectorComment: "", //
});
const formData = reactive<FremData>({
const formData = reactive<FormData>({
id: "", //Id
reasonCommander: "", //
reasonOligarch: "", //
@ -169,25 +154,11 @@ const formData = reactive<FremData>({
});
const isLoadData = ref<boolean>(false);
onMounted(async () => {
if (paramsId) {
showLoader();
Promise.all([
fetchOptionType(),
fetchDetailDeleteLeave(paramsId),
fetchKeycloakPosition(),
fetchDetailLeave(paramsId),
checkOfficer(),
]).finally(() => {
checkLeaveType(formData.leaveTypeId, formData.leaveSubTypeName);
hideLoader();
});
}
});
const leaveType = ref<LeaveType[]>([]); //
const checkForm = ref<string>(""); //
/**
* Function fetch รายละเอยดของขอม
* งกเรยกขอมลรายละเอยดของการยกเลกลา
* @param paramsId ID จาก paramID
*/
async function fetchDetailDeleteLeave(paramsId: string) {
@ -217,6 +188,10 @@ async function fetchDetailDeleteLeave(paramsId: string) {
});
}
/**
* งกเรยกขอมลรายละเอยดของการลา
* @param paramsId ID จาก paramID
*/
async function fetchDetailLeave(paramsId: string) {
isLoadData.value = false;
await http
@ -313,36 +288,25 @@ async function fetchDetailLeave(paramsId: string) {
commanders: data.commanders,
approvers: data.approvers,
};
// await fetchOptionType();
})
.catch((err) => {
messageError($q, err);
});
}
const leaveType = ref<LeaveType[]>();
/** function เรียกประเภทการลา */
/** ฟังก์ชันเรียกประเภทการลา */
async function fetchOptionType() {
await http
.get(config.API.leaveType())
.then((res) => {
leaveType.value = res.data.result;
})
.catch((err) => {
messageError($q, err);
});
leaveType.value = await stores.leaveTypeList();
}
/**Status Form การลา*/
const checkForm = ref<string>("");
/**
* Function เชคประเภทการลา
* @param type บค
* งกนเชคประเภทการลา
* @param type บค ID ประเภทการลา
*/
function checkLeaveType(leaveTypeId: string, leaveTypeName: string) {
async function checkLeaveType(leaveTypeId: string, leaveTypeName: string) {
if (leaveType.value) {
const filtertype: LeaveType | undefined = leaveType.value.find(
(e: any) => e.id === leaveTypeId
(e: LeaveType) => e.id === leaveTypeId
);
const type = filtertype?.code;
if (type === "LV-001" || type === "LV-002" || type === "LV-003") {
@ -378,8 +342,11 @@ function checkLeaveType(leaveTypeId: string, leaveTypeName: string) {
}
}
/** Function dialog*/
const openModal = async (data: string) => {
/**
* งกนเป modal อนการยกเลกลา
* @param data อมลทใชในการเป modal เช "approve" หร "UnApprove"
*/
function openModal(data: string) {
if (data === "approve") {
modalApprove.value = true;
dialogTitle.value = "อนุญาตให้ยกเลิกการลา";
@ -388,9 +355,12 @@ const openModal = async (data: string) => {
modalApprove.value = true;
dialogTitle.value = "ไม่อนุญาตให้ยกเลิกการลา";
}
};
}
/** Function Save*/
/**
* งกนบนทกขอมลการอน
* @param reason เหตผลในการอน
*/
function clickSave(reason: string) {
const body = {
reason: reason,
@ -402,15 +372,15 @@ function clickSave(reason: string) {
showLoader();
await http
.put(config.API.leaveDeleteApprove(formDataReject.id), body)
.then(() => {
.then(async () => {
await fetchDetailDeleteLeave(paramsId);
modalApprove.value = false;
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(async () => {
await fetchDetailDeleteLeave(paramsId);
modalApprove.value = false;
hideLoader();
});
},
@ -425,15 +395,15 @@ function clickSave(reason: string) {
showLoader();
await http
.put(config.API.leaveDeleteReject(formDataReject.id), body)
.then(() => {
.then(async () => {
await fetchDetailDeleteLeave(paramsId);
modalApprove.value = false;
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(async () => {
await fetchDetailDeleteLeave(paramsId);
modalApprove.value = false;
hideLoader();
});
},
@ -443,6 +413,12 @@ function clickSave(reason: string) {
}
}
/**
* งกนดาวนโหลดไฟลเอกสารการลา
* @param id ID ของการลา
* @param fileName อไฟลองการดาวนโหลด
* @param type ประเภทไฟล เช "docx" หร "pdf"
*/
async function onClickDownloadFile(id: string, fileName: string, type: string) {
showLoader();
await http
@ -459,6 +435,7 @@ async function onClickDownloadFile(id: string, fileName: string, type: string) {
});
}
/** ฟังก์ชันตรวจสอบสถานะเจ้าหน้าที่ */
async function checkOfficer() {
try {
const data = await fetchDataCheckIsoffice(
@ -475,19 +452,29 @@ async function checkOfficer() {
}
}
/** ฟังก์ชันดึงข้อมูลตำแหน่งจาก Keycloak */
async function fetchKeycloakPosition() {
if (myProfileId.value == "") {
await http
.get(config.API.keycloakPosition())
.then(async (res) => {
const data = await res.data.result;
myProfileId.value = data.profileId;
})
.catch((err) => {
messageError($q, err);
});
const data: DataProfilePosition = await stores.fetchKeycloakPosition();
myProfileId.value = data?.profileId ?? "";
}
}
onMounted(async () => {
if (paramsId) showLoader();
try {
await Promise.all([
fetchOptionType(),
fetchDetailDeleteLeave(paramsId),
fetchKeycloakPosition(),
fetchDetailLeave(paramsId),
checkOfficer(),
]);
await checkLeaveType(formData.leaveTypeId, formData.leaveSubTypeName);
} finally {
hideLoader();
}
});
</script>
<template>

View file

@ -23,7 +23,7 @@ interface DateFilter {
status: string; //*สถานะการของลา
keyword: string; //keyword ค้นหา
}
interface FremData {
interface FormData {
id: string; //Id การยื่นขอลา
reasonCommander: string; //เหตุผลผู้บังคับบัญชา
reasonOligarch: string; //เหตุผลผู้มีอำนาจ
@ -99,4 +99,4 @@ interface FremData {
leaveRangeEnd: string;
}
export type { ListsData, FremData, QuerySting, DateFilter };
export type { ListsData, FormData, QuerySting, DateFilter };

View file

@ -1,17 +1,20 @@
import { defineStore } from "pinia";
import { ref, reactive } from "vue";
import type { QTableProps } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
/** importType*/
import type { DataProfilePosition } from "@/interface/response/main";
import type { DateFilter } from "@/modules/09_leave/interface/request/leave";
import type { QTableProps } from "quasar";
import type {
DataRows,
ListLeave,
LeaveType,
} from "@/modules/09_leave/interface/response/leave";
import type { FremData } from "@/modules/09_leave/interface/request/leave";
import http from "@/plugins/http";
import config from "@/app.config";
import type { FormData } from "@/modules/09_leave/interface/request/leave";
const mixin = useCounterMixin();
const { date2Thai } = mixin;
@ -32,12 +35,13 @@ export const useLeavelistDataStore = defineStore("leave", () => {
});
/**ข้อมูลใน Table*/
const mainData = ref<any>([]);
const mainData = ref<any[]>([]);
const rows = ref<DataRows[]>([]);
const columns = ref<QTableProps["columns"]>([]);
const visibleColumns = ref<string[]>([]);
const profilePositionData = ref<DataProfilePosition>();
const leaveType = ref<any>([]);
const leaveType = ref<LeaveType[]>([]);
/**
* fetchListLeave
@ -101,7 +105,7 @@ export const useLeavelistDataStore = defineStore("leave", () => {
* @param data Page
*/
async function fetchListLeaveReject(data: any[]) {
let datalist = data.map((e: FremData) => ({
let datalist = data.map((e: FormData) => ({
id: e.id,
profileType: e.profileType ?? "-",
leaveTypeName: e.leaveTypeName,
@ -171,52 +175,72 @@ export const useLeavelistDataStore = defineStore("leave", () => {
/** function ข้อมูลประเภทการลา*/
async function leaveTypeList() {
if (leaveType.value.length == 0) {
await http.get(config.API.leaveType()).then((res) => {
try {
const res = await http.get(config.API.leaveType());
leaveType.value = res.data.result;
leaveTypeOption(res.data.result);
leaveTypeOption();
return res.data.result;
});
} catch (error) {
throw error; // re-throw ถ้าต้องการให้ caller handle error
}
} else {
return leaveType.value;
}
}
function colorType(val: string) {
const dataType = leaveType.value.find((item: any) => item.id === val);
switch (dataType.code) {
case "LV-001":
return "#FFD1D1"; // Light Red
case "LV-002":
return "#C8E6C9"; // Light Green
case "LV-003":
return "#BBDEFB"; // Light Blue
case "LV-004":
return "#E1BEE7"; // Light Purple
case "LV-005":
return "#DCEDC8"; // Light Lime
case "LV-006":
return "#FFE0B2"; // Light Orange
case "LV-007":
return "#FFECB3"; // Light Amber
case "LV-008":
return "#CFD8DC"; // Light Blue Grey
case "LV-009":
return "#FFCCBC"; // Light Deep Orange
case "LV-010":
return "#FFF9C4"; // Light Amber Lighten
case "LV-011":
return "#B2DFDB"; // Light Teal
const dataType = leaveType.value.find((item: LeaveType) => item.id === val);
if (dataType) {
switch (dataType.code) {
case "LV-001":
return "#FFD1D1"; // Light Red
case "LV-002":
return "#C8E6C9"; // Light Green
case "LV-003":
return "#BBDEFB"; // Light Blue
case "LV-004":
return "#E1BEE7"; // Light Purple
case "LV-005":
return "#DCEDC8"; // Light Lime
case "LV-006":
return "#FFE0B2"; // Light Orange
case "LV-007":
return "#FFECB3"; // Light Amber
case "LV-008":
return "#CFD8DC"; // Light Blue Grey
case "LV-009":
return "#FFCCBC"; // Light Deep Orange
case "LV-010":
return "#FFF9C4"; // Light Amber Lighten
case "LV-011":
return "#B2DFDB"; // Light Teal
}
}
}
function leaveTypeOption(val: any) {
dataToobar.value = leaveType.value.map((e: any) => ({
function leaveTypeOption() {
dataToobar.value = leaveType.value.map((e: LeaveType) => ({
id: e.id,
name: e.name,
code: e.code,
}));
}
/** ฟังก์ชั่นดึงข้อมูลตำแหน่งจาก Keycloak */
async function fetchKeycloakPosition() {
if (!profilePositionData.value) {
try {
const res = await http.get(config.API.keycloakPosition());
profilePositionData.value = res.data.result;
return res.data.result;
} catch (error) {
throw error;
}
} else {
return profilePositionData.value; // Return cached data if available
}
}
return {
dataToobar,
tabMenu,
@ -234,5 +258,6 @@ export const useLeavelistDataStore = defineStore("leave", () => {
converstType,
leaveTypeOption,
leaveTypeList,
fetchKeycloakPosition,
};
});