เรียนในใบลา

This commit is contained in:
setthawutttty 2025-05-15 11:38:52 +07:00
parent 49c316c062
commit 48d0c9febc
7 changed files with 342 additions and 52 deletions

View file

@ -169,6 +169,7 @@ export default {
* workflow
*/
workflow: `${workflow}/`,
commanderPosexe: (type:string)=>`${workflow}/commander-posexe/${type}`,
keycloakLogSSO: `${org}/keycloak/log/sso`,

View file

@ -12,6 +12,7 @@ interface ProfileData {
citizenId?: string;
salary?: number|null;
birthDate?: string;
keycloakId?: string;
org?: string;
dateStart?: string;
dateRetireLaw?: string;

View file

@ -1,13 +1,21 @@
<script setup lang="ts">
import { onMounted } from "vue";
import { onMounted, ref, watch } from "vue";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useLeaveStore } from "@/modules/05_leave/store";
import { useDataStore } from "@/stores/data";
import DialogHeader from "@/components/DialogHeader.vue";
import { useQuasar, type QTableProps } from "quasar";
const mixin = useCounterMixin();
const dataStore = useLeaveStore();
const { date2Thai } = mixin;
const storeData = useDataStore();
const { date2Thai, showLoader, hideLoader, messageError } = mixin;
const modal = ref<boolean>(false);
/** รับ props มาจากหน้าหลัก */
const props = defineProps({
model: {
@ -16,6 +24,110 @@ const props = defineProps({
},
});
const $q = useQuasar();
const isAct = ref<boolean>(false);
const search = ref<string>("");
const total = ref<number>(0);
const totalList = ref<number>(1);
const pagination = ref({
sortBy: "createdAt",
descending: true,
page: 1,
rowsPerPage: 10,
});
const selected = ref<any[]>([]);
const rows = ref<any[]>([]);
const columns = ref<QTableProps["columns"]>([
{
name: "posNo",
align: "left",
label: "เลขที่ตำแหน่ง",
sortable: true,
field: "posNo",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "fullName",
align: "left",
label: "ชื่อ-นามสกุล",
sortable: true,
field: "fullName",
format(val, row) {
return `${row.prefix}${row.firstName} ${row.lastName}`;
},
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "posExecutiveNameOrg",
align: "left",
label: "ตำแหน่งทางการบริหาร",
sortable: true,
field: "posExecutiveNameOrg",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
function onPerson() {
modal.value = true;
getCommander();
}
function onSubmit() {
modal.value = false;
dataStore.dear = selected.value[0].firstName
? `${selected.value[0].prefix}${selected.value[0].firstName} ${selected.value[0].lastName}`
: "";
dataStore.commanderPosition = selected.value[0].posExecutiveNameOrg;
}
function closeDialog() {
modal.value = false;
}
function getCommander() {
showLoader();
http
.put(config.API.commanderPosexe("operate"), {
isAct: isAct.value,
keyword: search.value,
page: pagination.value.page,
pageSize: pagination.value.rowsPerPage,
keycloakId: storeData.formData.keycloakId,
})
.then((res) => {
rows.value = res.data.result.data;
})
.catch((e) => {
messageError($q, e);
hideLoader();
})
.finally(() => {
hideLoader();
});
}
function updatePagination(newPagination: any) {
pagination.value.page = 1;
pagination.value.rowsPerPage = newPagination.rowsPerPage;
}
function getSearch() {
pagination.value.page = 1;
getCommander();
}
watch(
() => pagination.value.rowsPerPage,
async () => {
getSearch();
}
);
/**Hook */
onMounted(() => {
dataStore.typeLeave = "";
@ -24,9 +136,37 @@ onMounted(() => {
<template>
<q-card bordered class="q-pa-md bg-grey-1">
<div class="col-12 row q-pa-sm q-col-gutter-sm items-center">
<q-input
v-model="dataStore.dear"
dense
outlined
bg-color="white"
label="เรียน (ชื่อ - นามสกุล)"
class="col-4"
></q-input>
<q-input
v-model="dataStore.commanderPosition"
dense
outlined
bg-color="white"
label="เรียน (ตำแหน่ง)"
class="col-4"
></q-input>
<div class="col-4">
<q-btn
class="bg-secondary text-white"
icon="add"
unelevated
@click="onPerson"
><q-tooltip>เพมรายช</q-tooltip></q-btn
>
</div>
</div>
<div class="col-12"><q-separator /></div>
<div class="col-12 row q-pa-sm q-col-gutter-sm">
<datepicker
class="col-12 col-sm-4"
class="col-12 col-sm-6"
menu-class-name="modalfix"
v-model="dataStore.dateSendLeave"
:locale="'th'"
@ -70,7 +210,7 @@ onMounted(() => {
</template>
</datepicker>
<q-input
class="col-12 col-sm-4"
class="col-12 col-sm-6"
dense
bg-color="white"
outlined
@ -78,7 +218,7 @@ onMounted(() => {
v-model="dataStore.typeLeave"
label="เรื่อง"
/>
<q-input
<!-- <q-input
class="col-12 col-sm-4"
dense
outlined
@ -86,7 +226,7 @@ onMounted(() => {
bg-color="white"
v-model="dataStore.commanderPosition"
label="เรียน"
/>
/> -->
<q-input
class="col-12 col-sm-4"
@ -155,4 +295,139 @@ onMounted(() => {
/>
</div>
</q-card>
<q-dialog v-model="modal" persistent>
<q-card class="col-12" style="width: 80%">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader :tittle="`เลือกผู้บังคับบัญชา`" :close="closeDialog" />
<q-separator />
<q-card-section>
<div class="row q-col-gutter-sm">
<div class="col-12">
<div class="row q-col-gutter-md items-start">
<div class="col-12 col-sm-4 col-md-4">
<q-input
v-model="search"
outlined
hide-bottom-space
dense
label="คำค้น"
/>
</div>
<q-checkbox
keep-color
v-model="isAct"
label="แสดงเฉพาะรักษาการแทน"
color="primary"
>
<q-tooltip>แสดงเฉพาะรกษาการแทน </q-tooltip>
</q-checkbox>
<q-space />
<div class="col-12 col-sm-6 col-md-3">
<q-btn
color="primary"
icon="search"
label="ค้นหา"
class="full-width q-pa-sm"
outline
@click.prevent="getCommander"
>
</q-btn>
</div>
</div>
</div>
<div class="col-12">
<d-table
ref="table"
:columns="columns"
:rows="rows"
row-key="key"
flat
bordered
:paging="true"
dense
:rows-per-page-options="[10, 25, 50, 100]"
selection="single"
@update:pagination="updatePagination"
v-model:selected="selected"
>
<template v-slot:pagination="scope">
งหมด {{ total }} รายการ
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="Number(totalList)"
size="sm"
boundary-links
direction-links
:max-pages="5"
@update:model-value="getSearch"
></q-pagination>
</template>
<template v-slot:header-selection="scope">
<q-checkbox
keep-color
color="primary"
dense
v-model="scope.checkBox"
/>
</template>
<template v-slot:header="props">
<q-tr :props="props">
<q-th auto-width />
<q-th
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<span class="text-weight-medium">{{ col.label }}</span>
</q-th>
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td>
<q-checkbox
keep-color
color="primary"
dense
v-model="props.selected"
/>
</q-td>
<q-td
v-for="col in props.cols"
:key="col.name"
:props="props"
>
<div v-if="col.name == 'no'">
{{
(pagination.page - 1) * pagination.rowsPerPage +
props.rowIndex +
1
}}
</div>
<div v-else>
{{ col.value ? col.value : "-" }}
</div>
</q-td>
</q-tr>
</template>
</d-table>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn label="บันทึก" color="secondary" type="submit"
><q-tooltip>นทกขอม</q-tooltip></q-btn
>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>

View file

@ -316,8 +316,6 @@ export const useLeaveStore = defineStore("Leave", () => {
const data = res.data.result;
dateSendLeave.value = data.dateSendLeave;
leaveTypeName.value = data.leaveTypeName;
dear.value = data.dear;
commanderPosition.value = data.commanderPosition;
fullName.value = data.fullName;
positionName.value = data.positionName;
positionLevelName.value = data.positionLevelName;

View file

@ -36,6 +36,7 @@ const {
showLoader,
hideLoader,
convertDateToAPI,
dialogMessageNotify,
} = mixin;
const model = ref<string>("");
@ -58,29 +59,34 @@ async function fectOptionType() {
function onSubmit(postData: FormData, isLeave: boolean = true) {
if (isLeave) {
dialogConfirm($q, async () => {
showLoader();
if (model.value === "LV-006" || model.value === "LV-008") {
postData.append("leaveSubTypeName", modelSpecific.value);
}
if (postData.get("leaveEndDate") === postData.get("leaveStartDate")) {
postData.set("leaveRangeEnd", postData.get("leaveRange") as string);
}
if (dataStore.commanderPosition !== "" && dataStore.dear !== "") {
dialogConfirm($q, async () => {
showLoader();
if (model.value === "LV-006" || model.value === "LV-008") {
postData.append("leaveSubTypeName", modelSpecific.value);
}
if (postData.get("leaveEndDate") === postData.get("leaveStartDate")) {
postData.set("leaveRangeEnd", postData.get("leaveRange") as string);
}
postData.append("commanderPosition", dataStore.commanderPosition);
postData.append("dear", dataStore.dear);
await http
.post(config.API.leaveUser(), postData)
await http
.post(config.API.leaveUser(), postData)
.then((res) => {
router.push(`/leave/edit/${res.data.result.id}`);
success($q, "บันทึกสำเร็จ");
})
.catch((e: any) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
.then((res) => {
router.push(`/leave/edit/${res.data.result.id}`);
success($q, "บันทึกสำเร็จ");
})
.catch((e: any) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
} else {
dialogMessageNotify($q, "กรุณาเพิ่มรายชื่อ ผู้บังคับบัญชา");
}
} else {
messageError($q, "", "ไม่มีสิทธิ์ลา");
}

View file

@ -38,6 +38,7 @@ const {
success,
date2Thai,
dialogRemove,
dialogMessageNotify,
} = mixin;
const titleName = ref<string>("");
@ -221,27 +222,33 @@ async function fetchDataDetail(id: string) {
*/
function onSubmit(formData: any, isLeave: boolean = true) {
if (isLeave) {
dialogConfirm($q, async () => {
showLoader();
if (model.value === "LV-006" || model.value === "LV-008") {
formData.append("leaveSubTypeName", modelSpecific.value);
}
if (formData.get("leaveEndDate") === formData.get("leaveStartDate")) {
formData.set("leaveRangeEnd", formData.get("leaveRange") as string);
}
await http
.put(config.API.leaveUserId(personalId.value), formData)
.then(async () => {
await fetchDataDetail(personalId.value);
success($q, "บันทึกสำเร็จ");
})
.catch((e: any) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
if (dataStore.commanderPosition !== "" && dataStore.dear !== "") {
dialogConfirm($q, async () => {
showLoader();
if (model.value === "LV-006" || model.value === "LV-008") {
formData.append("leaveSubTypeName", modelSpecific.value);
}
if (formData.get("leaveEndDate") === formData.get("leaveStartDate")) {
formData.set("leaveRangeEnd", formData.get("leaveRange") as string);
}
formData.append("commanderPosition", dataStore.commanderPosition);
formData.append("dear", dataStore.dear);
await http
.put(config.API.leaveUserId(personalId.value), formData)
.then(async () => {
await fetchDataDetail(personalId.value);
success($q, "บันทึกสำเร็จ");
})
.catch((e: any) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
});
} else {
dialogMessageNotify($q, "กรุณาเพิ่มรายชื่อ ผู้บังคับบัญชา");
}
} else {
messageError($q, "", "ไม่มีสิทธิ์ลา");
}
@ -426,7 +433,7 @@ onMounted(async () => {
:on-confirm="onConfirm"
:click-delete="clickDelete"
/>
<HelpWifeBirthForm
<HelpWifeBirthForm5
v-if="model === 'LV-004'"
:data="formData"
:on-submit="onSubmit"

View file

@ -28,6 +28,7 @@ export const useDataStore = defineStore("dataMain", () => {
posLevelName: "",
salary: null,
birthDate: "",
keycloakId: "",
posNo: "",
org: "",
dateStart: "",
@ -108,6 +109,7 @@ export const useDataStore = defineStore("dataMain", () => {
formData.lastName = data.lastName;
formData.position = data.position;
formData.salary = data.salary;
formData.keycloakId = data.keycloak;
formData.citizenId = data.citizenId;
formData.birthDate = data.birthDate;
formData.posTypeName = data.posTypeName;