Merge branch 'develop' into dev
All checks were successful
Build & Deploy on Dev / build (push) Successful in 3m3s

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2026-05-07 16:24:51 +07:00
commit cf58e28a11
2 changed files with 97 additions and 59 deletions

View file

@ -11,7 +11,14 @@ export const useSpecialTimeStore = defineStore("LeaveSpecialTime", () => {
{ id: "NOT_COMPLETE", name: "ปฏิบัติงานไม่ครบตามกำหนดเวลา" }, { id: "NOT_COMPLETE", name: "ปฏิบัติงานไม่ครบตามกำหนดเวลา" },
]); ]);
// convertSatatus const optionStatusMain = ref<DataOption[]>([
{ id: "ALL", name: "ทั้งหมด" },
{ id: "PENDING", name: "รอดำเนินการ" },
{ id: "APPROVE", name: "อนุมัติ" },
{ id: "REJECT", name: "ไม่อนุมัติ" },
]);
// convertStatus
function convertStatus(val: string) { function convertStatus(val: string) {
const value = val ? val.toUpperCase() : null; const value = val ? val.toUpperCase() : null;
switch (value) { switch (value) {
@ -29,5 +36,6 @@ export const useSpecialTimeStore = defineStore("LeaveSpecialTime", () => {
return { return {
optionStatus, optionStatus,
convertStatus, convertStatus,
optionStatusMain,
}; };
}); });

View file

@ -10,8 +10,10 @@ import { useSpecialTimeStore } from "@/modules/09_leave/stores/SpecialTimeStore"
import { checkPermission } from "@/utils/permissions"; import { checkPermission } from "@/utils/permissions";
import { usePagination } from "@/composables/usePagination"; import { usePagination } from "@/composables/usePagination";
import type { DataDateMonthObject } from "@/modules/09_leave/interface/request/specialTime"; import type {
import type { DataSpecialTime } from "@/modules/09_leave/interface/index/Main"; DataSpecialTime,
DataOption,
} from "@/modules/09_leave/interface/index/Main";
import DialogReason from "@/components/Dialogs/PopupReason.vue"; import DialogReason from "@/components/Dialogs/PopupReason.vue";
import DialogApprove from "@/modules/09_leave/components/04_SpecialTime/DialogApprove.vue"; import DialogApprove from "@/modules/09_leave/components/04_SpecialTime/DialogApprove.vue";
@ -21,23 +23,17 @@ const mixin = useCounterMixin();
const store = useSpecialTimeStore(); const store = useSpecialTimeStore();
const { const {
hideLoader, hideLoader,
monthYear2Thai,
messageError, messageError,
showLoader, showLoader,
success, success,
date2Thai, date2Thai,
dialogConfirm, dialogConfirm,
dateToISO,
} = mixin; } = mixin;
const { pagination, params, onRequest } = usePagination("", fetchData); const { pagination, params, onRequest } = usePagination("", fetchData);
const emit = defineEmits(["update:change-page"]); const emit = defineEmits(["update:change-page"]);
const toDay = ref<Date>(new Date());
const monthToday = toDay.value.getMonth();
const yearToday = toDay.value.getFullYear();
const month = ref<number>(monthToday + 1);
const year = ref<number>(yearToday);
const description = ref<string>(""); const description = ref<string>("");
/**ตัวแปรที่ใช้ */ /**ตัวแปรที่ใช้ */
@ -51,16 +47,12 @@ const name = ref<string>("");
const id = ref<string>(""); const id = ref<string>("");
const dateDialog = ref<string>(""); const dateDialog = ref<string>("");
const dateFixDialog = ref<string>(""); const dateFixDialog = ref<string>("");
const dateYear = ref<number>(new Date().getFullYear());
/** Function Date */
const dateMonth = ref<DataDateMonthObject>({
month: new Date().getMonth(),
year: new Date().getFullYear(),
});
// //
const filterKeyword = ref<string>(""); const filterKeyword = ref<string>("");
const filterStatus = ref<string>("PENDING");
const filterDate = ref<[Date, Date] | null>([new Date(), new Date()]); //
const optionStatus = ref<DataOption[]>(store.optionStatusMain);
const rows = ref<DataSpecialTime[]>([]); const rows = ref<DataSpecialTime[]>([]);
const visibleColumns = ref<String[]>([ const visibleColumns = ref<String[]>([
"no", "no",
@ -144,9 +136,10 @@ async function fetchData() {
.get(config.API.specialTime(), { .get(config.API.specialTime(), {
params: { params: {
...params.value, ...params.value,
year: year.value,
month: month.value,
keyword: filterKeyword.value.trim(), keyword: filterKeyword.value.trim(),
status: filterStatus.value != "ALL" ? filterStatus.value : null,
startDate: filterDate.value ? dateToISO(filterDate.value[0]) : null,
endDate: filterDate.value ? dateToISO(filterDate.value[1]) : null,
}, },
}) })
.then(async (res) => { .then(async (res) => {
@ -246,40 +239,43 @@ async function clickSave(reason: string) {
}); });
} }
/**
* งขอมลตามป
* @param e
*/
async function updateMonth(e: DataDateMonthObject) {
if (e != null) {
dateYear.value = e.year;
dateYear.value = year.value;
month.value = dateMonth.value.month + 1;
year.value = dateMonth.value.year;
onSearchData();
}
}
//
function monthYearThai(val: DataDateMonthObject) {
if (val == null) return "";
else return monthYear2Thai(val.month, val.year);
}
/** ฟังก์ชั่นค้นหาข้อมูล */ /** ฟังก์ชั่นค้นหาข้อมูล */
function onSearchData() { function onSearchData() {
pagination.value.page = 1; pagination.value.page = 1;
fetchData(); fetchData();
} }
/**
* งกนคนหาขอมลของ Option Filter
* @param val คำทนหา
* @param update Function
* @param typeOp ประเภทของ Select
*/
function filterOption(val: string, update: Function) {
update(() => {
const needle = val.toLowerCase();
optionStatus.value = store.optionStatusMain.filter(
(v: DataOption) => v.name.toLowerCase().indexOf(needle) > -1
);
});
}
/**
* แปลงชวงวนทา2คาเปนวนเดยวกนจะโชววนเดยวแตาไมเทากนจะแสดงเปนชวง
* @param val วงวนท
*/
function dateThaiRange(val: [Date, Date]) {
if (val === null) {
return "";
} else if (date2Thai(val[0], true) === date2Thai(val[1], true)) {
return `${date2Thai(val[0], true)}`;
} else {
return `${date2Thai(val[0], true)} - ${date2Thai(val[1], true)}`;
}
}
/**Hook */ /**Hook */
onMounted(async () => { onMounted(async () => {
//
const toDay = ref<Date>(new Date());
const monthToday = toDay.value.getMonth();
const yearToday = toDay.value.getFullYear();
month.value = monthToday + 1;
year.value = yearToday;
await fetchData(); await fetchData();
}); });
</script> </script>
@ -291,25 +287,31 @@ onMounted(async () => {
<q-card flat bordered class="col-12 q-pa-md"> <q-card flat bordered class="col-12 q-pa-md">
<div class="row col-12 q-col-gutter-sm q-mb-sm"> <div class="row col-12 q-col-gutter-sm q-mb-sm">
<div class="col-xs-12 col-sm-3 col-md-2"> <div class="col-xs-12 col-sm-6 col-md-3">
<datepicker <datepicker
v-model="dateMonth" v-model="filterDate"
:locale="'th'" :locale="'th'"
autoApply autoApply
month-picker borderless
range
:enableTimePicker="false" :enableTimePicker="false"
@update:modelValue="updateMonth" week-start="0"
@update:modelValue="onSearchData()"
> >
<template #year="{ year }">{{ year + 543 }}</template> <template #year="{ year }">
<template #year-overlay-value="{ value }">{{ {{ year + 543 }}
parseInt(value + 543) </template>
}}</template> <template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger> <template #trigger>
<q-input <q-input
:model-value="monthYearThai(dateMonth)"
dense
outlined outlined
hide-bottom-space dense
class="full-width datepicker"
:model-value="
filterDate != null ? dateThaiRange(filterDate) : null
"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon
@ -323,9 +325,37 @@ onMounted(async () => {
</template> </template>
</datepicker> </datepicker>
</div> </div>
<div class="col-xs-12 col-sm-6 col-md-2">
<q-select
hide-bottom-space
dense
lazy-rules
outlined
onlind
hide-selected
v-model="filterStatus"
label="สถานะ"
emit-value
map-options
:options="optionStatus"
option-value="id"
use-input
fill-input
option-label="name"
@update:modelValue="onSearchData()"
@filter="(inputValue:string, doneFn:Function) =>
filterOption(inputValue, doneFn,)"
>
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey"> ไมอม </q-item-section>
</q-item>
</template>
</q-select>
</div>
<q-space /> <q-space v-if="!$q.screen.xs && !$q.screen.sm" />
<div class="col-xs-12 col-sm-3 col-md-2"> <div class="col-xs-12 col-sm-6 col-md-2">
<q-input <q-input
standout standout
dense dense
@ -340,7 +370,7 @@ onMounted(async () => {
</q-input> </q-input>
</div> </div>
<div class="col-xs-12 col-sm-3 col-md-2"> <div class="col-xs-12 col-sm-6 col-md-2">
<q-select <q-select
v-model="visibleColumns" v-model="visibleColumns"
multiple multiple