แก้ไขไม่ให้เลือกวันเกิน Date now

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2023-11-01 11:38:15 +07:00
parent d2db87cc2e
commit d2a50125a5
3 changed files with 354 additions and 161 deletions

View file

@ -140,7 +140,7 @@ const fetchPerson = async () => {
Ops.value.religionOps = optionreligions; Ops.value.religionOps = optionreligions;
OpsFilter.value.religionOps = optionreligions; OpsFilter.value.religionOps = optionreligions;
}) })
.catch((e: any) => { }) .catch((e: any) => {})
.finally(() => { .finally(() => {
hideLoader(); hideLoader();
}); });
@ -359,34 +359,82 @@ const clickBack = () => {
<div class="row"> <div class="row">
<div class="row col-12 q-col-gutter-x-sm q-mb-xs"> <div class="row col-12 q-col-gutter-x-sm q-mb-xs">
<div class="col-xs-6 col-sm-3 col-md-3"> <div class="col-xs-6 col-sm-3 col-md-3">
<q-input hide-bottom-space outlined v-model="informaData.cardid" dense @update:model-value="changeCardID " for="#cardId" <q-input
lazy-rules :rules="[ hide-bottom-space
outlined
v-model="informaData.cardid"
dense
@update:model-value="changeCardID"
for="#cardId"
lazy-rules
:rules="[
(val: string) => !!val || `${'กรุณากรอก เลขประจำตัวประชาชน'}`, (val: string) => !!val || `${'กรุณากรอก เลขประจำตัวประชาชน'}`,
(val: string) => (val: string) =>
val.length >= 13 || val.length >= 13 ||
`${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`, `${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,
]" label="เลขประจำตวประชาชน" maxlength="13" mask="#############" /> ]"
label="เลขประจำตัวประชาชน"
maxlength="13"
mask="#############"
/>
<!-- :rules="[(val:any) =>val.length != 13 ||`${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,]" --> <!-- :rules="[(val:any) =>val.length != 13 ||`${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,]" -->
</div> </div>
<div class="col-xs-6 col-sm-3 col-md-3"> <div class="col-xs-6 col-sm-3 col-md-3">
<selector for="#prefixId" hide-bottom-space outlined :rules="[(val: string) => !!val || `${'กรุณาเลือก คำนำหน้าชื่อ'}`]" dense <selector
lazy-rules v-model="informaData.prefixId" emit-value map-options option-label="name" for="#prefixId"
:options="Ops.prefixOps" option-value="id" :label="`${'คำนำหน้าชื่อ'}`" use-input input-debounce="0" hide-bottom-space
@filter="(inputValue: any, doneFn: Function) => filterSelector(inputValue, doneFn, 'prefixOps')" /> outlined
:rules="[(val: string) => !!val || `${'กรุณาเลือก คำนำหน้าชื่อ'}`]"
dense
lazy-rules
v-model="informaData.prefixId"
emit-value
map-options
option-label="name"
:options="Ops.prefixOps"
option-value="id"
:label="`${'คำนำหน้าชื่อ'}`"
use-input
input-debounce="0"
@filter="(inputValue: any, doneFn: Function) => filterSelector(inputValue, doneFn, 'prefixOps')"
/>
</div> </div>
<div class="col-xs-6 col-sm-3 col-md-3"> <div class="col-xs-6 col-sm-3 col-md-3">
<q-input for="#firstname" hide-bottom-space outlined dense lazy-rules v-model="informaData.firstname" <q-input
:rules="[(val: string) => !!val || `${'กรุณากรอก ชื่อ'}`]" :label="`${'ชื่อ'}`" /> for="#firstname"
hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.firstname"
:rules="[(val: string) => !!val || `${'กรุณากรอก ชื่อ'}`]"
:label="`${'ชื่อ'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-3 col-md-3"> <div class="col-xs-6 col-sm-3 col-md-3">
<q-input for="#lastname" hide-bottom-space outlined dense lazy-rules v-model="informaData.lastname" <q-input
:rules="[(val: string) => !!val || `${'กรุณากรอก นามสกุล'}`]" :label="`${'นามสกุล'}`" /> for="#lastname"
hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.lastname"
:rules="[(val: string) => !!val || `${'กรุณากรอก นามสกุล'}`]"
:label="`${'นามสกุล'}`"
/>
</div> </div>
</div> </div>
<div class="row col-12 q-col-gutter-x-sm q-mb-xs"> <div class="row col-12 q-col-gutter-x-sm q-mb-xs">
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<datepicker v-model="informaData.birthDate" :locale="'th'" autoApply :enableTimePicker="false" week-start="0" <datepicker
:max-date="calculateMaxDate()" @update:model-value="calRetire"> v-model="informaData.birthDate"
:locale="'th'"
autoApply
:enableTimePicker="false"
week-start="0"
:max-date="calculateMaxDate()"
@update:model-value="calRetire"
>
<template #year="{ year }"> <template #year="{ year }">
{{ year + 543 }} {{ year + 543 }}
</template> </template>
@ -394,13 +442,26 @@ const clickBack = () => {
{{ parseInt(value + 543) }} {{ parseInt(value + 543) }}
</template> </template>
<template #trigger> <template #trigger>
<q-input for="#birthDate" hide-bottom-space outlined dense lazy-rules :model-value="informaData.birthDate == null <q-input
? null for="#birthDate"
: date2Thai(informaData.birthDate) hide-bottom-space
" :rules="[(val: string) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`]" outlined
:label="`${'วัน/เดือน/ปี เกิด'}`"> dense
lazy-rules
:model-value="
informaData.birthDate == null
? null
: date2Thai(informaData.birthDate)
"
:rules="[(val: string) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`]"
:label="`${'วัน/เดือน/ปี เกิด'}`"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="event" class="cursor-pointer" style="color: var(--q-primary)"> <q-icon
name="event"
class="cursor-pointer"
style="color: var(--q-primary)"
>
</q-icon> </q-icon>
</template> </template>
</q-input> </q-input>
@ -408,55 +469,144 @@ const clickBack = () => {
</datepicker> </datepicker>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<q-input hide-bottom-space dense lazy-rules readonly borderless style="padding:0 12px;" <q-input
:model-value="informaData.age" :label="`${'อายุ'}`" /> hide-bottom-space
dense
lazy-rules
readonly
borderless
style="padding: 0 12px"
:model-value="informaData.age"
:label="`${'อายุ'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<selector for="#genderId" hide-bottom-space outlined dense lazy-rules v-model="informaData.genderId" emit-value map-options <selector
option-label="name" :options="Ops.genderOps" option-value="id" :label="`${'เพศ'}`" use-input for="#genderId"
input-debounce="0" @filter="(inputValue: any, hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.genderId"
emit-value
map-options
option-label="name"
:options="Ops.genderOps"
option-value="id"
:label="`${'เพศ'}`"
use-input
input-debounce="0"
@filter="(inputValue: any,
doneFn: Function) => filterSelector(inputValue, doneFn, 'genderOps' doneFn: Function) => filterSelector(inputValue, doneFn, 'genderOps'
)" /> )"
/>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<selector for="#statusId" hide-bottom-space outlined dense lazy-rules v-model="informaData.statusId" emit-value map-options <selector
option-label="name" :options="Ops.statusOps" option-value="id" :label="`${'สถานภาพ'}`" use-input for="#statusId"
input-debounce="0" @filter="(inputValue: any, hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.statusId"
emit-value
map-options
option-label="name"
:options="Ops.statusOps"
option-value="id"
:label="`${'สถานภาพ'}`"
use-input
input-debounce="0"
@filter="(inputValue: any,
doneFn: Function) => filterSelector(inputValue, doneFn, 'statusOps' doneFn: Function) => filterSelector(inputValue, doneFn, 'statusOps'
)" /> )"
/>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<q-input for="#nationality" hide-bottom-space outlined dense lazy-rules v-model="informaData.nationality" <q-input
:label="`${'สัญชาติ'}`" /> for="#nationality"
hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.nationality"
:label="`${'สัญชาติ'}`"
/>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<q-input for="#ethnicity" hide-bottom-space outlined dense lazy-rules v-model="informaData.ethnicity" <q-input
:label="`${'เชื้อชาติ'}`" /> for="#ethnicity"
hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.ethnicity"
:label="`${'เชื้อชาติ'}`"
/>
</div> </div>
</div> </div>
<div class="row col-12 q-col-gutter-x-sm q-mb-xs"> <div class="row col-12 q-col-gutter-x-sm q-mb-xs">
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<selector for="#religionId" hide-bottom-space outlined dense lazy-rules v-model="informaData.religionId" emit-value map-options <selector
option-label="name" :options="Ops.religionOps" option-value="id" :label="`${'ศาสนา'}`" use-input for="#religionId"
input-debounce="0" @filter="(inputValue: any, hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.religionId"
emit-value
map-options
option-label="name"
:options="Ops.religionOps"
option-value="id"
:label="`${'ศาสนา'}`"
use-input
input-debounce="0"
@filter="(inputValue: any,
doneFn: Function) => filterSelector(inputValue, doneFn, 'religionOps' doneFn: Function) => filterSelector(inputValue, doneFn, 'religionOps'
)" /> )"
/>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<selector for="#bloodId" hide-bottom-space outlined dense lazy-rules v-model="informaData.bloodId" emit-value map-options <selector
option-label="name" :options="Ops.bloodOps" option-value="id" :label="`${'หมู่เลือด'}`" use-input for="#bloodId"
input-debounce="0" @filter="(inputValue: any, hide-bottom-space
outlined
dense
lazy-rules
v-model="informaData.bloodId"
emit-value
map-options
option-label="name"
:options="Ops.bloodOps"
option-value="id"
:label="`${'หมู่เลือด'}`"
use-input
input-debounce="0"
@filter="(inputValue: any,
doneFn: Function) => filterSelector(inputValue, doneFn, 'bloodOps' doneFn: Function) => filterSelector(inputValue, doneFn, 'bloodOps'
)" clearable /> )"
clearable
/>
</div> </div>
<div class="col-xs-6 col-sm-2 col-md-2"> <div class="col-xs-6 col-sm-2 col-md-2">
<q-input for="#tel" hide-bottom-space outlined dense lazy-rules type="tel" v-model="informaData.tel" <q-input
:label="`${'เบอร์โทร'}`" :rules="[ for="#tel"
hide-bottom-space
outlined
dense
lazy-rules
type="tel"
v-model="informaData.tel"
:label="`${'เบอร์โทร'}`"
:rules="[
(val: string) => !!val || `${'กรุณากรอก เบอร์โทร'}`, (val: string) => !!val || `${'กรุณากรอก เบอร์โทร'}`,
(val: string) => (val: string) =>
val.length >= 10 || val.length >= 10 ||
`${'กรุณากรอกเบอร์โทรให้ครบ'}`, `${'กรุณากรอกเบอร์โทรให้ครบ'}`,
]" mask="##########" /> ]"
mask="##########"
/>
</div> </div>
</div> </div>
</div> </div>
@ -464,25 +614,60 @@ const clickBack = () => {
<div class="col-12 q-pt-md q-pb-sm"><q-separator /></div> <div class="col-12 q-pt-md q-pb-sm"><q-separator /></div>
<div class="row col-12"> <div class="row col-12">
<q-space /> <q-space />
<q-btn for="#submitForm" unelevated dense class="q-px-md items-center" color="light-blue-10" label="บันทึก" @click="saveData" /> <q-btn
for="#submitForm"
unelevated
dense
class="q-px-md items-center"
color="light-blue-10"
label="บันทึก"
@click="saveData"
/>
</div> </div>
</q-card> </q-card>
<!-- Header --> <!-- Header -->
<q-page-sticky position="top" expand class="bg-grey-2 text-white" style="z-index: 99; padding: 0% 1% 0% 1%"> <q-page-sticky
position="top"
expand
class="bg-grey-2 text-white"
style="z-index: 99; padding: 0% 1% 0% 1%"
>
<div class="row col-12 q-gutter-sm q-pb-sm text-dark no-wrap items-center"> <div class="row col-12 q-gutter-sm q-pb-sm text-dark no-wrap items-center">
<q-btn flat round class="bg-teal-1 full-height" color="primary" icon="mdi-chevron-left" dense <q-btn
@click="router.go(-1)"> flat
round
class="bg-teal-1 full-height"
color="primary"
icon="mdi-chevron-left"
dense
@click="router.go(-1)"
>
</q-btn> </q-btn>
<q-avatar size="65px" rounded class="containerimage"> <q-avatar size="65px" rounded class="containerimage">
<img v-if="image == null" src="@/assets/avatar_user.jpg" class="bg-grey-3" style="object-fit: cover" /> <img
v-if="image == null"
src="@/assets/avatar_user.jpg"
class="bg-grey-3"
style="object-fit: cover"
/>
<img :src="image" class="bg-grey-3" style="object-fit: cover" /> <img :src="image" class="bg-grey-3" style="object-fit: cover" />
<div class="overlay absolute-bottom text-subtitle2 text-center cursor-pointer" @click="addNewImage()"> <div
class="overlay absolute-bottom text-subtitle2 text-center cursor-pointer"
@click="addNewImage()"
>
<q-icon name="mdi-camera" size="18px" color="blue"> <q-icon name="mdi-camera" size="18px" color="blue">
<q-tooltip>ปเดตรปภาพ</q-tooltip> <q-tooltip>ปเดตรปภาพ</q-tooltip>
</q-icon> </q-icon>
<input for="#profile" type="file" style="display: none" ref="inputImage" accept="image/*" @change="uploadImage" /> <input
for="#profile"
type="file"
style="display: none"
ref="inputImage"
accept="image/*"
@change="uploadImage"
/>
</div> </div>
</q-avatar> </q-avatar>
@ -498,4 +683,4 @@ const clickBack = () => {
</div> </div>
</q-page-sticky> </q-page-sticky>
<!-- End Header --> <!-- End Header -->
</template> </template>

View file

@ -8,6 +8,12 @@ const mixin = useCounterMixin();
const { date2Thai } = mixin; const { date2Thai } = mixin;
const { filterFn, searchDataFn } = workStore; const { filterFn, searchDataFn } = workStore;
function calculateMaxDate() {
const today = new Date();
today.setDate(today.getDate() - 1);
return today;
}
</script> </script>
<template> <template>
@ -20,6 +26,7 @@ const { filterFn, searchDataFn } = workStore;
autoApply autoApply
:enableTimePicker="false" :enableTimePicker="false"
week-start="0" week-start="0"
:max-date="calculateMaxDate()"
@update:model-value=" @update:model-value="
searchDataFn(workStore.selectDate, workStore.selectStatus) searchDataFn(workStore.selectDate, workStore.selectStatus)
" "

View file

@ -2,116 +2,117 @@ import { defineStore } from "pinia";
import { ref } from "vue"; import { ref } from "vue";
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin";
import type { QTableProps } from "quasar"; import type { QTableProps } from "quasar";
import type { DataOption } from "@/modules/09_leave/interface/index/Main" import type { DataOption } from "@/modules/09_leave/interface/index/Main";
import type { TableRows, DataRes } from "@/modules/09_leave/interface/response/work" import type {
TableRows,
DataRes,
} from "@/modules/09_leave/interface/response/work";
const mixin = useCounterMixin(); const mixin = useCounterMixin();
const { date2Thai } = mixin; const { date2Thai } = mixin;
export const useWorklistDataStore = defineStore("work", () => { export const useWorklistDataStore = defineStore("work", () => {
// ข้อมูลในตาราง // ข้อมูลในตาราง
const rows = ref<TableRows[]>([]) const rows = ref<TableRows[]>([]);
const columns = ref<QTableProps["columns"]>([]); const columns = ref<QTableProps["columns"]>([]);
const visibleColumns = ref<string[]>([]); const visibleColumns = ref<string[]>([]);
const dataMain = ref<TableRows[]>([]) const dataMain = ref<TableRows[]>([]);
function fetchList(data: DataRes[]) { function fetchList(data: DataRes[]) {
let datalist: TableRows[] = data.map((e: DataRes) => ({ let datalist: TableRows[] = data.map((e: DataRes) => ({
fullName: e.fullName, fullName: e.fullName,
timeIn: e.timeIn, timeIn: e.timeIn,
coordinatesIn: e.coordinatesIn, coordinatesIn: e.coordinatesIn,
latIn: e.latIn, latIn: e.latIn,
longIn: e.longIn, longIn: e.longIn,
timeOut: e.timeOut, timeOut: e.timeOut,
coordinatesOut: e.coordinatesOut, coordinatesOut: e.coordinatesOut,
latOut: e.latOut, latOut: e.latOut,
longOut: e.longOut, longOut: e.longOut,
status: convertSatatus(e.status), status: convertSatatus(e.status),
date: date2Thai(e.date) date: date2Thai(e.date),
})) }));
dataMain.value = datalist dataMain.value = datalist;
fetchOption() fetchOption();
searchDataFn(selectDate.value, selectStatus.value) searchDataFn(selectDate.value, selectStatus.value);
} }
//ค้นหาข้อมูล
const filterTable = ref<string>("");
const selectDate = ref<Date | null>(new Date());
const selectStatus = ref<String>("all");
const optionStatusMain = ref<DataOption[]>([]);
const optionStatus = ref<DataOption[]>([]);
function searchDataFn(searchDate: any, searchStatus: any) {
searchStatus = searchStatus || "all";
if (searchDate == null && searchStatus == "all") {
rows.value = dataMain.value;
} else if (searchDate == null && searchStatus !== "all") {
rows.value = dataMain.value.filter((e: any) => e.status === searchStatus);
} else if (searchDate !== null && searchStatus == "all") {
rows.value = dataMain.value.filter(
(e: any) => e.date === date2Thai(searchDate)
);
} else {
rows.value = dataMain.value.filter(
(e: any) =>
e.date === date2Thai(searchDate) && e.status === searchStatus
);
}
}
//
function fetchOption() {
const double_status = [
...new Set(dataMain.value.map((item: any) => item.status)),
];
optionStatusMain.value = [{ id: "all", name: "ทั้งหมด" }];
for (let i = 1; i <= double_status.length; i++) {
const status = double_status[i - 1];
if (typeof status === "string") {
const listtype: DataOption = {
id: status,
name: status,
};
optionStatusMain.value.push(listtype);
optionStatus.value = optionStatusMain.value;
}
}
}
function filterFn(val: string, update: Function) {
if (val == "") {
update(() => {
optionStatus.value = optionStatusMain.value;
});
} else {
update(() => {
optionStatus.value = optionStatusMain.value.filter(
(e: any) => e.name.search(val) !== -1
);
});
}
}
// convertSatatus
function convertSatatus(val: string) {
switch (val) {
case "normal":
return "ปกติ";
case "late":
return "สาย";
case "absent":
return "ขาดราชการ";
}
}
return {
//ข้อมูลในตาราง
rows,
columns,
visibleColumns,
fetchList,
//ค้นหาข้อมูล //ค้นหาข้อมูล
const filterTable = ref<string>('') filterTable,
const selectDate = ref<Date | null>(new Date()); selectDate,
const selectStatus = ref<String>('all') selectStatus,
const optionStatusMain = ref<DataOption[]>([]) optionStatus,
const optionStatus = ref<DataOption[]>([]) searchDataFn,
function searchDataFn(searchDate: any, searchStatus: any) { filterFn,
let a = new Date(searchDate);// วันที่เลือก convertSatatus,
let b = new Date(); // วันที่ปัจจุบัน };
if (a > b) { });
selectDate.value = new Date()
searchDate = new Date()
}
searchStatus = searchStatus || "all";
if (searchDate == null && searchStatus == "all") {
rows.value = dataMain.value
} else if (searchDate == null && searchStatus !== "all") {
rows.value = dataMain.value.filter((e: any) => e.status === searchStatus)
} else if (searchDate !== null && searchStatus == "all") {
rows.value = dataMain.value.filter((e: any) => e.date === date2Thai(searchDate))
} else {
rows.value = dataMain.value.filter((e: any) => e.date === date2Thai(searchDate) && e.status === searchStatus)
}
}
//
function fetchOption() {
const double_status = [
...new Set(dataMain.value.map((item: any) => item.status)),
];
optionStatusMain.value = [{ id: "all", name: "ทั้งหมด" }];
for (let i = 1; i <= double_status.length; i++) {
const status = double_status[i - 1];
if (typeof status === 'string') {
const listtype: DataOption = {
id: status,
name: status,
};
optionStatusMain.value.push(listtype)
optionStatus.value = optionStatusMain.value
}
}
}
function filterFn(val: string, update: Function) {
if (val == "") {
update(() => {
optionStatus.value = optionStatusMain.value;
});
} else {
update(() => {
optionStatus.value = optionStatusMain.value.filter(
(e: any) => e.name.search(val) !== -1
);
});
}
}
// convertSatatus
function convertSatatus(val: string) {
switch (val) {
case "normal":
return "ปกติ"
case "late":
return "สาย"
case "absent":
return "ขาดราชการ"
}
}
return {
//ข้อมูลในตาราง
rows,
columns,
visibleColumns,
fetchList,
//ค้นหาข้อมูล
filterTable,
selectDate,
selectStatus,
optionStatus,
searchDataFn,
filterFn,
convertSatatus
};
})