hrms-mgt/src/components/Dialogs/PopupPersonalNew.vue
2026-02-18 14:00:01 +07:00

838 lines
30 KiB
Vue

<script setup lang="ts">
import { ref, reactive, watch, onMounted } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useRouter, useRoute } from "vue-router";
import { checkPermissionGet } from "@/utils/permissions";
import { useRegistryNewDataStore } from "@/modules/04_registryPerson/store";
/** importType*/
import type { PersonalImformation } from "@/components/information/interface/response/Information";
import type {
Goverment,
GovermentEmpTemp,
} from "@/components/information/interface/response/Government";
import type { Avatar } from "@/components/information/interface/response/avatar";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import CardPosition from "@/modules/21_report/components/CardPosition.vue";
/** use*/
const store = useRegistryNewDataStore();
const route = useRoute();
const mixin = useCounterMixin();
const router = useRouter();
const $q = useQuasar();
const retireDate = ref<Date>();
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
const isLeave = ref<boolean>(false);
const dateLeave = ref<Date | string | null>(null);
const leaveType = ref<string>("");
const leaveReason = ref<string>("");
const leaveCommandNo = ref<string>("");
const isEmployee = defineModel("isEmployee", { type: String });
const empType = ref<string>("officer");
const checkRoute = ref<boolean>(route.name == "reportRegistry");
/** props*/
const props = defineProps({
id: {
type: String,
requier: true,
},
modal: {
type: Boolean,
requier: true,
},
type: { type: String, default: "" },
});
/** emit*/
const emit = defineEmits(["update:modal"]);
/** ตัวแปร*/
const modal = ref<boolean>(false);
const isLoading = ref<boolean>(true);
const employeeClass = ref<string>("");
const avatar = reactive<Avatar>({
avatar: "",
fullname: "",
position: "",
});
const imformation = reactive<PersonalImformation>({
prefix: "",
citizenId: "",
firstName: "",
lastName: "",
birthDate: "",
age: "",
gender: "",
});
const goverment = reactive<Goverment>({
oc: "",
posNo: "",
position: "",
positionPathSide: "",
positionLine: "",
positionType: "",
positionLevel: "",
positionExecutive: "",
positionExecutiveSide: "",
dateLeave: "",
dateRetireLaw: "",
});
const govermentTemp = reactive<GovermentEmpTemp>({
positionEmployeeGroupId: "",
positionEmployeeLineId: "",
positionEmployeePositionId: "",
employeeOc: "",
employeeTypeIndividual: "",
employeeWage: "",
employeeMoneyIncrease: "",
employeeMoneyAllowance: "",
employeeMoneyEmployee: "",
employeeMoneyEmployer: "",
});
/**
* function คำนวนอายุ
* @param birthDate วันเดือนปีเกิด
* @returns อายุ
*/
function calculateAge(birthDate: Date | null) {
if (!birthDate) return null;
const birthDateTimeStamp = new Date(birthDate).getTime();
const now = new Date();
const diff = now.getTime() - birthDateTimeStamp;
const ageDate = new Date(diff);
const years = ageDate.getUTCFullYear() - 1970;
const months = ageDate.getUTCMonth();
const days = ageDate.getUTCDate() - 1;
const retire = new Date(birthDate);
retire.setFullYear(retire.getFullYear() + 60);
retireDate.value = retire;
if (years > 60) {
return "อายุเกิน 60 ปี";
}
return `${years} ปี ${months} เดือน ${days} วัน`;
}
/**
* function เรียกข้อมูลส่วนตัว
* @param id profileID
*/
async function fetchInformation(id: string) {
isLoading.value = true;
await http
.get(
config.API.orgProfileById(
id,
`${
props.type.toLocaleLowerCase() == "employee"
? `-${props.type.toLocaleLowerCase()}`
: ""
}`
)
)
.then(async (res) => {
const data = await res.data.result;
imformation.prefix = data.rank
? data.rank
: data.prefix
? data.prefix
: "-";
imformation.citizenId = data.citizenId ? data.citizenId : "-";
imformation.firstName = data.firstName ? data.firstName : "-";
imformation.lastName = data.lastName ? data.lastName : "-";
imformation.birthDate = data.birthDate ? date2Thai(data.birthDate) : "-";
imformation.age = data.birthDate ? calculateAge(data.birthDate) : "-";
imformation.gender = data.gender ?? "-";
isLeave.value = data.isLeave;
dateLeave.value = data.dateLeave ? date2Thai(data.dateLeave) : "-";
leaveType.value = store.convertTypeRetired(data.leaveType);
leaveReason.value = data.leaveReason;
leaveCommandNo.value = data.leaveCommandNo;
employeeClass.value = data.employeeClass ?? "officer";
avatar.fullname = `${data.prefix}${data.firstName} ${data.lastName}`;
avatar.position = data.position ? data.position : "-";
//ถ้ามีรูปเรียก Function fetchProfile เรียกข้อมูลรูปโปรไฟล์
if (data.avatarName) {
await fetchProfile(data.id as string, data.avatarName);
} else {
avatar.avatar = "";
}
if (props.id) {
// employeeClass.value === "TEMP" เรียกข้อมูลลูกจ้างชั่วคราว ไม่ใช่ เรียกข้อมูลข้อมูลราชการ
employeeClass.value === "TEMP"
? await fetchProfileGovTemp(props.id)
: await fetchProfileGov(props.id);
}
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
isLoading.value = false;
});
}
/**
* function เรียกข้อมูลข้อมูลราชการ
* @param id profileID
*/
async function fetchProfileGov(id: string) {
await http
.get(
config.API.profileNewGovernmentCard(
id,
`${
props.type.toLocaleLowerCase() == "employee"
? `-${props.type.toLocaleLowerCase()}`
: ""
}`
)
)
.then(async (res) => {
const data = await res.data.result;
goverment.oc = data.org !== "" ? data.org : "-";
goverment.posNo = data.posMasterNo !== "" ? data.posMasterNo : "-";
goverment.position = data.position !== "" ? data.position : "-";
goverment.positionPathSide =
data.positionArea !== "" ? data.positionArea : "-";
goverment.positionLine =
data.positionField !== "" ? data.positionField : "-";
goverment.positionType = data.posType !== "" ? data.posType : "-";
goverment.positionLevel = data.posLevel !== "" ? data.posLevel : "-";
goverment.positionExecutive =
data.posExecutive !== null ? data.posExecutive : "-";
goverment.positionExecutiveSide =
data.positionExecutiveField !== "" ? data.positionExecutiveField : "-";
goverment.dateLeave = !data.dateLeave ? "-" : date2Thai(data.dateLeave);
goverment.dateRetireLaw = !data.dateRetireLaw
? "-"
: date2Thai(data.dateRetireLaw);
})
.catch((err) => {
messageError($q, err);
});
}
/**
* function fetch ข้อมูลลูกจ้างชั่วคราว
* @param id profileID
*/
async function fetchProfileGovTemp(id: string) {
await http
.get(config.API.informationEmployee(id))
.then((res) => {
const data = res.data.result;
govermentTemp.positionEmployeeGroupId = data.positionEmployeeGroupId;
govermentTemp.positionEmployeeLineId = data.positionEmployeeLineId;
govermentTemp.positionEmployeePositionId =
data.positionEmployeePositionId;
govermentTemp.employeeOc = data.employeeOc;
govermentTemp.employeeTypeIndividual = data.employeeTypeIndividual;
govermentTemp.employeeWage = data.employeeWage;
govermentTemp.employeeMoneyIncrease = data.employeeMoneyIncrease;
govermentTemp.employeeMoneyAllowance = data.employeeMoneyAllowance;
govermentTemp.employeeMoneyEmployee = data.employeeMoneyEmployee;
govermentTemp.employeeMoneyEmployer = data.employeeMoneyEmployer;
})
.catch((err) => {
messageError($q, err);
});
}
/**
* function เรียกไฟล์รูป
* @param id profileID
* @param avatarName ชื่อไฟล์
*/
async function fetchProfile(id: string, avatarName: string) {
await http
.get(config.API.fileByFile("ทะเบียนประวัติ", "โปรไฟล์", id, avatarName))
.then(async (res) => {
avatar.avatar = await res.data.downloadUrl;
});
}
function redirecToRegistry() {
window.open(
`/registry-${
employeeClass.value.toLocaleLowerCase() === "perm"
? "employee"
: employeeClass.value.toLocaleLowerCase() === "temp"
? "temp"
: "officer"
}/${props.id}`,
"_blank"
);
modal.value = false;
}
watch(
() => props.modal,
async () => {
modal.value = props.modal ? props.modal : false;
if (modal.value) {
if (props.id) {
empType.value =
route.name === "appoint-employee-detail" ||
isEmployee.value == "EMPLOYEE"
? "employee"
: "officer";
await fetchInformation(props.id);
}
}
}
);
watch(modal, (newValue) => {
if (!newValue) {
emit("update:modal", false);
}
});
</script>
<template>
<q-dialog v-model="modal" position="right" :maximized="true" persistent>
<q-card style="width: 420px; overflow: visible">
<q-toolbar>
<q-toolbar-title
:class="
isLeave
? 'text-subtitle1 text-bold text-red'
: 'text-subtitle1 text-bold'
"
>ทะเบยนประว{{ isLeave ? "ผู้พ้นจากราชการ" : "" }}
</q-toolbar-title>
<q-btn
icon="close"
unelevated
round
dense
@click="emit('update:modal', false)"
style="color: red; background-color: #ffdede"
/>
</q-toolbar>
<q-card-section class="col q-pt-none bg-grey-12">
<div class="q-gutter-md">
<div v-if="isLoading">
<q-skeleton
type="QAvatar"
size="120px"
style="background: #e3e3e3"
class="q-mx-auto q-mt-md"
/>
<q-skeleton
type="text"
width="150px"
style="background: #e3e3e3"
class="q-mx-auto q-mt-md"
/>
<q-skeleton
type="text"
width="100px"
style="background: #e3e3e3"
class="q-mx-auto q-mt-sm"
/>
<q-skeleton
type="QBtn"
width="150px"
style="background: #e3e3e3"
class="q-mx-auto q-mt-sm"
/>
</div>
<q-card v-else bordered class="text-center bg-grey-12">
<div>
<q-avatar size="120px" color="grey-4">
<img
v-if="avatar.avatar"
:src="avatar.avatar"
class="bg-grey-3"
style="object-fit: cover"
/>
<img
v-else
src="@/assets/avatar_user.jpg"
class="bg-grey-3"
style="object-fit: cover"
/>
</q-avatar>
</div>
<div
class="q-mt-md text-subtitle2 text-bold"
style="font-size: 18px"
>
{{ avatar.fullname }}
</div>
<div
v-if="avatar.position != '-'"
class="q-mb-xs text-center text-grey"
>
{{ avatar.position }}
</div>
<div class="q-mt-md">
<q-btn
v-if="
props.type.toLocaleLowerCase() === 'employee'
? checkPermissionGet('SYS_REGISTRY_EMP')
: checkPermissionGet('SYS_REGISTRY_OFFICER')
"
class="bg-white"
outline
rounded
label="ดูรายละเอียดเพิ่มเติมทั้งหมด"
color="secondary"
@click.prevent="redirecToRegistry"
/>
</div>
</q-card>
<q-scroll-area style="height: 65vh; max-width: 100%">
<div class="q-gutter-md q-pa-sm">
<q-card bordered style="border: 1px solid #d6dee1">
<div class="q-pa-md">
<div class="text-weight-bold row items-center">
<q-icon name="mdi-account" color="grey-7" />
<span class="q-ml-md">ข้อมูลส่วนตัว </span>
</div>
<div v-if="isLoading" class="row q-pa-sm">
<div
v-for="n in 6"
:key="n"
class="col-xs-6 col-md-6 q-pa-sm"
>
<q-skeleton type="QInput" height="40px" />
</div>
</div>
<div v-else class="row q-pa-sm">
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
imformation.citizenId ? imformation.citizenId : '-'
"
label="เลขประจำตัวประชาชน"
></q-input>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
imformation.gender ? imformation.gender : '-'
"
label="เพศ"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
imformation.birthDate ? imformation.birthDate : '-'
"
label="วัน/เดือน/ปีเกิด"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="imformation.age ? imformation.age : '-'"
label="อายุ"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
goverment.dateLeave ? goverment.dateLeave : '-'
"
label="วันครบเกษียณอายุ"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
goverment.dateRetireLaw
? goverment.dateRetireLaw
: '-'
"
label="วันที่เกษียณอายุราชการตามกฏหมาย"
/>
</div>
</div>
</div>
</q-card>
<q-card bordered style="border: 1px solid #d6dee1">
<div class="q-pa-md">
<div class="text-weight-bold row items-center">
<q-icon name="mdi-account-tie" color="grey-7" />
<span class="q-ml-md">
{{
employeeClass !== "TEMP"
? "ข้อมูลราชการ"
: "ข้อมูลลูกจ้างชั่วคราว"
}}
</span>
</div>
<div v-if="isLoading" class="row q-pa-sm">
<div
v-for="n in 9"
:key="n"
:class="
n !== 1
? 'col-xs-6 col-md-6 q-pa-sm'
: 'col-xs-12 col-md-12 q-pa-sm'
"
>
<q-skeleton type="QInput" height="40px" />
</div>
</div>
<div v-else>
<div v-if="isLeave" class="row q-col-gutter-sm q-pa-sm">
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="dateLeave ? dateLeave : '-'"
label="วันเดือนปีที่พ้นจากราชการ"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="leaveType ? leaveType : '-'"
label="ประเภทการพ้นจากราชการ"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="leaveCommandNo ? leaveCommandNo : '-'"
label="คำสั่ง/เอกสารอ้างอิง"
/>
</div>
<div class="col-xs-12 col-md-12">
<q-input
borderless
readonly
:model-value="leaveReason ? leaveReason : '-'"
label="สาเหตุ/เหตุผล"
/>
</div>
</div>
<q-separator v-if="isLeave" />
<div class="row q-pa-sm" v-if="employeeClass !== 'TEMP'">
<div class="col-xs-12 col-md-12 text-html">
<q-input
borderless
readonly
:model-value="goverment.oc ? goverment.oc : '-'"
label="สังกัด"
autogrow
></q-input>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="goverment.posNo ? goverment.posNo : '-'"
:label="
props.type.toLocaleLowerCase() == 'employee'
? 'ตำแหน่งเลขที่'
: 'เลขที่ตำแหน่ง'
"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
goverment.position ? goverment.position : '-'
"
:label="
props.type.toLocaleLowerCase() == 'employee'
? 'ตำแหน่ง'
: 'ตำแหน่งในสายงาน'
"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
autogrow
:model-value="
goverment.positionPathSide
? goverment.positionPathSide
: '-'
"
label="ด้าน/สาขา"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
goverment.positionLine
? goverment.positionLine
: '-'
"
label="สายงาน"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
goverment.positionType
? goverment.positionType
: '-'
"
:label="
props.type.toLocaleLowerCase() == 'employee'
? 'กลุ่มงาน'
: 'ตำแหน่งประเภท'
"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
goverment.positionLevel
? goverment.positionLevel
: '-'
"
:label="
props.type.toLocaleLowerCase() == 'employee'
? 'ระดับชั้นงาน'
: 'ระดับตำแหน่ง'
"
/>
</div>
<div
class="col-xs-6 col-md-6"
v-if="props.type.toLocaleLowerCase() !== 'employee'"
>
<q-input
borderless
readonly
autogrow
:model-value="
goverment.positionExecutive
? goverment.positionExecutive
: '-'
"
label="ตำแหน่งทางการบริหาร"
/>
</div>
<div
class="col-xs-6 col-md-6"
v-if="props.type.toLocaleLowerCase() !== 'employee'"
>
<q-input
borderless
readonly
:model-value="
goverment.positionExecutiveSide
? goverment.positionExecutiveSide
: '-'
"
autogrow
label="ด้านทางการบริหาร"
/>
</div>
</div>
<div class="row q-pa-sm" v-else>
<div class="col-xs-12 col-md-12 text-html">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeOc
? govermentTemp.employeeOc
: '-'
"
label="สังกัด"
autogrow
></q-input>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.positionEmployeeGroupId
? govermentTemp.positionEmployeeGroupId
: '-'
"
label="กลุ่มงาน"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.positionEmployeeLineId
? govermentTemp.positionEmployeeLineId
: '-'
"
label="สายงาน"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.positionEmployeePositionId
? govermentTemp.positionEmployeePositionId
: '-'
"
label="ตำแหน่ง"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeTypeIndividual
? govermentTemp.employeeTypeIndividual
: '-'
"
label="ประเภทบุคคล"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeWage
? govermentTemp.employeeWage
: '-'
"
label="ค่าจ้าง"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeMoneyIncrease
? govermentTemp.employeeMoneyIncrease
: '-'
"
label="เงินเพิ่มการครองชีพชั่วคราว"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeMoneyAllowance
? govermentTemp.employeeMoneyAllowance
: '-'
"
label="เงินช่วยเหลือการครองชีพชั่วคราว"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeMoneyEmployee
? govermentTemp.employeeMoneyEmployee
: '-'
"
label="เงินสมทบประกันสังคม (ลูกจ้าง)"
/>
</div>
<div class="col-xs-6 col-md-6">
<q-input
borderless
readonly
:model-value="
govermentTemp.employeeMoneyEmployer
? govermentTemp.employeeMoneyEmployer
: '-'
"
label="เงินสมทบประกันสังคม (นายจ้าง)"
/>
</div>
</div>
</div>
</div>
</q-card>
<q-card
bordered
style="border: 1px solid #d6dee1"
v-if="
checkRoute && props.type.toLocaleLowerCase() === 'officer'
"
>
<CardPosition :id="props.id" :type="props.type" />
</q-card>
</div>
</q-scroll-area>
</div>
</q-card-section>
</q-card>
</q-dialog>
</template>
<style scoped></style>