Merge branch 'develop' into devTee

This commit is contained in:
setthawutttty 2024-12-24 13:18:29 +07:00
commit f47cfae539
6 changed files with 96 additions and 136 deletions

View file

@ -147,8 +147,9 @@ watch(
<q-card style="width: 950px; max-width: 80vw"> <q-card style="width: 950px; max-width: 80vw">
<q-toolbar> <q-toolbar>
<q-toolbar-title class="text-subtitle1 text-weight-bold"> <q-toolbar-title class="text-subtitle1 text-weight-bold">
<span style="margin-right: 0"> รายละเอยดการลงเวลาของ</span> <span style="margin-right: 0"> รายละเอยดการลงเวลา</span>
<span class="text-primary">{{ formData.fullName }}</span>
<span class="text-primary q-pl-sm">{{ formData.fullName }}</span>
</q-toolbar-title> </q-toolbar-title>
<q-btn <q-btn
for="closeDialog" for="closeDialog"

View file

@ -130,7 +130,7 @@ watch(
สถานะชวงเช สถานะชวงเช
<q-select <q-select
ref="morningStatusRef" ref="morningStatusRef"
class="q-pa-sm" class="q-pa-sm inputgreen"
dense dense
outlined outlined
v-model="morningStatus" v-model="morningStatus"
@ -165,7 +165,7 @@ watch(
<q-select <q-select
ref="afternoonStatusRef" ref="afternoonStatusRef"
class="q-pa-sm" class="q-pa-sm inputgreen"
dense dense
outlined outlined
v-model="afternoonStatus" v-model="afternoonStatus"
@ -192,6 +192,7 @@ watch(
<q-card flat class="col-12 q-mt-sm"> <q-card flat class="col-12 q-mt-sm">
<q-input <q-input
class="inputgreen"
outlined outlined
dense dense
v-model="reason" v-model="reason"

View file

@ -232,7 +232,7 @@ watch(
/> />
</q-toolbar> </q-toolbar>
<div v-if="props.editCheck === 'edit'"> <div v-if="props.editCheck === 'edit'">
<q-separator color="grey-4" /> <q-separator />
<q-card-section style="max-height: 50vh" class="scroll q-pa-none"> <q-card-section style="max-height: 50vh" class="scroll q-pa-none">
<div class="q-pa-md"> <div class="q-pa-md">
<div class="row"> <div class="row">
@ -270,10 +270,12 @@ watch(
:borderless="true" :borderless="true"
outlined outlined
style="width: 23.5rem" style="width: 23.5rem"
class="inputgreen"
/> />
</div> </div>
<div class="col-6"> <div class="col-6">
<datepicker <datepicker
class="inputgreen"
menu-class-name="modalfix" menu-class-name="modalfix"
v-model="formData.effectiveDate" v-model="formData.effectiveDate"
:locale="'th'" :locale="'th'"
@ -326,6 +328,7 @@ watch(
<div class="col-12"> <div class="col-12">
<q-input <q-input
class="inputgreen"
outlined outlined
stack-label stack-label
ref="resonRef" ref="resonRef"
@ -340,20 +343,18 @@ watch(
</div> </div>
</q-card-section> </q-card-section>
</div> </div>
<q-separator color="grey-4" /> <q-separator />
<div class="q-pa-xs"> <q-card-actions align="right">
<div class="row justify-end q-mr-sm q-py-sm"> <q-btn
<q-btn v-if="props.editCheck === 'edit'"
v-if="props.editCheck === 'edit'" id="onSubmit"
id="onSubmit" type="submit"
type="submit" unelevated
unelevated label="บันทึก"
label="บันทึก" class="q-px-md items-center"
class="q-px-md items-center" color="secondary"
color="secondary" />
/> </q-card-actions>
</div>
</div>
</form> </form>
<div v-if="props.editCheck === 'history'"> <div v-if="props.editCheck === 'history'">
<div class="q-pa-md"> <div class="q-pa-md">

View file

@ -7,10 +7,8 @@ import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import { useSpecialTimeStore } from "@/modules/09_leave/stores/SpecialTimeStore"; import { useSpecialTimeStore } from "@/modules/09_leave/stores/SpecialTimeStore";
import type { import type { dataRowRound } from "@/modules/09_leave/interface/response/specialTime";
dataRowRound, import type { DataOption } from "@/modules/09_leave/interface/index/Main";
MyObjectRoundRef,
} from "@/modules/09_leave/interface/response/specialTime";
import DialogHeader from "@/components/DialogHeader.vue"; import DialogHeader from "@/components/DialogHeader.vue";
@ -19,7 +17,7 @@ const $q = useQuasar();
const SpecialTimeStore = useSpecialTimeStore(); const SpecialTimeStore = useSpecialTimeStore();
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { dialogConfirm, showLoader, success, messageError, hideLoader } = mixin; const { dialogConfirm, showLoader, success, messageError, hideLoader } = mixin;
const option = ref<any[]>(SpecialTimeStore.optionStatus); const option = ref<DataOption[]>(SpecialTimeStore.optionStatus);
/** props*/ /** props*/
const props = defineProps({ const props = defineProps({
@ -32,14 +30,9 @@ const props = defineProps({
checkOutStatus: { type: String, default: "" }, checkOutStatus: { type: String, default: "" },
closeDialog: { type: Function, default: () => {} }, closeDialog: { type: Function, default: () => {} },
detailData: Object, detailData: Object,
fetchData: { type: Function, default: () => {} },
}); });
const checkInRef = ref<Object | null>(null);
const checkOutRef = ref<Object | null>(null);
const checkInStatusRef = ref<Object | null>(null);
const checkOutStatusRef = ref<Object | null>(null);
const reasonRef = ref<Object | null>(null);
const formData = reactive<dataRowRound>({ const formData = reactive<dataRowRound>({
checkIn: "", checkIn: "",
checkOut: "", checkOut: "",
@ -50,73 +43,35 @@ const formData = reactive<dataRowRound>({
checkOutEdit: false, checkOutEdit: false,
}); });
const objectRound: MyObjectRoundRef = {
checkIn: checkInRef,
checkOut: checkOutRef,
checkInStatus: checkInStatusRef,
checkOutStatus: checkOutStatusRef,
note: reasonRef,
};
/** function validateFom*/
function validateForm() {
const hasError = [];
for (const key in objectRound) {
if (Object.prototype.hasOwnProperty.call(objectRound, key)) {
const property = objectRound[key];
if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate();
hasError.push(isValid);
}
}
}
if (hasError.every((result) => result === true)) {
onSubmit();
}
}
/** function confrim*/ /** function confrim*/
function onSubmit() { async function onSubmit() {
dialogConfirm( dialogConfirm($q, async () => {
$q, showLoader();
async () => { await http
await approveData(); .put(config.API.specialTimeApprove(props.id), {
props.closeDialog?.(); checkInTime: formData.checkIn,
}, checkOutTime: formData.checkOut,
"ยืนยันการบันทึกข้อมูล", checkInStatus: formData.checkInStatus,
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?" checkOutStatus: formData.checkOutStatus,
); reason: formData.note,
} })
.then(async () => {
/** function บันทึกข้อมูล*/ await props.fetchData();
async function approveData() { success($q, "บันทึกข้อมูลสำเร็จ");
showLoader(); props.closeDialog?.();
const body = { })
checkInTime: formData.checkIn, .catch((e) => {
checkOutTime: formData.checkOut, messageError($q, e);
checkInStatus: formData.checkInStatus, })
checkOutStatus: formData.checkOutStatus, .finally(async () => {
reason: formData.note, hideLoader();
}; });
await http });
.put(config.API.specialTimeApprove(props.id), body)
.then(() => {
success($q, "บันทึกข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
SpecialTimeStore.fetchData();
hideLoader();
});
} }
/** function closeDialog*/ /** function closeDialog*/
function close() { function close() {
if (props.closeDialog) { props.closeDialog();
props.closeDialog();
}
} }
/** /**
@ -127,7 +82,7 @@ function close() {
function filterOptionFn(val: string, update: Function) { function filterOptionFn(val: string, update: Function) {
update(() => { update(() => {
option.value = SpecialTimeStore.optionStatus.filter( option.value = SpecialTimeStore.optionStatus.filter(
(e: any) => e.name.search(val) !== -1 (e: DataOption) => e.name.search(val) !== -1
); );
}); });
} }
@ -176,7 +131,7 @@ watch(
<template> <template>
<q-dialog v-model="props.modal" persistent> <q-dialog v-model="props.modal" persistent>
<q-card style="width: 350px" class="bg-grey-11"> <q-card style="width: 350px" class="bg-grey-11">
<form @submit.prevent="validateForm"> <q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader <DialogHeader
:tittle=" :tittle="
props.editCheck === 'PENDING' props.editCheck === 'PENDING'
@ -269,7 +224,10 @@ watch(
option-label="name" option-label="name"
label="สถานะ" label="สถานะ"
use-input use-input
hide-selected
fill-input
@filter="filterOptionFn" @filter="filterOptionFn"
class="inputgreen"
> >
<template v-slot:no-option> <template v-slot:no-option>
<q-item> <q-item>
@ -302,19 +260,30 @@ watch(
hide-bottom-space hide-bottom-space
full-width full-width
v-model="formData.checkOutStatus" v-model="formData.checkOutStatus"
:options="SpecialTimeStore.optionStatus" :options="option"
option-value="id" option-value="id"
option-label="name" option-label="name"
label="สถานะ" label="สถานะ"
use-input use-input
hide-selected
fill-input
class="inputgreen"
@filter="filterOptionFn"
> >
<template v-slot:no-option>
<q-item>
<q-item-section class="text-grey">
ไมอม
</q-item-section>
</q-item>
</template>
</q-select> </q-select>
</div> </div>
</div> </div>
<q-input <q-input
ref="reasonRef" ref="reasonRef"
class="col-12 bg-white q-ma-md" class="col-12 bg-white q-ma-md inputgreen"
outlined outlined
stack-label stack-label
:rules="[(val:string) => !!val || 'กรุณาเหตุผล']" :rules="[(val:string) => !!val || 'กรุณาเหตุผล']"
@ -327,20 +296,12 @@ watch(
<q-separator color="grey-4" /> <q-separator color="grey-4" />
<div class="q-pa-xs"> <div class="q-pa-xs">
<div class="row justify-end"> <div class="row justify-end">
<q-btn <q-btn label="บันทึก" color="public" id="onSubmit" type="submit">
dense
unelevated
label="บันทึก"
color="public"
id="onSubmit"
type="submit"
class="q-px-md"
>
<q-tooltip>นท</q-tooltip> <q-tooltip>นท</q-tooltip>
</q-btn> </q-btn>
</div> </div>
</div> </div>
</form> </q-form>
</q-card> </q-card>
</q-dialog> </q-dialog>
</template> </template>

View file

@ -127,9 +127,9 @@ export const useChangeRoundDataStore = defineStore(
showLoader(); showLoader();
await http await http
.post(config.API.leaveSearch(), { .post(config.API.leaveSearch(), {
citizenId: dataDetail.cardId || "", //เลขประจำตัวประชาชน citizenId: dataDetail.cardId.trim() || "", //เลขประจำตัวประชาชน
firstname: dataDetail.firstName || "", //ชื่อจริง firstname: dataDetail.firstName.trim() || "", //ชื่อจริง
lastname: dataDetail.lastName || "", //นามสกุล lastname: dataDetail.lastName.trim() || "", //นามสกุล
page: dataDetail.page, //หน้า page: dataDetail.page, //หน้า
pageSize: dataDetail.pageSize || 10, //จำนวนแถวต่อหน้า pageSize: dataDetail.pageSize || 10, //จำนวนแถวต่อหน้า
keyword: dataDetail.keyword || "", //keyword ค้นหา keyword: dataDetail.keyword || "", //keyword ค้นหา

View file

@ -69,13 +69,6 @@ const pagination = ref({
// //
const filterKeyword = ref<string>(""); const filterKeyword = ref<string>("");
const filterRef = ref<HTMLInputElement | null>(null); const filterRef = ref<HTMLInputElement | null>(null);
const resetFilter = () => {
filterKeyword.value = "";
fetchData();
if (filterRef.value) {
filterRef.value.focus();
}
};
const visibleColumns = ref<String[]>([ const visibleColumns = ref<String[]>([
"no", "no",
@ -193,7 +186,6 @@ function closeDialog() {
async function clickSave(reason: string) { async function clickSave(reason: string) {
dialogConfirm($q, async () => { dialogConfirm($q, async () => {
showLoader(); showLoader();
modalUnapprove.value = false;
const body = { const body = {
reason: reason, reason: reason,
}; };
@ -202,6 +194,7 @@ async function clickSave(reason: string) {
.then(async () => { .then(async () => {
await fetchData(); await fetchData();
success($q, "บันทึกข้อมูลสำเร็จ"); success($q, "บันทึกข้อมูลสำเร็จ");
modalUnapprove.value = false;
}) })
.catch((e) => { .catch((e) => {
messageError($q, e); messageError($q, e);
@ -253,6 +246,8 @@ watch(
* งชนเรยกดอม * งชนเรยกดอม
*/ */
async function fetchData() { async function fetchData() {
console.log(pagination.value.page);
showLoader(); showLoader();
await http await http
.get( .get(
@ -264,7 +259,7 @@ async function fetchData() {
}&keyword=${filterKeyword.value.trim()}` }&keyword=${filterKeyword.value.trim()}`
) )
.then(async (res) => { .then(async (res) => {
let data = res.data.result.data; let data = await res.data.result.data;
total.value = res.data.result.total; total.value = res.data.result.total;
totalList.value = Math.ceil( totalList.value = Math.ceil(
res.data.result.total / pagination.value.rowsPerPage res.data.result.total / pagination.value.rowsPerPage
@ -310,7 +305,6 @@ async function fetchData() {
}) })
.finally(() => { .finally(() => {
hideLoader(); hideLoader();
console.log(month.value);
}); });
} }
@ -403,7 +397,7 @@ onMounted(async () => {
<d-table <d-table
:columns="columns" :columns="columns"
:rows="rows" :rows="rows"
row-key="tb-list" row-key="id"
flat flat
bordered bordered
:paging="false" :paging="false"
@ -412,20 +406,6 @@ onMounted(async () => {
:rows-per-page-options="[10, 25, 50, 100]" :rows-per-page-options="[10, 25, 50, 100]"
@update:pagination="updatePagination" @update:pagination="updatePagination"
> >
<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="fetchData()"
></q-pagination>
</template>
<template v-slot:header="props"> <template v-slot:header="props">
<q-tr :props="props"> <q-tr :props="props">
<q-th auto-width /> <q-th auto-width />
@ -500,14 +480,29 @@ onMounted(async () => {
v-else-if="col.name === 'description'" v-else-if="col.name === 'description'"
class="table_ellipsis" class="table_ellipsis"
> >
{{ props.row.description }} {{ col.value ?? "-" }}
</div> </div>
<div v-else> <div v-else>
{{ col.value }} {{ col.value ?? "-" }}
</div> </div>
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<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="fetchData()"
></q-pagination>
</template>
</d-table> </d-table>
</div> </div>
</q-card> </q-card>
@ -528,6 +523,7 @@ onMounted(async () => {
:id="id" :id="id"
:editCheck="editCheck" :editCheck="editCheck"
:detailData="detailData" :detailData="detailData"
:fetch-data="fetchData"
/> />
</template> </template>