เพิ่ม multiple upload ในไฟล์ฟอร์มการลา

เพิ่ม multiple upload
This commit is contained in:
AnandaTon 2024-01-10 14:35:46 +07:00
parent 8bdb84cd95
commit cf806db19f
24 changed files with 5549 additions and 6303 deletions

View file

@ -1,32 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch, computed, onMounted } from "vue"; import { ref, reactive, watch, computed, onMounted } from "vue"
import type { import type { FormData, FormRef } from "@/modules/05_leave/interface/request/SickForm"
FormData, import { useCounterMixin } from "@/stores/mixin"
FormRef, import { useLeaveStore } from "@/modules/05_leave/store"
} from "@/modules/05_leave/interface/request/SickForm"; import http from "@/plugins/http"
import { useCounterMixin } from "@/stores/mixin"; import config from "@/app.config"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useQuasar } from "quasar"
import http from "@/plugins/http"; import { useRouter } from "vue-router"
import config from "@/app.config";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const router = useRouter(); const router = useRouter()
const { const { date2Thai, dateToISO, dialogConfirm, success, messageError, fails, showLoader, hideLoader } = mixin
date2Thai, const edit = ref<boolean>(true)
dateToISO,
dialogConfirm,
success,
messageError,
fails,
showLoader,
hideLoader,
} = mixin;
const edit = ref<boolean>(true);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
@ -42,7 +30,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataSick = reactive<any>({ const formDataSick = reactive<any>({
@ -57,18 +45,19 @@ const formDataSick = reactive<any>({
leaveAddress: "", leaveAddress: "",
leaveDetail: "", leaveDetail: "",
leaveDocument: [], leaveDocument: [],
}); })
const leaveDocumentList = ref<any>()
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveRangeRef = ref<object | null>(null); const leaveRangeRef = ref<object | null>(null)
const leaveTotalRef = ref<object | null>(null); const leaveTotalRef = ref<object | null>(null)
const leaveLastRef = ref<object | null>(null); const leaveLastRef = ref<object | null>(null)
const leaveNumberRef = ref<object | null>(null); const leaveNumberRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = { const FormRef: FormRef = {
@ -80,66 +69,56 @@ const FormRef: FormRef = {
leaveNumber: leaveNumberRef, leaveNumber: leaveNumberRef,
leaveAddress: leaveAddressRef, leaveAddress: leaveAddressRef,
leaveDetail: leaveDetailRef, leaveDetail: leaveDetailRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
async function fileUploadDoc(files: any) { async function fileUploadDoc(files: any) {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
} }
/** /**
* function เซทค leaveStartDate เเละ leaveEndDate * function เซทค leaveStartDate เเละ leaveEndDate
*/ */
function resetDate() { function resetDate() {
if ( if (formDataSick.leaveRange === "MORNING" || formDataSick.leaveRange === "AFTERNOON") {
formDataSick.leaveRange === "MORNING" || formDataSick.leaveStartDate = null
formDataSick.leaveRange === "AFTERNOON" formDataSick.leaveEndDate = null
) {
formDataSick.leaveStartDate = null;
formDataSick.leaveEndDate = null;
} }
console.log("testnull"); console.log("testnull")
} }
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in FormRef) { for (const key in FormRef) {
if (Object.prototype.hasOwnProperty.call(FormRef, key)) { if (Object.prototype.hasOwnProperty.call(FormRef, key)) {
const property = FormRef[key]; const property = FormRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataSick.leaveDocument.length > 0) {
// const blob = formDataSick.leaveDocument.slice(
// 0,
// formDataSick.leaveDocument[0].size
// );
// const newFile = new File(blob, nameFile.value, {
// type: formDataSick.leaveDocument[0].type,
// });
// formData.append("leaveDocument", newFile);
// }
formData.append("leaveDocument", formDataSick.leaveDocument); formDataSick.leaveDocument.forEach((file: File) => {
formData.append("type", formDataSick.type); formData.append("leaveDocument", file)
formData.append("leaveRange", formDataSick.leaveRange); })
formData.append("leaveStartDate", dateToISO(formDataSick.leaveStartDate)); // formData.append("leaveDocument", formDataSick.leaveDocument)
formData.append("leaveEndDate", dateToISO(formDataSick.leaveEndDate)); formData.append("type", formDataSick.type)
formData.append("leaveWrote", formDataSick.leaveWrote); formData.append("leaveRange", formDataSick.leaveRange)
formData.append("leaveAddress", formDataSick.leaveAddress); formData.append("leaveStartDate", dateToISO(formDataSick.leaveStartDate))
formData.append("leaveNumber", formDataSick.leaveNumber); formData.append("leaveEndDate", dateToISO(formDataSick.leaveEndDate))
formData.append("leaveDetail", formDataSick.leaveDetail); formData.append("leaveWrote", formDataSick.leaveWrote)
props.onSubmit(formData); formData.append("leaveAddress", formDataSick.leaveAddress)
formData.append("leaveNumber", formDataSick.leaveNumber)
formData.append("leaveDetail", formDataSick.leaveDetail)
props.onSubmit(formData)
} }
} }
@ -147,7 +126,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -156,63 +135,60 @@ async function fetchCheck() {
EndLeaveDate: formDataSick.leaveEndDate ?? null, EndLeaveDate: formDataSick.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
formDataSick.leaveTotal = formDataSick.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
data.totalDate - data.sumDateWork - data.sumDateHoliday;
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* งกนแปลงครงว/งว * งกนแปลงครงว/งว
*/ */
const isReadOnly = computed(() => { const isReadOnly = computed(() => {
const conditionleaveRange = const conditionleaveRange = formDataSick.leaveRange === "MORNING" || formDataSick.leaveRange === "AFTERNOON"
formDataSick.leaveRange === "MORNING" ||
formDataSick.leaveRange === "AFTERNOON";
if (conditionleaveRange) { if (conditionleaveRange) {
formDataSick.leaveEndDate = formDataSick.leaveStartDate; // Set formDataSick.leaveEndDate to null formDataSick.leaveEndDate = formDataSick.leaveStartDate // Set formDataSick.leaveEndDate to null
formDataSick.leaveTotal = 0.5; formDataSick.leaveTotal = 0.5
} else { } else {
formDataSick.leaveTotal = null; formDataSick.leaveTotal = null
} }
return conditionleaveRange; return conditionleaveRange
}); })
function inputEdit(val: boolean) { function inputEdit(val: boolean) {
return { return {
"full-width cursor-pointer ": val, "full-width cursor-pointer ": val,
"full-width cursor-pointer inputgreen": !val, "full-width cursor-pointer inputgreen": !val,
}; }
} }
function resetEndDate(type: string) { function resetEndDate(type: string) {
if (type === "day") { if (type === "day") {
formDataSick.EndLeaveDate === null; formDataSick.EndLeaveDate === null
} }
} }
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataSick.leaveWrote = props.data.leaveWrote; formDataSick.leaveWrote = props.data.leaveWrote
formDataSick.leaveStartDate = new Date(props.data.leaveStartDate); formDataSick.leaveStartDate = new Date(props.data.leaveStartDate)
formDataSick.leaveEndDate = new Date(props.data.leaveEndDate); formDataSick.leaveEndDate = new Date(props.data.leaveEndDate)
formDataSick.contractTel = props.data.contractTel; formDataSick.contractTel = props.data.contractTel
formDataSick.leaveTotal = props.data.leaveTotal; formDataSick.leaveTotal = props.data.leaveTotal
formDataSick.leaveNumber = props.data.leaveNumber; formDataSick.leaveNumber = props.data.leaveNumber
formDataSick.leaveDetail = props.data.leaveDetail; formDataSick.leaveDetail = props.data.leaveDetail
// formDataSick.leaveDocument = props.data.leaveDocument; leaveDocumentList.value = props.data.leaveDocument
formDataSick.leaveAddress = props.data.leaveAddress; formDataSick.leaveAddress = props.data.leaveAddress
} }
}); })
</script> </script>
<!-- ฟอรมลาปวย และลากจสวนต --> <!-- ฟอรมลาปวย และลากจสวนต -->
@ -235,30 +211,13 @@ onMounted(() => {
v-model="formDataSick.leaveWrote" v-model="formDataSick.leaveWrote"
label="เขียนที่" label="เขียนที่"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<div class="col-12 col-md-4 col-sm-12"> <div class="col-12 col-md-4 col-sm-12">
<q-radio <q-radio v-model="formDataSick.leaveRange" val="ALL" label="ลาทั้งวัน" checked-icon="task_alt" />
v-model="formDataSick.leaveRange" <q-radio v-model="formDataSick.leaveRange" val="MORNING" label="ลาครึ่งวันเช้า" checked-icon="task_alt" @update:model-value="resetDate" />
val="ALL" <q-radio v-model="formDataSick.leaveRange" val="AFTERNOON" label="ลาครึ่งวันบ่าย" checked-icon="task_alt" @update:model-value="resetDate" />
label="ลาทั้งวัน"
checked-icon="task_alt"
/>
<q-radio
v-model="formDataSick.leaveRange"
val="MORNING"
label="ลาครึ่งวันเช้า"
checked-icon="task_alt"
@update:model-value="resetDate"
/>
<q-radio
v-model="formDataSick.leaveRange"
val="AFTERNOON"
label="ลาครึ่งวันบ่าย"
checked-icon="task_alt"
@update:model-value="resetDate"
/>
</div> </div>
<div class="full-width"> <div class="full-width">
<div class="q-col-gutter-sm row"> <div class="q-col-gutter-sm row">
@ -290,22 +249,13 @@ onMounted(() => {
:readonly="!edit" :readonly="!edit"
bg-color="white" bg-color="white"
class="full-width cursor-pointer inputgreen" class="full-width cursor-pointer inputgreen"
:model-value=" :model-value="formDataSick.leaveStartDate != null ? date2Thai(formDataSick.leaveStartDate) : null"
formDataSick.leaveStartDate != null
? date2Thai(formDataSick.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
style="color: var(--q-primary)" style="color: var(--q-primary)"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -340,21 +290,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!formDataSick.leaveStartDate" :readonly="!formDataSick.leaveStartDate"
:class="inputEdit(isReadOnly)" :class="inputEdit(isReadOnly)"
:model-value=" :model-value="formDataSick.leaveEndDate != null ? date2Thai(formDataSick.leaveEndDate) : null"
formDataSick.leaveEndDate != null
? date2Thai(formDataSick.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -400,9 +341,7 @@ onMounted(() => {
unmasked-value unmasked-value
label="หมายเลขโทรศัพท์ที่ติดต่อได้" label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`,
]"
/> />
<q-input <q-input
@ -414,9 +353,7 @@ onMounted(() => {
v-model="formDataSick.leaveAddress" v-model="formDataSick.leaveAddress"
label="ที่อยู่ที่ติดต่อได้ระหว่างลา" label="ที่อยู่ที่ติดต่อได้ระหว่างลา"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`]"
(val) => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`,
]"
hide-bottom-space hide-bottom-space
bg-color="white" bg-color="white"
/> />
@ -437,36 +374,47 @@ onMounted(() => {
<div class="full-width"> <div class="full-width">
<div class="q-col-gutter-sm row"> <div class="q-col-gutter-sm row">
<!-- multiple --> <!-- multiple -->
<q-file <q-file for="leaveDocumentRef" v-model="formDataSick.leaveDocument" dense label="เอกสารประกอบ" outlined use-chips multiple bg-color="white" class="col-12 q-pl-sm col-12">
for="leaveDocumentRef"
v-model="formDataSick.leaveDocument"
dense
label="เอกสารประกอบ"
outlined
use-chips
bg-color="white"
class="col-12 q-pl-sm col-12"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataSick.leaveDocument.length == 0 && !data">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div> -->
</div> </div>
</div> </div>
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
<div class="col-12 col-sm-6 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
v-for="(file, index) in formDataSick.leaveDocument"
:key="index"
class="q-my-xs"
>
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.name }} {{ file.name }}
@ -484,18 +432,11 @@ onMounted(() => {
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn
v-if="data" v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit" id="onSubmit"
type="button" type="button"
unelevated unelevated

View file

@ -1,21 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import type { FormRef } from "@/modules/05_leave/interface/request/BirthForm"; import type { FormRef } from "@/modules/05_leave/interface/request/BirthForm"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const router = useRouter(); const router = useRouter()
const $q = useQuasar(); const $q = useQuasar()
const { date2Thai, dateToISO, dialogConfirm, success, messageError, fails } = const { date2Thai, dateToISO, dialogConfirm, success, messageError, fails } = mixin
mixin; const edit = ref<boolean>(true)
const edit = ref<boolean>(true);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
@ -31,7 +30,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataBirth = reactive<any>({ const formDataBirth = reactive<any>({
@ -45,17 +44,17 @@ const formDataBirth = reactive<any>({
leaveAddress: "", leaveAddress: "",
leaveDetail: "", leaveDetail: "",
leaveDocument: [], leaveDocument: [],
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveTotalRef = ref<object | null>(null); const leaveTotalRef = ref<object | null>(null)
const leaveNumberRef = ref<object | null>(null); const leaveNumberRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = { const FormRef: FormRef = {
@ -67,48 +66,44 @@ const FormRef: FormRef = {
leaveAddress: leaveAddressRef, leaveAddress: leaveAddressRef,
leaveDetail: leaveDetailRef, leaveDetail: leaveDetailRef,
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
async function fileUploadDoc(files: any) { async function fileUploadDoc(files: any) {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
} }
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in FormRef) { for (const key in FormRef) {
if (Object.prototype.hasOwnProperty.call(FormRef, key)) { if (Object.prototype.hasOwnProperty.call(FormRef, key)) {
const property = FormRef[key]; const property = FormRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataBirth.leaveDocument.length > 0) { formDataBirth.leaveDocument.forEach((file: File) => {
// const blob = formDataBirth.leaveDocument.slice(0, formDataBirth.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataBirth.leaveDocument[0].type, // formData.append("leaveDocument", formDataBirth.leaveDocument);
// }) formData.append("type", formDataBirth.type)
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataBirth.leaveStartDate))
// } formData.append("leaveEndDate", dateToISO(formDataBirth.leaveEndDate))
formData.append("leaveDocument", formDataBirth.leaveDocument); formData.append("leaveWrote", formDataBirth.leaveWrote)
formData.append("type", formDataBirth.type); formData.append("leaveAddress", formDataBirth.leaveAddress)
formData.append("leaveStartDate", dateToISO(formDataBirth.leaveStartDate)); formData.append("leaveNumber", formDataBirth.leaveNumber)
formData.append("leaveEndDate", dateToISO(formDataBirth.leaveEndDate)); formData.append("leaveDetail", formDataBirth.leaveDetail)
formData.append("leaveWrote", formDataBirth.leaveWrote);
formData.append("leaveAddress", formDataBirth.leaveAddress);
formData.append("leaveNumber", formDataBirth.leaveNumber);
formData.append("leaveDetail", formDataBirth.leaveDetail);
props.onSubmit(formData); props.onSubmit(formData)
} }
} }
@ -116,7 +111,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -125,33 +120,35 @@ async function fetchCheck() {
EndLeaveDate: formDataBirth.leaveEndDate ?? null, EndLeaveDate: formDataBirth.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
formDataBirth.leaveTotal = data.totalDate; formDataBirth.leaveTotal = data.totalDate
// formDataBirth.leaveLast = data.sumDateWork // formDataBirth.leaveLast = data.sumDateWork
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataBirth.leaveWrote = props.data.leaveWrote; formDataBirth.leaveWrote = props.data.leaveWrote
formDataBirth.leaveStartDate = props.data.leaveStartDate; formDataBirth.leaveStartDate = props.data.leaveStartDate
formDataBirth.leaveEndDate = props.data.leaveEndDate; formDataBirth.leaveEndDate = props.data.leaveEndDate
formDataBirth.leaveTotal = props.data.leaveTotal; formDataBirth.leaveTotal = props.data.leaveTotal
formDataBirth.leaveNumber = props.data.leaveNumber; formDataBirth.leaveNumber = props.data.leaveNumber
formDataBirth.leaveAddress = props.data.leaveAddress; formDataBirth.leaveAddress = props.data.leaveAddress
formDataBirth.leaveDetail = props.data.leaveDetail; formDataBirth.leaveDetail = props.data.leaveDetail
// formDataBirth.leaveDocument = props.data.leaveDocument; leaveDocumentList.value = props.data.leaveDocument
} }
}); })
</script> </script>
<!-- ฟอรมลาคลอดบตร--> <!-- ฟอรมลาคลอดบตร-->
@ -174,7 +171,7 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -206,21 +203,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataBirth.leaveStartDate != null ? date2Thai(formDataBirth.leaveStartDate) : null"
formDataBirth.leaveStartDate != null
? date2Thai(formDataBirth.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -256,21 +244,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!formDataBirth.leaveStartDate" :readonly="!formDataBirth.leaveStartDate"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataBirth.leaveEndDate != null ? date2Thai(formDataBirth.leaveEndDate) : null"
formDataBirth.leaveEndDate != null
? date2Thai(formDataBirth.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -314,9 +293,7 @@ onMounted(() => {
unmasked-value unmasked-value
label="หมายเลขโทรศัพท์ที่ติดต่อได้" label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`,
]"
/> />
<q-input <q-input
@ -330,9 +307,7 @@ onMounted(() => {
v-model="formDataBirth.leaveAddress" v-model="formDataBirth.leaveAddress"
label="ที่อยู่ที่ติดต่อได้ระหว่างลา" label="ที่อยู่ที่ติดต่อได้ระหว่างลา"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`]"
(val) => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`,
]"
/> />
</div> </div>
</div> </div>
@ -359,28 +334,59 @@ onMounted(() => {
bg-color="white" bg-color="white"
label="เอกสารประกอบ" label="เอกสารประกอบ"
outlined outlined
multiple
use-chips use-chips
class="q-pl-sm col-12" class="q-pl-sm col-12"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataBirth.leaveDocument.length == 0">
<div class="col-12 row" v-if="!edit"> <q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> </div> -->
<div class="q-pl-sm text-weight-bold text-dark"> <!-- <div class="col-12" v-if="formDataBirth.leaveDocument.length">
เอกสารเพมเต <q-card bordered>
<q-list separator>
<q-item v-for="(file, index) in formDataBirth.leaveDocument" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="full-width ellipsis">
{{ file.name }}
</q-item-label>
<q-item-label caption> </q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div> -->
<div class="col-12 row" v-if="data">
<!-- <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div> -->
<q-card bordered flat class="full-width">
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div> </div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
<div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
v-for="(file, index) in formDataBirth.leaveDocument"
:key="index"
class="q-my-xs"
>
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.name }} {{ file.name }}
@ -398,26 +404,10 @@ onMounted(() => {
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,31 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue"
import type { import type { FormData, FormRef } from "@/modules/05_leave/interface/request/HelpWifeForm"
FormData, import { useCounterMixin } from "@/stores/mixin"
FormRef, import { useLeaveStore } from "@/modules/05_leave/store"
} from "@/modules/05_leave/interface/request/HelpWifeForm"; import http from "@/plugins/http"
import { useCounterMixin } from "@/stores/mixin"; import config from "@/app.config"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useQuasar } from "quasar"
import http from "@/plugins/http"; import { useRouter } from "vue-router"
import config from "@/app.config";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const router = useRouter(); const router = useRouter()
const $q = useQuasar(); const $q = useQuasar()
const { const { date2Thai, calculateDurationYmd, dateToISO, dialogConfirm, fails, success, messageError } = mixin
date2Thai, const edit = ref<boolean>(true)
calculateDurationYmd,
dateToISO,
dialogConfirm,
fails,
success,
messageError,
} = mixin;
const edit = ref<boolean>(true);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
@ -41,7 +30,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataHelpWife = reactive<any>({ const formDataHelpWife = reactive<any>({
@ -56,19 +45,19 @@ const formDataHelpWife = reactive<any>({
leaveAddress: "", leaveAddress: "",
leaveDetail: "", leaveDetail: "",
leaveDocument: [], leaveDocument: [],
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const wifeDayNameRef = ref<object | null>(null); const wifeDayNameRef = ref<object | null>(null)
const wifeDayDateBornRef = ref<object | null>(null); const wifeDayDateBornRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveTotalRef = ref<object | null>(null); const leaveTotalRef = ref<object | null>(null)
const leaveNumberRef = ref<object | null>(null); const leaveNumberRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = { const FormRef: FormRef = {
@ -82,55 +71,45 @@ const FormRef: FormRef = {
leaveAddress: leaveAddressRef, leaveAddress: leaveAddressRef,
leaveDetail: leaveDetailRef, leaveDetail: leaveDetailRef,
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in FormRef) { for (const key in FormRef) {
if (Object.prototype.hasOwnProperty.call(FormRef, key)) { if (Object.prototype.hasOwnProperty.call(FormRef, key)) {
const property = FormRef[key]; const property = FormRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataHelpWife.leaveDocument.length > 0) { formDataHelpWife.leaveDocument.forEach((file: File) => {
// const blob = formDataHelpWife.leaveDocument.slice(0, formDataHelpWife.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataHelpWife.leaveDocument[0].type, formData.append("leaveDocument", formDataHelpWife.leaveDocument)
// }) formData.append("type", formDataHelpWife.type)
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataHelpWife.leaveStartDate))
// } formData.append("leaveEndDate", dateToISO(formDataHelpWife.leaveEndDate))
formData.append("leaveDocument", formDataHelpWife.leaveDocument); formData.append("leaveWrote", formDataHelpWife.leaveWrote)
formData.append("type", formDataHelpWife.type); formData.append("leaveAddress", formDataHelpWife.leaveAddress)
formData.append( formData.append("leaveNumber", formDataHelpWife.leaveNumber)
"leaveStartDate", formData.append("leaveDetail", formDataHelpWife.leaveDetail)
dateToISO(formDataHelpWife.leaveStartDate) formData.append("wifeDayName", formDataHelpWife.wifeDayName)
); formData.append("wifeDayDateBorn", dateToISO(formDataHelpWife.wifeDayDateBorn))
formData.append("leaveEndDate", dateToISO(formDataHelpWife.leaveEndDate)); props.onSubmit(formData)
formData.append("leaveWrote", formDataHelpWife.leaveWrote);
formData.append("leaveAddress", formDataHelpWife.leaveAddress);
formData.append("leaveNumber", formDataHelpWife.leaveNumber);
formData.append("leaveDetail", formDataHelpWife.leaveDetail);
formData.append("wifeDayName", formDataHelpWife.wifeDayName);
formData.append(
"wifeDayDateBorn",
dateToISO(formDataHelpWife.wifeDayDateBorn)
);
props.onSubmit(formData);
} }
} }
@ -138,18 +117,15 @@ function onValidate() {
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataHelpWife.leaveStartDate, formDataHelpWife.leaveEndDate)
formDataHelpWife.leaveStartDate, formDataHelpWife.leaveTotal = newLeaveTotal
formDataHelpWife.leaveEndDate
);
formDataHelpWife.leaveTotal = newLeaveTotal;
} }
/** /**
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -158,37 +134,39 @@ async function fetchCheck() {
EndLeaveDate: formDataHelpWife.leaveEndDate ?? null, EndLeaveDate: formDataHelpWife.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
formDataHelpWife.leaveTotal = formDataHelpWife.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
data.totalDate - data.sumDateWork - data.sumDateHoliday;
// formDataHelpWife.leaveLast = data.totalDate // formDataHelpWife.leaveLast = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
// console.log("data==>", props.data) // console.log("data==>", props.data)
formDataHelpWife.leaveWrote = props.data.leaveWrote; formDataHelpWife.leaveWrote = props.data.leaveWrote
formDataHelpWife.wifeDayName = props.data.wifeDayName; formDataHelpWife.wifeDayName = props.data.wifeDayName
formDataHelpWife.wifeDayDateBorn = props.data.wifeDayDateBorn; formDataHelpWife.wifeDayDateBorn = props.data.wifeDayDateBorn
formDataHelpWife.leaveStartDate = props.data.leaveStartDate; formDataHelpWife.leaveStartDate = props.data.leaveStartDate
formDataHelpWife.leaveEndDate = props.data.leaveEndDate; formDataHelpWife.leaveEndDate = props.data.leaveEndDate
formDataHelpWife.leaveTotal = props.data.leaveTotal; formDataHelpWife.leaveTotal = props.data.leaveTotal
formDataHelpWife.leaveNumber = props.data.leaveNumber; formDataHelpWife.leaveNumber = props.data.leaveNumber
formDataHelpWife.leaveAddress = props.data.leaveAddress; formDataHelpWife.leaveAddress = props.data.leaveAddress
formDataHelpWife.leaveDetail = props.data.leaveDetail; formDataHelpWife.leaveDetail = props.data.leaveDetail
leaveDocumentList.value = props.data.leaveDocument
// formDataHelpWife.leaveDocument = props.data.leaveDocument; // formDataHelpWife.leaveDocument = props.data.leaveDocument;
} }
}); })
</script> </script>
<template> <template>
@ -210,7 +188,7 @@ onMounted(() => {
v-model="formDataHelpWife.leaveWrote" v-model="formDataHelpWife.leaveWrote"
label="เขียนที่" label="เขียนที่"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
class="col-12 col-md-4 col-sm-12 cursor-pointer inputgreen" class="col-12 col-md-4 col-sm-12 cursor-pointer inputgreen"
@ -241,21 +219,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataHelpWife.leaveStartDate != null ? date2Thai(formDataHelpWife.leaveStartDate) : null"
formDataHelpWife.leaveStartDate != null
? date2Thai(formDataHelpWife.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -291,21 +260,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!formDataHelpWife.leaveStartDate" :readonly="!formDataHelpWife.leaveStartDate"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataHelpWife.leaveEndDate != null ? date2Thai(formDataHelpWife.leaveEndDate) : null"
formDataHelpWife.leaveEndDate != null
? date2Thai(formDataHelpWife.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -334,7 +294,7 @@ onMounted(() => {
v-model="formDataHelpWife.wifeDayName" v-model="formDataHelpWife.wifeDayName"
label="ชื่อภรรยา" label="ชื่อภรรยา"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'ชื่อภรรยา'}`]" :rules="[val => !!val || `${'ชื่อภรรยา'}`]"
/> />
</div> </div>
@ -366,21 +326,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataHelpWife.wifeDayDateBorn != null ? date2Thai(formDataHelpWife.wifeDayDateBorn) : null"
formDataHelpWife.wifeDayDateBorn != null
? date2Thai(formDataHelpWife.wifeDayDateBorn)
: null
"
:label="`${'วันที่คลอด'}`" :label="`${'วันที่คลอด'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่คลอด'}`]" :rules="[val => !!val || `${'กรุณาเลือกวันที่คลอด'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -400,9 +351,7 @@ onMounted(() => {
bg-color="white" bg-color="white"
label="หมายเลขโทรศัพท์ที่ติดต่อได้" label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`,
]"
/> />
<q-input <q-input
@ -416,9 +365,7 @@ onMounted(() => {
v-model="formDataHelpWife.leaveAddress" v-model="formDataHelpWife.leaveAddress"
label="ที่อยู่ที่ติดต่อได้ระหว่างลา" label="ที่อยู่ที่ติดต่อได้ระหว่างลา"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`]"
(val) => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`,
]"
/> />
</div> </div>
</div> </div>
@ -437,36 +384,58 @@ onMounted(() => {
/> />
<!-- multiple --> <!-- multiple -->
<q-file <q-file bg-color="white" ref="leaveDocumentRef" v-model="formDataHelpWife.leaveDocument" @added="fileUploadDoc" dense label="เอกสารประกอบ" outlined use-chips class="q-pl-sm col-12">
bg-color="white"
ref="leaveDocumentRef"
v-model="formDataHelpWife.leaveDocument"
@added="fileUploadDoc"
dense
label="เอกสารประกอบ"
outlined
use-chips
class="q-pl-sm col-12"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<div class="col-12" v-if="data">
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-md-12 col-sm-12">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <q-card bordered>
<div class="q-pl-sm text-weight-bold text-dark"> <!-- <div class="col-12">
เอกสารเพมเต <q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div> </div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
<div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
v-for="(file, index) in formDataHelpWife.leaveDocument" <q-item-section>
:key="index" <q-item-label class="full-width ellipsis">
class="q-my-xs" {{ file.name }}
> </q-item-label>
<q-item-label caption> </q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
<div class="col-12 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div>
<q-card bordered flat class="full-width">
<q-list separator>
<q-item v-for="(file, index) in formDataHelpWife.leaveDocument" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.name }} {{ file.name }}
@ -483,26 +452,10 @@ onMounted(() => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,24 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, onMounted, computed } from "vue"; import { ref, reactive, onMounted, computed } from "vue"
import type { import type { FormData, FormRef } from "@/modules/05_leave/interface/request/VacationForm"
FormData, import { useCounterMixin } from "@/stores/mixin"
FormRef, import { useLeaveStore } from "@/modules/05_leave/store"
} from "@/modules/05_leave/interface/request/VacationForm"; import http from "@/plugins/http"
import { useCounterMixin } from "@/stores/mixin"; import config from "@/app.config"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useQuasar } from "quasar"
import http from "@/plugins/http"; import { useRouter } from "vue-router"
import config from "@/app.config";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
/** Use */ /** Use */
const $q = useQuasar(); const $q = useQuasar()
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const router = useRouter(); const router = useRouter()
const { date2Thai, dateToISO, dialogConfirm, success, messageError, fails } = const { date2Thai, dateToISO, dialogConfirm, success, messageError, fails } = mixin
mixin; const edit = ref<boolean>(true)
const edit = ref<boolean>(true);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
@ -34,7 +30,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataVacation = reactive<any>({ const formDataVacation = reactive<any>({
@ -50,20 +46,20 @@ const formDataVacation = reactive<any>({
leaveAddress: "", leaveAddress: "",
leaveDetail: "", leaveDetail: "",
leaveDocument: [], leaveDocument: [],
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const restDayOldTotalRef = ref<object | null>(null); const restDayOldTotalRef = ref<object | null>(null)
const restDayCurrentTotalRef = ref<object | null>(null); const restDayCurrentTotalRef = ref<object | null>(null)
const leaveRangeRef = ref<object | null>(null); const leaveRangeRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveTotalRef = ref<object | null>(null); const leaveTotalRef = ref<object | null>(null)
const leaveNumberRef = ref<object | null>(null); const leaveNumberRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = { const FormRef: FormRef = {
@ -78,51 +74,44 @@ const FormRef: FormRef = {
leaveAddress: leaveAddressRef, leaveAddress: leaveAddressRef,
leaveDetail: leaveDetailRef, leaveDetail: leaveDetailRef,
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in FormRef) { for (const key in FormRef) {
if (Object.prototype.hasOwnProperty.call(FormRef, key)) { if (Object.prototype.hasOwnProperty.call(FormRef, key)) {
const property = FormRef[key]; const property = FormRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataVacation.leaveDocument.length > 0) { formDataVacation.leaveDocument.forEach((file: File) => {
// const blob = formDataVacation.leaveDocument.slice(0, formDataVacation.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataVacation.leaveDocument[0].type, // formData.append("leaveDocument", formDataVacation.leaveDocument);
// }) formData.append("type", formDataVacation.type)
// formData.append("leaveDocument", newFile) formData.append("leaveRange", formDataVacation.leaveRange)
// } formData.append("leaveStartDate", dateToISO(formDataVacation.leaveStartDate))
formData.append("leaveDocument", formDataVacation.leaveDocument); formData.append("leaveEndDate", dateToISO(formDataVacation.leaveEndDate))
formData.append("type", formDataVacation.type); formData.append("leaveWrote", formDataVacation.leaveWrote)
formData.append("leaveRange", formDataVacation.leaveRange); formData.append("leaveAddress", formDataVacation.leaveAddress)
formData.append( formData.append("leaveNumber", formDataVacation.leaveNumber)
"leaveStartDate", formData.append("leaveDetail", formDataVacation.leaveDetail)
dateToISO(formDataVacation.leaveStartDate) props.onSubmit(formData)
);
formData.append("leaveEndDate", dateToISO(formDataVacation.leaveEndDate));
formData.append("leaveWrote", formDataVacation.leaveWrote);
formData.append("leaveAddress", formDataVacation.leaveAddress);
formData.append("leaveNumber", formDataVacation.leaveNumber);
formData.append("leaveDetail", formDataVacation.leaveDetail);
props.onSubmit(formData);
} }
} }
@ -130,7 +119,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -139,65 +128,61 @@ async function fetchCheck() {
EndLeaveDate: formDataVacation.leaveEndDate ?? null, EndLeaveDate: formDataVacation.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
formDataVacation.leaveTotal = formDataVacation.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
data.totalDate - data.sumDateWork - data.sumDateHoliday;
// formDataVacation.leaveLast = data.totalDate // formDataVacation.leaveLast = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function เซทค leaveStartDate เเละ leaveEndDate * function เซทค leaveStartDate เเละ leaveEndDate
*/ */
function resetDate() { function resetDate() {
if ( if (formDataVacation.leaveRange === "MORNING" || formDataVacation.leaveRange === "AFTERNOON") {
formDataVacation.leaveRange === "MORNING" || formDataVacation.leaveStartDate = null
formDataVacation.leaveRange === "AFTERNOON" formDataVacation.leaveEndDate = null
) {
formDataVacation.leaveStartDate = null;
formDataVacation.leaveEndDate = null;
} }
console.log("testnull"); console.log("testnull")
} }
/** ฟังก์ชั่นแปลงค่า ครึ่งวัน/ทั้งวัน */ /** ฟังก์ชั่นแปลงค่า ครึ่งวัน/ทั้งวัน */
const isReadOnly = computed(() => { const isReadOnly = computed(() => {
const conditionleaveRange = const conditionleaveRange = formDataVacation.leaveRange === "MORNING" || formDataVacation.leaveRange === "AFTERNOON"
formDataVacation.leaveRange === "MORNING" ||
formDataVacation.leaveRange === "AFTERNOON";
if (conditionleaveRange) { if (conditionleaveRange) {
formDataVacation.leaveEndDate = formDataVacation.leaveStartDate; // Set formDataVacation.leaveEndDate to null formDataVacation.leaveEndDate = formDataVacation.leaveStartDate // Set formDataVacation.leaveEndDate to null
formDataVacation.leaveTotal = 0.5; formDataVacation.leaveTotal = 0.5
} else { } else {
formDataVacation.leaveTotal = null; formDataVacation.leaveTotal = null
} }
return conditionleaveRange; return conditionleaveRange
}); })
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
// console.log("data==>", props.data) // console.log("data==>", props.data)
formDataVacation.leaveWrote = props.data.leaveWrote; formDataVacation.leaveWrote = props.data.leaveWrote
formDataVacation.restDayOldTotal = props.data.restDayOldTotal; formDataVacation.restDayOldTotal = props.data.restDayOldTotal
formDataVacation.restDayCurrentTotal = props.data.restDayCurrentTotal; formDataVacation.restDayCurrentTotal = props.data.restDayCurrentTotal
formDataVacation.leaveStartDate = props.data.leaveStartDate; formDataVacation.leaveStartDate = props.data.leaveStartDate
formDataVacation.leaveEndDate = props.data.leaveEndDate; formDataVacation.leaveEndDate = props.data.leaveEndDate
formDataVacation.leaveTotal = props.data.leaveTotal; formDataVacation.leaveTotal = props.data.leaveTotal
formDataVacation.leaveNumber = props.data.leaveNumber; formDataVacation.leaveNumber = props.data.leaveNumber
formDataVacation.leaveAddress = props.data.leaveAddress; formDataVacation.leaveAddress = props.data.leaveAddress
formDataVacation.leaveDetail = props.data.leaveDetail; formDataVacation.leaveDetail = props.data.leaveDetail
leaveDocumentList.value = props.data.leaveDocument
// formDataVacation.leaveDocument = props.data.leaveDocument; // formDataVacation.leaveDocument = props.data.leaveDocument;
} }
}); })
</script> </script>
<template> <template>
@ -219,29 +204,12 @@ onMounted(() => {
v-model="formDataVacation.leaveWrote" v-model="formDataVacation.leaveWrote"
label="เขียนที่" label="เขียนที่"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<div class="col-12 col-md-4 col-sm-6"> <div class="col-12 col-md-4 col-sm-6">
<q-radio <q-radio v-model="formDataVacation.leaveRange" val="ALL" label="ลาทั้งวัน" checked-icon="task_alt" />
v-model="formDataVacation.leaveRange" <q-radio v-model="formDataVacation.leaveRange" val="MORNING" label="ลาครึ่งวันเช้า" checked-icon="task_alt" @update:model-value="resetDate" />
val="ALL" <q-radio v-model="formDataVacation.leaveRange" val="AFTERNOON" label="ลาครึ่งวันบ่าย" checked-icon="task_alt" @update:model-value="resetDate" />
label="ลาทั้งวัน"
checked-icon="task_alt"
/>
<q-radio
v-model="formDataVacation.leaveRange"
val="MORNING"
label="ลาครึ่งวันเช้า"
checked-icon="task_alt"
@update:model-value="resetDate"
/>
<q-radio
v-model="formDataVacation.leaveRange"
val="AFTERNOON"
label="ลาครึ่งวันบ่าย"
checked-icon="task_alt"
@update:model-value="resetDate"
/>
</div> </div>
<q-input <q-input
class="col-12 col-md-4 col-sm-6" class="col-12 col-md-4 col-sm-6"
@ -298,21 +266,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataVacation.leaveStartDate != null ? date2Thai(formDataVacation.leaveStartDate) : null"
formDataVacation.leaveStartDate != null
? date2Thai(formDataVacation.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -348,21 +307,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
class="full-width datepicker" class="full-width datepicker"
:readonly="isReadOnly" :readonly="isReadOnly"
:model-value=" :model-value="formDataVacation.leaveEndDate != null ? date2Thai(formDataVacation.leaveEndDate) : null"
formDataVacation.leaveEndDate != null
? date2Thai(formDataVacation.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -394,9 +344,7 @@ onMounted(() => {
unmasked-value unmasked-value
label="หมายเลขโทรศัพท์ที่ติดต่อได้" label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`,
]"
/> />
<q-input <q-input
@ -410,9 +358,7 @@ onMounted(() => {
v-model="formDataVacation.leaveAddress" v-model="formDataVacation.leaveAddress"
label="ที่อยู่ที่ติดต่อได้ระหว่างลา" label="ที่อยู่ที่ติดต่อได้ระหว่างลา"
:readonly="!edit" :readonly="!edit"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`]"
(val) => !!val || `${'กรุณากรอกที่อยู่ที่ติดต่อได้ระหว่างลา'}`,
]"
/> />
</div> </div>
</div> </div>
@ -429,7 +375,8 @@ onMounted(() => {
label="รายละเอียด" label="รายละเอียด"
:readonly="!edit" :readonly="!edit"
/> />
<div class="full-width">
<div class="q-col-gutter-sm row">
<!-- multiple --> <!-- multiple -->
<q-file <q-file
ref="leaveDocumentRef" ref="leaveDocumentRef"
@ -438,29 +385,50 @@ onMounted(() => {
@added="fileUploadDoc" @added="fileUploadDoc"
dense dense
label="เอกสารประกอบ" label="เอกสารประกอบ"
multiple
outlined outlined
use-chips use-chips
class="q-pl-sm col-12" class="q-pl-sm col-12"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataVacation.leaveDocument.length == 0">
<div class="col-12 row" v-if="!edit"> <q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> </div> -->
<div class="q-pl-sm text-weight-bold text-dark">
เอกสารเพมเต
</div> </div>
</div> </div>
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
<div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
v-for="(file, index) in formDataVacation.leaveDocument"
:key="index"
class="q-my-xs"
>
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.name }} {{ file.name }}
@ -477,26 +445,10 @@ onMounted(() => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,34 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, onMounted } from "vue"; import { reactive, ref, onMounted } from "vue"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import type { OrdinationForm } from "@/modules/05_leave/interface/request/AddAbsence"; import type { OrdinationForm } from "@/modules/05_leave/interface/request/AddAbsence"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const router = useRouter(); const router = useRouter()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { const { date2Thai, dialogConfirm, calculateDurationYmd, fails, dateToISO, success, messageError } = mixin
date2Thai, const edit = ref<boolean>(true)
dialogConfirm, const files = ref<any>(null)
calculateDurationYmd,
fails,
dateToISO,
success,
messageError,
} = mixin;
const edit = ref<boolean>(true);
const files = ref<any>(null);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Object,
default: null, default: null,
}, },
onSubmit: { onSubmit: {
@ -39,22 +31,22 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const ordainDayLocationNumberRef = ref<object | null>(null); const ordainDayLocationNumberRef = ref<object | null>(null)
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const leavebirthDateRef = ref<object | null>(null); const leavebirthDateRef = ref<object | null>(null)
const leavegovernmentDateRef = ref<object | null>(null); const leavegovernmentDateRef = ref<object | null>(null)
const totalLeaveRef = ref<object | null>(null); const totalLeaveRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const ordainDayOrdinationRef = ref<object | null>(null); const ordainDayOrdinationRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const ordainDayLocationAddressRef = ref<object | null>(null); const ordainDayLocationAddressRef = ref<object | null>(null)
const ordainDayBuddhistLentAddressRef = ref<object | null>(null); const ordainDayBuddhistLentAddressRef = ref<object | null>(null)
const ordainDayLocationNameRef = ref<object | null>(null); const ordainDayLocationNameRef = ref<object | null>(null)
const ordainDayBuddhistLentNameRef = ref<object | null>(null); const ordainDayBuddhistLentNameRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataOrdination = reactive<any>({ const formDataOrdination = reactive<any>({
@ -73,13 +65,13 @@ const formDataOrdination = reactive<any>({
ordainDayBuddhistLentAddress: "", ordainDayBuddhistLentAddress: "",
ordainDayStatus: "true", ordainDayStatus: "true",
leaveDocument: null, leaveDocument: null,
}); })
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const formRef: OrdinationForm = { const formRef: OrdinationForm = {
leaveWrote: leaveWroteRef, leaveWrote: leaveWroteRef,
// leavegovernmentDate: leavegovernmentDateRef, leavegovernmentDate: leavegovernmentDateRef,
// leavebirthDate: leavebirthDateRef, leavebirthDate: leavebirthDateRef,
leaveStartDate: leaveStartDateRef, leaveStartDate: leaveStartDateRef,
leaveEndDate: leaveEndDateRef, leaveEndDate: leaveEndDateRef,
totalLeave: totalLeaveRef, totalLeave: totalLeaveRef,
@ -90,73 +82,48 @@ const formRef: OrdinationForm = {
ordainDayBuddhistLentName: ordainDayBuddhistLentNameRef, ordainDayBuddhistLentName: ordainDayBuddhistLentNameRef,
ordainDayBuddhistLentAddress: ordainDayBuddhistLentAddressRef, ordainDayBuddhistLentAddress: ordainDayBuddhistLentAddressRef,
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */ /** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in formRef) { for (const key in formRef) {
if (Object.prototype.hasOwnProperty.call(formRef, key)) { if (Object.prototype.hasOwnProperty.call(formRef, key)) {
const property = formRef[key]; const property = formRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataOrdination.leaveDocument.length > 0) { formDataOrdination.leaveDocument.forEach((file: File) => {
// const blob = formDataOrdination.leaveDocument.slice(0, formDataOrdination.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataOrdination.leaveDocument[0].type, // formData.append("leaveDocument", formDataOrdination.leaveDocument);
// }) formData.append("type", formDataOrdination.type)
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataOrdination.leaveStartDate))
// } formData.append("leaveEndDate", dateToISO(formDataOrdination.leaveEndDate))
formData.append("leaveDocument", formDataOrdination.leaveDocument); formData.append("ordainDayOrdination", dateToISO(formDataOrdination.ordainDayOrdination))
formData.append("type", formDataOrdination.type); formData.append("ordainDayLocationName", formDataOrdination.ordainDayLocationName)
formData.append( formData.append("ordainDayLocationNumber", formDataOrdination.ordainDayLocationNumber)
"leaveStartDate", formData.append("ordainDayLocationAddress", formDataOrdination.ordainDayLocationAddress)
dateToISO(formDataOrdination.leaveStartDate) formData.append("ordainDayBuddhistLentName", formDataOrdination.ordainDayBuddhistLentName)
); formData.append("ordainDayBuddhistLentAddress", formDataOrdination.ordainDayBuddhistLentAddress)
formData.append("leaveEndDate", dateToISO(formDataOrdination.leaveEndDate)); formData.append("ordainDayStatus", formDataOrdination.ordainDayStatus)
formData.append( formData.append("leaveWrote", formDataOrdination.leaveWrote)
"ordainDayOrdination", formData.append("leaveDetail", formDataOrdination.leaveDetail)
dateToISO(formDataOrdination.ordainDayOrdination) props.onSubmit(formData)
);
formData.append(
"ordainDayLocationName",
formDataOrdination.ordainDayLocationName
);
formData.append(
"ordainDayLocationNumber",
formDataOrdination.ordainDayLocationNumber
);
formData.append(
"ordainDayLocationAddress",
formDataOrdination.ordainDayLocationAddress
);
formData.append(
"ordainDayBuddhistLentName",
formDataOrdination.ordainDayBuddhistLentName
);
formData.append(
"ordainDayBuddhistLentAddress",
formDataOrdination.ordainDayBuddhistLentAddress
);
formData.append("ordainDayStatus", formDataOrdination.ordainDayStatus);
formData.append("leaveWrote", formDataOrdination.leaveWrote);
formData.append("leaveDetail", formDataOrdination.leaveDetail);
props.onSubmit(formData);
} }
} }
@ -164,7 +131,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -173,53 +140,48 @@ async function fetchCheck() {
EndLeaveDate: formDataOrdination.leaveEndDate ?? null, EndLeaveDate: formDataOrdination.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataOrdination.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday // formDataOrdination.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
formDataOrdination.leaveTotal = data.totalDate; formDataOrdination.leaveTotal = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataOrdination.leaveStartDate, formDataOrdination.leaveEndDate)
formDataOrdination.leaveStartDate, formDataOrdination.leaveTotal = newLeaveTotal
formDataOrdination.leaveEndDate
);
formDataOrdination.leaveTotal = newLeaveTotal;
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataOrdination.leaveWrote = props.data.leaveWrote; formDataOrdination.leaveWrote = props.data.leaveWrote
formDataOrdination.leaveStartDate = props.data.leaveStartDate; formDataOrdination.leaveStartDate = props.data.leaveStartDate
formDataOrdination.leaveEndDate = props.data.leaveEndDate; formDataOrdination.leaveEndDate = props.data.leaveEndDate
formDataOrdination.leaveTotal = props.data.leaveTotal; formDataOrdination.leaveTotal = props.data.leaveTotal
formDataOrdination.ordainDayOrdination = props.data.ordainDayOrdination; formDataOrdination.ordainDayOrdination = props.data.ordainDayOrdination
formDataOrdination.ordainDayLocationName = props.data.ordainDayLocationName; formDataOrdination.ordainDayLocationName = props.data.ordainDayLocationName
formDataOrdination.ordainDayLocationNumber = formDataOrdination.ordainDayLocationNumber = props.data.ordainDayLocationNumber
props.data.ordainDayLocationNumber; formDataOrdination.ordainDayLocationAddress = props.data.ordainDayLocationAddress
formDataOrdination.ordainDayLocationAddress = formDataOrdination.ordainDayBuddhistLentName = props.data.ordainDayBuddhistLentName
props.data.ordainDayLocationAddress; formDataOrdination.ordainDayBuddhistLentAddress = props.data.ordainDayBuddhistLentAddress
formDataOrdination.ordainDayBuddhistLentName = formDataOrdination.ordainDayStatus = props.data.ordainDayStatus
props.data.ordainDayBuddhistLentName; formDataOrdination.leaveDetail = props.data.leaveDetail
formDataOrdination.ordainDayBuddhistLentAddress = leaveDocumentList.value = props.data.leaveDocument
props.data.ordainDayBuddhistLentAddress;
formDataOrdination.ordainDayStatus = props.data.ordainDayStatus;
formDataOrdination.leaveDetail = props.data.leaveDetail;
// formDataOrdination.leaveDocument = props.data.leaveDocument; // formDataOrdination.leaveDocument = props.data.leaveDocument;
} }
}); })
</script> </script>
<!-- ฟอร ลาอปสมบท --> <!-- ฟอร ลาอปสมบท -->
@ -240,7 +202,7 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
v-model="formDataOrdination.leaveWrote" v-model="formDataOrdination.leaveWrote"
label="เขียนที่" label="เขียนที่"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -268,21 +230,12 @@ onMounted(() => {
ref="leaveStartDateRef" ref="leaveStartDateRef"
hide-bottom-space hide-bottom-space
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataOrdination.leaveStartDate != null ? date2Thai(formDataOrdination.leaveStartDate) : null"
formDataOrdination.leaveStartDate != null
? date2Thai(formDataOrdination.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -315,22 +268,13 @@ onMounted(() => {
bg-color="white" bg-color="white"
hide-bottom-space hide-bottom-space
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataOrdination.leaveEndDate != null ? date2Thai(formDataOrdination.leaveEndDate) : null"
formDataOrdination.leaveEndDate != null
? date2Thai(formDataOrdination.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:readonly="!formDataOrdination.leaveStartDate" :readonly="!formDataOrdination.leaveStartDate"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -375,20 +319,11 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
readonly readonly
class="full-width" class="full-width"
:model-value=" :model-value="dataStore.dateAppoint != null ? date2Thai(dataStore.dateAppoint) : null"
dataStore.dateAppoint != null
? date2Thai(dataStore.dateAppoint)
: null
"
:label="`${'วันที่เข้ารับราชการ'}`" :label="`${'วันที่เข้ารับราชการ'}`"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(--black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(--black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -420,20 +355,11 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
readonly readonly
class="full-width" class="full-width"
:model-value=" :model-value="dataStore.birthDate != null ? date2Thai(dataStore.birthDate) : null"
dataStore.birthDate != null
? date2Thai(dataStore.birthDate)
: null
"
:label="`${'วันเดือนปีเกิด'}`" :label="`${'วันเดือนปีเกิด'}`"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(--black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(--black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -441,24 +367,10 @@ onMounted(() => {
</div> </div>
</div> </div>
<div class="q-pl-sm text-weight-bold text-dark col-12"> <div class="q-pl-sm text-weight-bold text-dark col-12">เคยบวชหรอไม</div>
เคยบวชหรอไม
</div>
<div class="col-12"> <div class="col-12">
<q-radio <q-radio v-model="formDataOrdination.ordainDayStatus" :val="true" label="เคยบวช" checked-icon="task_alt " hide-bottom-space />
v-model="formDataOrdination.ordainDayStatus" <q-radio v-model="formDataOrdination.ordainDayStatus" :val="false" label="ไม่เคยบวช" checked-icon="task_alt" hide-bottom-space />
:val="true"
label="เคยบวช"
checked-icon="task_alt "
hide-bottom-space
/>
<q-radio
v-model="formDataOrdination.ordainDayStatus"
:val="false"
label="ไม่เคยบวช"
checked-icon="task_alt"
hide-bottom-space
/>
</div> </div>
<div class="text-weight-bold text-dark col-12">สถานทบวช</div> <div class="text-weight-bold text-dark col-12">สถานทบวช</div>
@ -488,21 +400,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
hide-bottom-space hide-bottom-space
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataOrdination.ordainDayOrdination != null ? date2Thai(formDataOrdination.ordainDayOrdination) : null"
formDataOrdination.ordainDayOrdination != null
? date2Thai(formDataOrdination.ordainDayOrdination)
: null
"
:label="`${'วันอุปสมบท'}`" :label="`${'วันอุปสมบท'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกวันอุปสมบท'}`]" :rules="[val => !!val || `${'กรุณาเลือกวันอุปสมบท'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -518,7 +421,7 @@ onMounted(() => {
full-width full-width
v-model="formDataOrdination.ordainDayLocationName" v-model="formDataOrdination.ordainDayLocationName"
label="ชื่อวัด" label="ชื่อวัด"
:rules="[(val) => !!val || `${'กรุณากรอกชื่อวัด'}`]" :rules="[val => !!val || `${'กรุณากรอกชื่อวัด'}`]"
/> />
<q-input <q-input
@ -533,7 +436,7 @@ onMounted(() => {
unmasked-value unmasked-value
hide-bottom-space hide-bottom-space
label="หมายเลขโทรศัพท์" label="หมายเลขโทรศัพท์"
:rules="[(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์'}`]" :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์'}`]"
/> />
<q-input <q-input
class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen" class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen"
@ -544,13 +447,11 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
v-model="formDataOrdination.ordainDayLocationAddress" v-model="formDataOrdination.ordainDayLocationAddress"
label="ที่อยู่" label="ที่อยู่"
:rules="[(val) => !!val || `${'กรุณากรอกที่อยู่'}`]" :rules="[val => !!val || `${'กรุณากรอกที่อยู่'}`]"
type="textarea" type="textarea"
/> />
<div class="q-pl-sm text-weight-bold text-dark col-12"> <div class="q-pl-sm text-weight-bold text-dark col-12">สถานทจำพรรษา</div>
สถานทจำพรรษา
</div>
<q-input <q-input
class="col-12 col-sm-6 col-md-4 cursor-pointer inputgreen" class="col-12 col-sm-6 col-md-4 cursor-pointer inputgreen"
dense dense
@ -560,7 +461,7 @@ onMounted(() => {
outlined outlined
v-model="formDataOrdination.ordainDayBuddhistLentName" v-model="formDataOrdination.ordainDayBuddhistLentName"
label="ชื่อวัด" label="ชื่อวัด"
:rules="[(val) => !!val || `${'กรุณากรอกชื่อวัด'}`]" :rules="[val => !!val || `${'กรุณากรอกชื่อวัด'}`]"
/> />
<q-input <q-input
@ -571,7 +472,7 @@ onMounted(() => {
outlined outlined
v-model="formDataOrdination.ordainDayBuddhistLentAddress" v-model="formDataOrdination.ordainDayBuddhistLentAddress"
label="ที่อยู่" label="ที่อยู่"
:rules="[(val) => !!val || `${'กรุณากรอกที่อยู่'}`]" :rules="[val => !!val || `${'กรุณากรอกที่อยู่'}`]"
type="textarea" type="textarea"
hide-bottom-space hide-bottom-space
/> />
@ -587,39 +488,54 @@ onMounted(() => {
label="รายละเอียด" label="รายละเอียด"
:readonly="!edit" :readonly="!edit"
/> />
<div class="full-width col-12">
<div class="col-12"> <div class="q-col-gutter-sm row">
<!-- multiple --> <!-- multiple -->
<q-file <q-file ref="leaveDocumentRef" v-model="formDataOrdination.leaveDocument" @added="fileUploadDoc" dense label="เอกสารประกอบ" multiple outlined bg-color="white" use-chips>
ref="leaveDocumentRef"
v-model="formDataOrdination.leaveDocument"
@added="fileUploadDoc"
dense
label="เอกสารประกอบ"
outlined
bg-color="white"
use-chips
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataOrdination.leaveDocument.length == 0">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div> -->
</div>
</div>
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div> </div>
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs"> <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.fileName }} {{ file.name }}
</q-item-label> </q-item-label>
<q-item-label caption> </q-item-label> <q-item-label caption> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -633,26 +549,10 @@ onMounted(() => {
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,41 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, onMounted } from "vue"; import { reactive, ref, onMounted } from "vue"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import type { HajiForm } from "@/modules/05_leave/interface/request/AddAbsence"; import type { HajiForm } from "@/modules/05_leave/interface/request/AddAbsence"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
/** Use */ /** Use */
const router = useRouter(); const router = useRouter()
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { const { date2Thai, dialogConfirm, calculateDurationYmd, fails, messageError, success, dateToISO } = mixin
date2Thai, const edit = ref<boolean>(true)
dialogConfirm, const files = ref<any>(null)
calculateDurationYmd,
fails,
messageError,
success,
dateToISO,
} = mixin;
const edit = ref<boolean>(true);
const files = ref<any>(null);
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const leavegovernmentDateRef = ref<object | null>(null); const leavegovernmentDateRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Object,
default: null, default: null,
}, },
onSubmit: { onSubmit: {
@ -46,7 +38,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataHaji = reactive<any>({ const formDataHaji = reactive<any>({
@ -58,7 +50,7 @@ const formDataHaji = reactive<any>({
totalLeave: null, totalLeave: null,
hajjDayStatus: "true", hajjDayStatus: "true",
leaveDocument: null, leaveDocument: null,
}); })
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const formRef: HajiForm = { const formRef: HajiForm = {
@ -67,46 +59,42 @@ const formRef: HajiForm = {
leaveStartDate: leaveStartDateRef, leaveStartDate: leaveStartDateRef,
leaveEndDate: leaveEndDateRef, leaveEndDate: leaveEndDateRef,
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */ /** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in formRef) { for (const key in formRef) {
if (Object.prototype.hasOwnProperty.call(formRef, key)) { if (Object.prototype.hasOwnProperty.call(formRef, key)) {
const property = formRef[key]; const property = formRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataHaji.leaveDocument.length > 0) { formDataHaji.leaveDocument.forEach((file: File) => {
// const blob = formDataHaji.leaveDocument.slice(0, formDataHaji.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataHaji.leaveDocument[0].type, // formData.append("leaveDocument", formDataHaji.leaveDocument);
// }) formData.append("type", formDataHaji.type)
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataHaji.leaveStartDate))
// } formData.append("leaveEndDate", dateToISO(formDataHaji.leaveEndDate))
formData.append("leaveDocument", formDataHaji.leaveDocument); formData.append("hajjDayStatus", formDataHaji.hajjDayStatus)
formData.append("type", formDataHaji.type); formData.append("leaveWrote", formDataHaji.leaveWrote)
formData.append("leaveStartDate", dateToISO(formDataHaji.leaveStartDate)); formData.append("leaveDetail", formDataHaji.leaveDetail)
formData.append("leaveEndDate", dateToISO(formDataHaji.leaveEndDate)); props.onSubmit(formData)
formData.append("hajjDayStatus", formDataHaji.hajjDayStatus);
formData.append("leaveWrote", formDataHaji.leaveWrote);
formData.append("leaveDetail", formDataHaji.leaveDetail);
props.onSubmit(formData);
} }
} }
@ -114,7 +102,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -123,44 +111,43 @@ async function fetchCheck() {
EndLeaveDate: formDataHaji.leaveEndDate ?? null, EndLeaveDate: formDataHaji.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataHaji.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday // formDataHaji.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
formDataHaji.leaveTotal = data.totalDate; formDataHaji.leaveTotal = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataHaji.leaveStartDate, formDataHaji.leaveEndDate)
formDataHaji.leaveStartDate, formDataHaji.leaveTotal = newLeaveTotal
formDataHaji.leaveEndDate
);
formDataHaji.leaveTotal = newLeaveTotal;
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataHaji.leaveWrote = props.data.leaveWrote; formDataHaji.leaveWrote = props.data.leaveWrote
formDataHaji.leaveTotal = props.data.leaveTotal; formDataHaji.leaveTotal = props.data.leaveTotal
formDataHaji.leaveStartDate = props.data.leaveStartDate; formDataHaji.leaveStartDate = props.data.leaveStartDate
formDataHaji.leaveEndDate = props.data.leaveEndDate; formDataHaji.leaveEndDate = props.data.leaveEndDate
formDataHaji.totalLeave = props.data.totalLeave; formDataHaji.totalLeave = props.data.totalLeave
formDataHaji.hajjDayStatus = props.data.hajjDayStatus; formDataHaji.hajjDayStatus = props.data.hajjDayStatus
formDataHaji.leaveDetail = props.data.leaveDetail; formDataHaji.leaveDetail = props.data.leaveDetail
leaveDocumentList.value = props.data.leaveDocument
// formDataHaji.leaveDocument = props.data.leaveDocument; // formDataHaji.leaveDocument = props.data.leaveDocument;
} }
}); })
</script> </script>
<template> <template>
@ -180,7 +167,7 @@ onMounted(() => {
outlined outlined
label="เขียนที่" label="เขียนที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<div class="full-width"> <div class="full-width">
@ -211,20 +198,11 @@ onMounted(() => {
dense dense
hide-bottom-space hide-bottom-space
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
:model-value=" :model-value="formDataHaji.leaveStartDate != null ? date2Thai(formDataHaji.leaveStartDate) : null"
formDataHaji.leaveStartDate != null
? date2Thai(formDataHaji.leaveStartDate)
: null
"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -260,20 +238,11 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
@update:model-value="fetchCheck()" @update:model-value="fetchCheck()"
:model-value=" :model-value="formDataHaji.leaveEndDate != null ? date2Thai(formDataHaji.leaveEndDate) : null"
formDataHaji.leaveEndDate != null :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
? date2Thai(formDataHaji.leaveEndDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -291,16 +260,7 @@ onMounted(() => {
readonly readonly
hide-bottom-space hide-bottom-space
/> />
<datepicker <datepicker class="col-12 col-md-4 col-sm-6" menu-class-name="modalfix" autoApply borderless readonly week-start="0" :locale="'th'" :enableTimePicker="false">
class="col-12 col-md-4 col-sm-6"
menu-class-name="modalfix"
autoApply
borderless
readonly
week-start="0"
:locale="'th'"
:enableTimePicker="false"
>
<template #year="{ year }"> <template #year="{ year }">
{{ year + 543 }} {{ year + 543 }}
</template> </template>
@ -317,22 +277,11 @@ onMounted(() => {
readonly readonly
hide-bottom-space hide-bottom-space
:label="`${'วันที่เข้ารับราชการ'}`" :label="`${'วันที่เข้ารับราชการ'}`"
:model-value=" :model-value="dataStore.dateAppoint != null ? date2Thai(dataStore.dateAppoint) : null"
dataStore.dateAppoint != null :rules="[val => !!val || `${'กรุณาเลือกวันที่เข้ารับราชการ'}`]"
? date2Thai(dataStore.dateAppoint)
: null
"
:rules="[
(val) => !!val || `${'กรุณาเลือกวันที่เข้ารับราชการ'}`,
]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(--black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(--black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -340,67 +289,61 @@ onMounted(() => {
</div> </div>
</div> </div>
<div class="q-pl-sm text-weight-bold text-dark col-12"> <div class="q-pl-sm text-weight-bold text-dark col-12">เคยไปประกอบพจญหรอไม</div>
เคยไปประกอบพจญหรอไม
</div>
<div class="col-12"> <div class="col-12">
<q-radio <q-radio v-model="formDataHaji.hajjDayStatus" :val="'true'" checked-icon="task_alt" label="เคย" />
v-model="formDataHaji.hajjDayStatus" <q-radio v-model="formDataHaji.hajjDayStatus" :val="'false'" checked-icon="task_alt" label="ไม่เคยไปประกอบพิธีฮัจญ์" />
:val="true"
checked-icon="task_alt"
label="เคย"
/>
<q-radio
v-model="formDataHaji.hajjDayStatus"
:val="false"
checked-icon="task_alt"
label="ไม่เคยไปประกอบพิธีฮัจญ์"
/>
</div> </div>
<q-input <q-input v-model="formDataHaji.leaveDetail" class="col-12 q-mt-sm cursor-pointer inputgreen" bg-color="white" dense outlined type="textarea" label="รายละเอียด" />
v-model="formDataHaji.leaveDetail" <div class="full-width">
class="col-12 q-mt-sm cursor-pointer inputgreen" <div class="q-col-gutter-sm row">
bg-color="white"
dense
outlined
type="textarea"
label="รายละเอียด"
/>
<div class="col-12">
<!-- multiple --> <!-- multiple -->
<q-file <q-file v-model="formDataHaji.leaveDocument" multiple bg-color="white" label="เอกสารประกอบ" use-chips @added="fileUploadDoc" dense outlined hide-bottom-space>
v-model="formDataHaji.leaveDocument"
bg-color="white"
label="เอกสารประกอบ"
use-chips
@added="fileUploadDoc"
dense
outlined
hide-bottom-space
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataHaji.leaveDocument.length == 0">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div> -->
</div>
</div>
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div> </div>
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs"> <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.fileName }} {{ file.name }}
</q-item-label> </q-item-label>
<q-item-label caption> </q-item-label> <q-item-label caption> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -412,26 +355,10 @@ onMounted(() => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,45 +1,37 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, onMounted } from "vue"; import { reactive, ref, onMounted } from "vue"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import type { MilitaryForm } from "@/modules/05_leave/interface/request/AddAbsence"; import type { MilitaryForm } from "@/modules/05_leave/interface/request/AddAbsence"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
/** Use */ /** Use */
const router = useRouter(); const router = useRouter()
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { const { date2Thai, dialogConfirm, calculateDurationYmd, dateToISO, success, messageError, fails } = mixin
date2Thai, const edit = ref<boolean>(true)
dialogConfirm, const files = ref<any>(null)
calculateDurationYmd,
dateToISO,
success,
messageError,
fails,
} = mixin;
const edit = ref<boolean>(true);
const files = ref<any>(null);
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const absentDaySummonRef = ref<object | null>(null); const absentDaySummonRef = ref<object | null>(null)
const absentDayLocationRef = ref<object | null>(null); const absentDayLocationRef = ref<object | null>(null)
const absentDayRegistorDateRef = ref<object | null>(null); const absentDayRegistorDateRef = ref<object | null>(null)
const absentDayGetInRef = ref<object | null>(null); const absentDayGetInRef = ref<object | null>(null)
const absentDayAtRef = ref<object | null>(null); const absentDayAtRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Object,
default: null, default: null,
}, },
onSubmit: { onSubmit: {
@ -50,7 +42,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataMilitary = reactive<any>({ const formDataMilitary = reactive<any>({
@ -66,16 +58,16 @@ const formDataMilitary = reactive<any>({
absentDayGetIn: "", absentDayGetIn: "",
absentDayAt: "", absentDayAt: "",
leaveDetail: "", leaveDetail: "",
}); })
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const formRef: MilitaryForm = { const formRef: MilitaryForm = {
@ -88,47 +80,37 @@ const formRef: MilitaryForm = {
absentDayGetIn: absentDayGetInRef, absentDayGetIn: absentDayGetInRef,
absentDayAt: absentDayAtRef, absentDayAt: absentDayAtRef,
leaveDetail: leaveDetailRef, leaveDetail: leaveDetailRef,
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */ /** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in formRef) { for (const key in formRef) {
if (Object.prototype.hasOwnProperty.call(formRef, key)) { if (Object.prototype.hasOwnProperty.call(formRef, key)) {
const property = formRef[key]; const property = formRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataMilitary.leaveDocument.length > 0) { formDataMilitary.leaveDocument.forEach((file: File) => {
// const blob = formDataMilitary.leaveDocument.slice(0, formDataMilitary.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataMilitary.leaveDocument[0].type, // formData.append("leaveDocument", formDataMilitary.leaveDocument);
// }) formData.append("type", formDataMilitary.type)
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataMilitary.leaveStartDate))
// } formData.append("leaveEndDate", dateToISO(formDataMilitary.leaveEndDate))
formData.append("leaveDocument", formDataMilitary.leaveDocument); formData.append("absentDaySummon", formDataMilitary.absentDaySummon)
formData.append("type", formDataMilitary.type); formData.append("absentDayLocation", formDataMilitary.absentDayLocation)
formData.append( formData.append("absentDayRegistorDate", dateToISO(formDataMilitary.absentDayRegistorDate))
"leaveStartDate", formData.append("absentDayGetIn", formDataMilitary.absentDayGetIn)
dateToISO(formDataMilitary.leaveStartDate) formData.append("absentDayAt", formDataMilitary.absentDayAt)
); formData.append("leaveWrote", formDataMilitary.leaveWrote)
formData.append("leaveEndDate", dateToISO(formDataMilitary.leaveEndDate)); formData.append("leaveDetail", formDataMilitary.leaveDetail)
formData.append("absentDaySummon", formDataMilitary.absentDaySummon); props.onSubmit(formData)
formData.append("absentDayLocation", formDataMilitary.absentDayLocation);
formData.append(
"absentDayRegistorDate",
dateToISO(formDataMilitary.absentDayRegistorDate)
);
formData.append("absentDayGetIn", formDataMilitary.absentDayGetIn);
formData.append("absentDayAt", formDataMilitary.absentDayAt);
formData.append("leaveWrote", formDataMilitary.leaveWrote);
formData.append("leaveDetail", formDataMilitary.leaveDetail);
props.onSubmit(formData);
} }
} }
@ -136,7 +118,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -145,48 +127,47 @@ async function fetchCheck() {
EndLeaveDate: formDataMilitary.leaveEndDate ?? null, EndLeaveDate: formDataMilitary.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataMilitary.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday // formDataMilitary.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
formDataMilitary.leaveTotal = data.totalDate; formDataMilitary.leaveTotal = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataMilitary.leaveStartDate, formDataMilitary.leaveEndDate)
formDataMilitary.leaveStartDate, formDataMilitary.leaveTotal = newLeaveTotal
formDataMilitary.leaveEndDate console.log("test")
);
formDataMilitary.leaveTotal = newLeaveTotal;
console.log("test");
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataMilitary.leaveWrote = props.data.leaveWrote; formDataMilitary.leaveWrote = props.data.leaveWrote
formDataMilitary.leaveStartDate = props.data.leaveStartDate; formDataMilitary.leaveStartDate = props.data.leaveStartDate
formDataMilitary.leaveEndDate = props.data.leaveEndDate; formDataMilitary.leaveEndDate = props.data.leaveEndDate
formDataMilitary.leaveTotal = props.data.leaveTotal; formDataMilitary.leaveTotal = props.data.leaveTotal
formDataMilitary.absentDaySummon = props.data.absentDaySummon; formDataMilitary.absentDaySummon = props.data.absentDaySummon
formDataMilitary.absentDayLocation = props.data.absentDayLocation; formDataMilitary.absentDayLocation = props.data.absentDayLocation
formDataMilitary.absentDayRegistorDate = props.data.absentDayRegistorDate; formDataMilitary.absentDayRegistorDate = props.data.absentDayRegistorDate
formDataMilitary.absentDayGetIn = props.data.absentDayGetIn; formDataMilitary.absentDayGetIn = props.data.absentDayGetIn
formDataMilitary.absentDayAt = props.data.absentDayAt; formDataMilitary.absentDayAt = props.data.absentDayAt
formDataMilitary.leaveDetail = props.data.leaveDetail; formDataMilitary.leaveDetail = props.data.leaveDetail
leaveDocumentList.value = props.data.leaveDocument
// formDataMilitary.leaveDocument = props.data.leaveDocument; // formDataMilitary.leaveDocument = props.data.leaveDocument;
} }
}); })
</script> </script>
<template> <template>
@ -206,7 +187,7 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
v-model="formDataMilitary.leaveWrote" v-model="formDataMilitary.leaveWrote"
label="เขียนที่" label="เขียนที่"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -234,21 +215,12 @@ onMounted(() => {
ref="leaveStartDateRef" ref="leaveStartDateRef"
hide-bottom-space hide-bottom-space
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataMilitary.leaveStartDate != null ? date2Thai(formDataMilitary.leaveStartDate) : null"
formDataMilitary.leaveStartDate != null
? date2Thai(formDataMilitary.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -282,21 +254,12 @@ onMounted(() => {
hide-bottom-space hide-bottom-space
:readonly="!formDataMilitary.leaveStartDate" :readonly="!formDataMilitary.leaveStartDate"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataMilitary.leaveEndDate != null ? date2Thai(formDataMilitary.leaveEndDate) : null"
formDataMilitary.leaveEndDate != null
? date2Thai(formDataMilitary.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -325,7 +288,7 @@ onMounted(() => {
v-model="formDataMilitary.absentDaySummon" v-model="formDataMilitary.absentDaySummon"
label="ได้รับหมายเรียกของ" label="ได้รับหมายเรียกของ"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกได้รับหมายเรียกของ'}`]" :rules="[val => !!val || `${'กรุณากรอกได้รับหมายเรียกของ'}`]"
/> />
<q-input <q-input
@ -337,7 +300,7 @@ onMounted(() => {
v-model="formDataMilitary.absentDayLocation" v-model="formDataMilitary.absentDayLocation"
label="ที่" label="ที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกที่'}`]" :rules="[val => !!val || `${'กรุณากรอกที่'}`]"
/> />
</div> </div>
</div> </div>
@ -368,21 +331,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
hide-bottom-space hide-bottom-space
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataMilitary.absentDayRegistorDate != null ? date2Thai(formDataMilitary.absentDayRegistorDate) : null"
formDataMilitary.absentDayRegistorDate != null
? date2Thai(formDataMilitary.absentDayRegistorDate)
: null
"
:label="`${'ลงวันที่'}`" :label="`${'ลงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -397,7 +351,7 @@ onMounted(() => {
v-model="formDataMilitary.absentDayGetIn" v-model="formDataMilitary.absentDayGetIn"
label="ให้เข้ารับการ" label="ให้เข้ารับการ"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกให้เข้ารับการ'}`]" :rules="[val => !!val || `${'กรุณากรอกให้เข้ารับการ'}`]"
/> />
<q-input <q-input
@ -409,54 +363,59 @@ onMounted(() => {
v-model="formDataMilitary.absentDayAt" v-model="formDataMilitary.absentDayAt"
label="ณ ที่" label="ณ ที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอก ณ ที่'}`]" :rules="[val => !!val || `${'กรุณากรอก ณ ที่'}`]"
/> />
</div> </div>
</div> </div>
<q-input <q-input class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen" dense bg-color="white" outlined v-model="formDataMilitary.leaveDetail" type="textarea" label="รายละเอียด" />
class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen"
dense
bg-color="white"
outlined
v-model="formDataMilitary.leaveDetail"
type="textarea"
label="รายละเอียด"
/>
<div class="col-12"> <div class="col-12">
<!-- multiple --> <!-- multiple -->
<q-file <q-file v-model="formDataMilitary.leaveDocument" multiple dense label="เอกสารประกอบ" outlined bg-color="white" hide-bottom-space use-chips @added="fileUploadDoc">
v-model="formDataMilitary.leaveDocument"
dense
label="เอกสารประกอบ"
outlined
bg-color="white"
hide-bottom-space
use-chips
@added="fileUploadDoc"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<div class="col-12" v-if="formDataMilitary.leaveDocument.length == 0">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div>
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</div> </div>
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs"> <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.fileName }} {{ file.name }}
</q-item-label> </q-item-label>
<q-item-label caption> </q-item-label> <q-item-label caption> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -468,26 +427,10 @@ onMounted(() => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,50 +1,41 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, computed, onMounted } from "vue"; import { reactive, ref, computed, onMounted } from "vue"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import type { studyDaySubjectForm } from "@/modules/05_leave/interface/request/AddAbsence"; import type { studyDaySubjectForm } from "@/modules/05_leave/interface/request/AddAbsence"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const router = useRouter(); const router = useRouter()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { const { date2Thai, dialogConfirm, calculateDurationYmd, fails, dateToISO, success, messageError, arabicNumberToText } = mixin
date2Thai, const edit = ref<boolean>(true)
dialogConfirm, const files = ref<any>(null)
calculateDurationYmd,
fails,
dateToISO,
success,
messageError,
arabicNumberToText,
} = mixin;
const edit = ref<boolean>(true);
const files = ref<any>(null);
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leavebirthDateRef = ref<object | null>(null); const leavebirthDateRef = ref<object | null>(null)
const leavegovernmentDateRef = ref<object | null>(null); const leavegovernmentDateRef = ref<object | null>(null)
const leaveSalaryRef = ref<object | null>(null); const leaveSalaryRef = ref<object | null>(null)
const leaveNumberRef = ref<object | null>(null); const leaveNumberRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const studyDayScholarshipRef = ref<object | null>(null); const studyDayScholarshipRef = ref<object | null>(null)
const studyDayCountryRef = ref<object | null>(null); const studyDayCountryRef = ref<object | null>(null)
const studyDayUniversityNameRef = ref<object | null>(null); const studyDayUniversityNameRef = ref<object | null>(null)
const studyDayDegreeLevelRef = ref<object | null>(null); const studyDayDegreeLevelRef = ref<object | null>(null)
const studyDaySubjectRef = ref<object | null>(null); const studyDaySubjectRef = ref<object | null>(null)
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Object,
default: null, default: null,
}, },
onSubmit: { onSubmit: {
@ -55,7 +46,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataStudy = reactive<any>({ const formDataStudy = reactive<any>({
@ -77,7 +68,7 @@ const formDataStudy = reactive<any>({
leaveDocument: "", // leaveDocument: "", //
leaveDetail: "", leaveDetail: "",
leaveTotal: "", leaveTotal: "",
}); })
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const formRef: studyDaySubjectForm = { const formRef: studyDaySubjectForm = {
@ -94,59 +85,49 @@ const formRef: studyDaySubjectForm = {
studyDayDegreeLevel: studyDayDegreeLevelRef, studyDayDegreeLevel: studyDayDegreeLevelRef,
studyDaySubject: studyDaySubjectRef, studyDaySubject: studyDaySubjectRef,
leaveWrote: leaveWroteRef, leaveWrote: leaveWroteRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */ /** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in formRef) { for (const key in formRef) {
if (Object.prototype.hasOwnProperty.call(formRef, key)) { if (Object.prototype.hasOwnProperty.call(formRef, key)) {
const property = formRef[key]; const property = formRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataStudy.leaveDocument.length > 0) { formDataStudy.leaveDocument.forEach((file: File) => {
// const blob = formDataStudy.leaveDocument.slice(0, formDataStudy.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataStudy.leaveDocument[0].type, // formData.append("leaveDocument", formDataStudy.leaveDocument);
// }) formData.append("type", formDataStudy.type) //
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataStudy.leaveStartDate)) //
// } formData.append("leaveEndDate", dateToISO(formDataStudy.leaveEndDate)) //
formData.append("leaveDocument", formDataStudy.leaveDocument); formData.append("studyDaySubject", formDataStudy.studyDaySubject)
formData.append("type", formDataStudy.type); // formData.append("studyDayDegreeLevel", formDataStudy.studyDayDegreeLevel)
formData.append("leaveStartDate", dateToISO(formDataStudy.leaveStartDate)); // formData.append("leavegovernmentDate", dateToISO(formDataStudy.leavegovernmentDate))
formData.append("leaveEndDate", dateToISO(formDataStudy.leaveEndDate)); // formData.append("studyDayUniversityName", formDataStudy.studyDayUniversityName)
formData.append("studyDaySubject", formDataStudy.studyDaySubject); formData.append("studyDayCountry", formDataStudy.studyDayCountry)
formData.append("studyDayDegreeLevel", formDataStudy.studyDayDegreeLevel); formData.append("leaveWrote", formDataStudy.leaveWrote) //
formData.append( formData.append("leaveDetail", formDataStudy.leaveDetail) //
"leavegovernmentDate", formData.append("studyDayScholarship", formDataStudy.studyDayScholarship)
dateToISO(formDataStudy.leavegovernmentDate) formData.append("leaveAddress", formDataStudy.leaveAddress) //
); formData.append("leaveNumber", formDataStudy.leaveNumber) //
formData.append( props.onSubmit(formData)
"studyDayUniversityName",
formDataStudy.studyDayUniversityName
);
formData.append("studyDayCountry", formDataStudy.studyDayCountry);
formData.append("leaveWrote", formDataStudy.leaveWrote); //
formData.append("leaveDetail", formDataStudy.leaveDetail); //
formData.append("studyDayScholarship", formDataStudy.studyDayScholarship);
formData.append("leaveAddress", formDataStudy.leaveAddress); //
formData.append("leaveNumber", formDataStudy.leaveNumber); //
props.onSubmit(formData);
} }
} }
@ -154,7 +135,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -163,60 +144,55 @@ async function fetchCheck() {
EndLeaveDate: formDataStudy.leaveEndDate ?? null, EndLeaveDate: formDataStudy.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataStudy.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday; // formDataStudy.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday;
formDataStudy.leaveTotal = data.totalDate; formDataStudy.leaveTotal = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
fetchCheck(); fetchCheck()
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataStudy.leaveStartDate, formDataStudy.leaveEndDate)
formDataStudy.leaveStartDate, formDataStudy.leaveTotal = newLeaveTotal
formDataStudy.leaveEndDate
);
formDataStudy.leaveTotal = newLeaveTotal;
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(async () => { onMounted(async () => {
if (props.data) { if (props.data) {
formDataStudy.leaveWrote = props.data.leaveWrote; formDataStudy.leaveWrote = props.data.leaveWrote
formDataStudy.leaveStartDate = props.data.leaveStartDate; formDataStudy.leaveStartDate = props.data.leaveStartDate
formDataStudy.leaveEndDate = props.data.leaveEndDate; formDataStudy.leaveEndDate = props.data.leaveEndDate
formDataStudy.leaveTotal = props.data.leaveTotal; formDataStudy.leaveTotal = props.data.leaveTotal
formDataStudy.leavebirthDate = props.data.leavebirthDate; formDataStudy.leavebirthDate = props.data.leavebirthDate
formDataStudy.leavegovernmentDate = props.data.leavegovernmentDate; formDataStudy.leavegovernmentDate = props.data.leavegovernmentDate
formDataStudy.leaveSalary = props.data.leaveSalary; formDataStudy.leaveSalary = props.data.leaveSalary
formDataStudy.leaveSalaryText = props.data.leaveSalaryText; formDataStudy.leaveSalaryText = props.data.leaveSalaryText
formDataStudy.leaveNumber = props.data.leaveNumber; formDataStudy.leaveNumber = props.data.leaveNumber
formDataStudy.leaveAddress = props.data.leaveAddress; formDataStudy.leaveAddress = props.data.leaveAddress
formDataStudy.studyDayScholarship = props.data.studyDayScholarship; formDataStudy.studyDayScholarship = props.data.studyDayScholarship
formDataStudy.studyDayCountry = props.data.studyDayCountry; formDataStudy.studyDayCountry = props.data.studyDayCountry
formDataStudy.studyDayUniversityName = props.data.studyDayUniversityName; formDataStudy.studyDayUniversityName = props.data.studyDayUniversityName
formDataStudy.studyDayDegreeLevel = props.data.studyDayDegreeLevel; formDataStudy.studyDayDegreeLevel = props.data.studyDayDegreeLevel
formDataStudy.studyDaySubject = props.data.studyDaySubject; formDataStudy.studyDaySubject = props.data.studyDaySubject
// formDataStudy.leaveDocument = props.data.leaveDocument; // formDataStudy.leaveDocument = props.data.leaveDocument;
formDataStudy.leaveDetail = props.data.leaveDetail; formDataStudy.leaveDetail = props.data.leaveDetail
leaveDocumentList.value = props.data.leaveDocument
const leaveTotal = await calculateDurationYmd( const leaveTotal = await calculateDurationYmd(props.data.leaveStartDate, props.data.leaveEndDate)
new Date(props.data.leaveStartDate), formDataStudy.leaveTotal = leaveTotal
new Date(props.data.leaveEndDate)
);
formDataStudy.leaveTotal = leaveTotal;
} }
}); })
</script> </script>
<template> <template>
@ -236,7 +212,7 @@ onMounted(async () => {
outlined outlined
label="เขียนที่" label="เขียนที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -266,20 +242,11 @@ onMounted(async () => {
lazy-rules lazy-rules
hide-bottom-space hide-bottom-space
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:model-value=" :model-value="formDataStudy.leaveStartDate != null ? date2Thai(formDataStudy.leaveStartDate) : null"
formDataStudy.leaveStartDate != null :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
? date2Thai(formDataStudy.leaveStartDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -315,20 +282,11 @@ onMounted(async () => {
hide-bottom-space hide-bottom-space
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:readonly="!formDataStudy.leaveStartDate" :readonly="!formDataStudy.leaveStartDate"
:model-value=" :model-value="formDataStudy.leaveEndDate != null ? date2Thai(formDataStudy.leaveEndDate) : null"
formDataStudy.leaveEndDate != null :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
? date2Thai(formDataStudy.leaveEndDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -349,16 +307,7 @@ onMounted(async () => {
<div class="full-width"> <div class="full-width">
<div class="q-col-gutter-sm row"> <div class="q-col-gutter-sm row">
<datepicker <datepicker class="col-12 col-md-3 col-sm-6" menu-class-name="modalfix" autoApply borderless week-start="0" readonly :enableTimePicker="false" :locale="'th'">
class="col-12 col-md-3 col-sm-6"
menu-class-name="modalfix"
autoApply
borderless
week-start="0"
readonly
:enableTimePicker="false"
:locale="'th'"
>
<template #year="{ year }"> <template #year="{ year }">
{{ year + 543 }} {{ year + 543 }}
</template> </template>
@ -375,37 +324,17 @@ onMounted(async () => {
dense dense
hide-bottom-space hide-bottom-space
:label="`${'วันที่เข้ารับราชการ'}`" :label="`${'วันที่เข้ารับราชการ'}`"
:model-value=" :model-value="dataStore.dateAppoint != null ? date2Thai(dataStore.dateAppoint) : null"
dataStore.dateAppoint != null :rules="[val => !!val || `${'กรุณาเลือกวันที่เข้ารับราชการ'}`]"
? date2Thai(dataStore.dateAppoint)
: null
"
:rules="[
(val) => !!val || `${'กรุณาเลือกวันที่เข้ารับราชการ'}`,
]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(--black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(--black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
</datepicker> </datepicker>
<datepicker <datepicker class="col-12 col-md-3 col-sm-6" menu-class-name="modalfix" autoApply borderless readonly week-start="0" :enableTimePicker="false" :locale="'th'">
class="col-12 col-md-3 col-sm-6"
menu-class-name="modalfix"
autoApply
borderless
readonly
week-start="0"
:enableTimePicker="false"
:locale="'th'"
>
<template #year="{ year }"> <template #year="{ year }">
{{ year + 543 }} {{ year + 543 }}
</template> </template>
@ -422,35 +351,17 @@ onMounted(async () => {
readonly readonly
hide-bottom-space hide-bottom-space
:label="`${'วันเดือนปีเกิด'}`" :label="`${'วันเดือนปีเกิด'}`"
:model-value=" :model-value="dataStore.birthDate != null ? date2Thai(dataStore.birthDate) : null"
dataStore.birthDate != null :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
? date2Thai(dataStore.birthDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(--black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(--black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
</datepicker> </datepicker>
<q-input <q-input :model-value="dataStore.salary" ref="leaveSalaryRef" class="col-12 col-sm-6 col-md-3" bg-color="white" dense outlined readonly label="เงินเดือนปัจจุบัน" />
:model-value="dataStore.salary"
ref="leaveSalaryRef"
class="col-12 col-sm-6 col-md-3"
bg-color="white"
dense
outlined
readonly
label="เงินเดือนปัจจุบัน"
/>
<q-input <q-input
:model-value="dataStore.salaryText" :model-value="dataStore.salaryText"
@ -462,7 +373,7 @@ onMounted(async () => {
outlined outlined
label="เงินเดือนปัจจุบัน (ตัวอักษร)" label="เงินเดือนปัจจุบัน (ตัวอักษร)"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือนปัจจุบัน'}`]" :rules="[val => !!val || `${'กรุณากรอกเงินเดือนปัจจุบัน'}`]"
/> />
</div> </div>
</div> </div>
@ -478,7 +389,7 @@ onMounted(async () => {
outlined outlined
label="ชื่อสถานศึกษา" label="ชื่อสถานศึกษา"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกชื่อสถานศึกษา'}`]" :rules="[val => !!val || `${'กรุณากรอกชื่อสถานศึกษา'}`]"
/> />
<q-input <q-input
@ -490,7 +401,7 @@ onMounted(async () => {
outlined outlined
label="ชั้นปริญญา" label="ชั้นปริญญา"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกชั้นปริญญา'}`]" :rules="[val => !!val || `${'กรุณากรอกชั้นปริญญา'}`]"
/> />
<q-input <q-input
@ -502,7 +413,7 @@ onMounted(async () => {
outlined outlined
label="ศึกษาวิชา" label="ศึกษาวิชา"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกศึกษาวิชา'}`]" :rules="[val => !!val || `${'กรุณากรอกศึกษาวิชา'}`]"
/> />
<q-input <q-input
@ -514,7 +425,7 @@ onMounted(async () => {
outlined outlined
label="ประเทศ" label="ประเทศ"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกประเทศ'}`]" :rules="[val => !!val || `${'กรุณากรอกประเทศ'}`]"
/> />
<q-input <q-input
@ -526,7 +437,7 @@ onMounted(async () => {
outlined outlined
label="ด้วยทุน" label="ด้วยทุน"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกด้วยทุน'}`]" :rules="[val => !!val || `${'กรุณากรอกด้วยทุน'}`]"
/> />
<q-input <q-input
@ -540,9 +451,7 @@ onMounted(async () => {
hide-bottom-space hide-bottom-space
mask="(###)-###-####" mask="(###)-###-####"
label="หมายเลขโทรศัพท์ที่ติดต่อได้" label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`,
]"
/> />
<q-input <q-input
@ -554,54 +463,59 @@ onMounted(async () => {
outlined outlined
label="ที่อยู่ที่ติดต่อได้ระหว่างลา" label="ที่อยู่ที่ติดต่อได้ระหว่างลา"
hide-bottom-space hide-bottom-space
:rules="[ :rules="[val => !!val || `${'กรุณากรอก ที่อยู่ที่ติดต่อได้ระหว่างลา'}`]"
(val) => !!val || `${'กรุณากรอก ที่อยู่ที่ติดต่อได้ระหว่างลา'}`,
]"
/> />
</div> </div>
</div> </div>
<q-input <q-input v-model="formDataStudy.leaveDetail" class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen" bg-color="white" dense outlined type="textarea" label="รายละเอียด" />
v-model="formDataStudy.leaveDetail"
class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen"
bg-color="white"
dense
outlined
type="textarea"
label="รายละเอียด"
/>
<div class="col-12"> <div class="col-12">
<!-- multiple --> <!-- multiple -->
<q-file <q-file v-model="formDataStudy.leaveDocument" bg-color="white" multiple dense outlined use-chips @added="fileUploadDoc" label="เอกสารประกอบ">
v-model="formDataStudy.leaveDocument"
bg-color="white"
dense
outlined
use-chips
@added="fileUploadDoc"
label="เอกสารประกอบ"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataStudy.leaveDocument.length == 0">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div> -->
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</div> </div>
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs"> <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.fileName }} {{ file.name }}
</q-item-label> </q-item-label>
<q-item-label caption> </q-item-label> <q-item-label caption> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -613,26 +527,10 @@ onMounted(async () => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,35 +1,26 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, computed, onMounted } from "vue"; import { reactive, ref, computed, onMounted } from "vue"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import type { TrainForm } from "@/modules/05_leave/interface/request/AddAbsence"; import type { TrainForm } from "@/modules/05_leave/interface/request/AddAbsence"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const router = useRouter(); const router = useRouter()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { const { date2Thai, dialogConfirm, arabicNumberToText, calculateDurationYmd, fails, dateToISO, success, messageError } = mixin
date2Thai, const edit = ref<boolean>(true)
dialogConfirm, const files = ref<any>(null)
arabicNumberToText,
calculateDurationYmd,
fails,
dateToISO,
success,
messageError,
} = mixin;
const edit = ref<boolean>(true);
const files = ref<any>(null);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Object,
default: null, default: null,
}, },
onSubmit: { onSubmit: {
@ -40,7 +31,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataTrain = reactive<any>({ const formDataTrain = reactive<any>({
@ -60,20 +51,20 @@ const formDataTrain = reactive<any>({
studyDayTrainingName: "", studyDayTrainingName: "",
leaveDocument: "", leaveDocument: "",
leaveDetail: "", leaveDetail: "",
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leavebirthDateRef = ref<object | null>(null); const leavebirthDateRef = ref<object | null>(null)
const leavegovernmentDateRef = ref<object | null>(null); const leavegovernmentDateRef = ref<object | null>(null)
const leaveNumberRef = ref<object | null>(null); const leaveNumberRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const studyDayScholarshipRef = ref<object | null>(null); const studyDayScholarshipRef = ref<object | null>(null)
const studyDayCountryRef = ref<object | null>(null); const studyDayCountryRef = ref<object | null>(null)
const studyDayTrainingSubjectRef = ref<object | null>(null); const studyDayTrainingSubjectRef = ref<object | null>(null)
const studyDayTrainingNameRef = ref<object | null>(null); const studyDayTrainingNameRef = ref<object | null>(null)
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const formRef: TrainForm = { const formRef: TrainForm = {
@ -88,63 +79,53 @@ const formRef: TrainForm = {
studyDayTrainingSubject: studyDayTrainingSubjectRef, studyDayTrainingSubject: studyDayTrainingSubjectRef,
studyDayTrainingName: studyDayTrainingNameRef, studyDayTrainingName: studyDayTrainingNameRef,
leaveWrote: leaveWroteRef, leaveWrote: leaveWroteRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */ /** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in formRef) { for (const key in formRef) {
if (Object.prototype.hasOwnProperty.call(formRef, key)) { if (Object.prototype.hasOwnProperty.call(formRef, key)) {
const property = formRef[key]; const property = formRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataTrain.leaveDocument.length > 0) { formDataTrain.leaveDocument.forEach((file: File) => {
// const blob = formDataTrain.leaveDocument.slice(0, formDataTrain.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataTrain.leaveDocument[0].type, // formData.append("leaveDocument", formDataTrain.leaveDocument);
// }) formData.append("type", formDataTrain.type) //
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataTrain.leaveStartDate)) //
// } // formData.append("leaveEndDate", dateToISO(formDataTrain.leaveEndDate)) //
formData.append("leaveDocument", formDataTrain.leaveDocument); formData.append("studyDayCountry", formDataTrain.studyDayCountry)
formData.append("type", formDataTrain.type); // formData.append("leavegovernmentDate", dateToISO(formDataTrain.leavegovernmentDate))
formData.append("leaveStartDate", dateToISO(formDataTrain.leaveStartDate)); // formData.append("leavebirthDate", dateToISO(formDataTrain.leavebirthDate))
formData.append("leaveEndDate", dateToISO(formDataTrain.leaveEndDate)); // formData.append("studyDayTrainingName", formDataTrain.studyDayTrainingName)
formData.append("studyDayCountry", formDataTrain.studyDayCountry); formData.append("studyDayTrainingSubject", formDataTrain.studyDayTrainingSubject)
formData.append( formData.append("leaveWrote", formDataTrain.leaveWrote) //
"leavegovernmentDate", formData.append("leaveDetail", formDataTrain.leaveDetail) //
dateToISO(formDataTrain.leavegovernmentDate) formData.append("studyDayScholarship", formDataTrain.studyDayScholarship)
); formData.append("leaveAddress", formDataTrain.leaveAddress) //
formData.append("leavebirthDate", dateToISO(formDataTrain.leavebirthDate)); formData.append("leaveNumber", formDataTrain.leaveNumber) //
formData.append("studyDayTrainingName", formDataTrain.studyDayTrainingName); formData.append("leaveSalaryText", formDataTrain.leaveSalaryText) //
formData.append( formData.append("leaveSalary", formDataTrain.leaveSalary) //
"studyDayTrainingSubject", formData.append("leaveTotal", formDataTrain.leaveTotal) //
formDataTrain.studyDayTrainingSubject props.onSubmit(formData)
);
formData.append("leaveWrote", formDataTrain.leaveWrote); //
formData.append("leaveDetail", formDataTrain.leaveDetail); //
formData.append("studyDayScholarship", formDataTrain.studyDayScholarship);
formData.append("leaveAddress", formDataTrain.leaveAddress); //
formData.append("leaveNumber", formDataTrain.leaveNumber); //
formData.append("leaveSalaryText", formDataTrain.leaveSalaryText); //
formData.append("leaveSalary", formDataTrain.leaveSalary); //
formData.append("leaveTotal", formDataTrain.leaveTotal); //
props.onSubmit(formData);
} }
} }
@ -152,7 +133,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -161,67 +142,61 @@ async function fetchCheck() {
EndLeaveDate: formDataTrain.leaveEndDate ?? null, EndLeaveDate: formDataTrain.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataTrain.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday // formDataTrain.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
formDataTrain.leaveTotal = data.totalDate; formDataTrain.leaveTotal = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
fetchCheck(); fetchCheck()
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataTrain.leaveStartDate, formDataTrain.leaveEndDate)
formDataTrain.leaveStartDate, formDataTrain.leaveTotal = newLeaveTotal
formDataTrain.leaveEndDate
);
formDataTrain.leaveTotal = newLeaveTotal;
} }
/** /**
* แปลงตวเลขเงนเดอน * แปลงตวเลขเงนเดอน
*/ */
const formattedSalary = computed(() => { const formattedSalary = computed(() => {
return formDataTrain.leaveSalary !== null return formDataTrain.leaveSalary !== null ? formDataTrain.leaveSalary.toLocaleString("th-TH") : ""
? formDataTrain.leaveSalary.toLocaleString("th-TH") })
: "";
});
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(async () => { onMounted(async () => {
if (props.data) { if (props.data) {
formDataTrain.leaveWrote = props.data.leaveWrote; formDataTrain.leaveWrote = props.data.leaveWrote
formDataTrain.leaveStartDate = props.data.leaveStartDate; formDataTrain.leaveStartDate = props.data.leaveStartDate
formDataTrain.leaveEndDate = props.data.leaveEndDate; formDataTrain.leaveEndDate = props.data.leaveEndDate
formDataTrain.leaveTotal = props.data.leaveTotal; formDataTrain.leaveTotal = props.data.leaveTotal
formDataTrain.leavebirthDate = props.data.leavebirthDate; formDataTrain.leavebirthDate = props.data.leavebirthDate
formDataTrain.leavegovernmentDate = props.data.leavegovernmentDate; formDataTrain.leavegovernmentDate = props.data.leavegovernmentDate
formDataTrain.leaveSalary = props.data.leaveSalary; formDataTrain.leaveSalary = props.data.leaveSalary
formDataTrain.leaveSalaryText = props.data.leaveSalaryText; formDataTrain.leaveSalaryText = props.data.leaveSalaryText
formDataTrain.leaveNumber = props.data.leaveNumber; formDataTrain.leaveNumber = props.data.leaveNumber
formDataTrain.leaveAddress = props.data.leaveAddress; formDataTrain.leaveAddress = props.data.leaveAddress
formDataTrain.studyDayScholarship = props.data.studyDayScholarship; formDataTrain.studyDayScholarship = props.data.studyDayScholarship
formDataTrain.studyDayCountry = props.data.studyDayCountry; formDataTrain.studyDayCountry = props.data.studyDayCountry
formDataTrain.studyDayTrainingSubject = props.data.studyDayTrainingSubject; formDataTrain.studyDayTrainingSubject = props.data.studyDayTrainingSubject
formDataTrain.studyDayTrainingName = props.data.studyDayTrainingName; formDataTrain.studyDayTrainingName = props.data.studyDayTrainingName
formDataTrain.leaveDetail = props.data.leaveDetail; formDataTrain.leaveDetail = props.data.leaveDetail
// formDataTrain.leaveDocument = props.data.leaveDocument; // formDataTrain.leaveDocument = props.data.leaveDocument;
const leaveTotal = await calculateDurationYmd( const leaveTotal = await calculateDurationYmd(props.data.leaveStartDate, props.data.leaveEndDate)
new Date(props.data.leaveStartDate), formDataTrain.leaveTotal = leaveTotal
new Date(props.data.leaveEndDate) leaveDocumentList.value = props.data.leaveDocument
);
formDataStudy.leaveTotal = leaveTotal;
} }
}); })
</script> </script>
<template> <template>
@ -241,7 +216,7 @@ onMounted(async () => {
outlined outlined
label="เขียนที่" label="เขียนที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -271,20 +246,11 @@ onMounted(async () => {
lazy-rules lazy-rules
hide-bottom-space hide-bottom-space
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:model-value=" :model-value="formDataTrain.leaveStartDate != null ? date2Thai(formDataTrain.leaveStartDate) : null"
formDataTrain.leaveStartDate != null :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
? date2Thai(formDataTrain.leaveStartDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -320,20 +286,11 @@ onMounted(async () => {
hide-bottom-space hide-bottom-space
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:readonly="!formDataTrain.leaveStartDate" :readonly="!formDataTrain.leaveStartDate"
:model-value=" :model-value="formDataTrain.leaveEndDate != null ? date2Thai(formDataTrain.leaveEndDate) : null"
formDataTrain.leaveEndDate != null :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
? date2Thai(formDataTrain.leaveEndDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -381,22 +338,11 @@ onMounted(async () => {
dense dense
hide-bottom-space hide-bottom-space
:label="`${'วันที่เข้ารับราชการ'}`" :label="`${'วันที่เข้ารับราชการ'}`"
:model-value=" :model-value="formDataTrain.leavegovernmentDate != null ? date2Thai(formDataTrain.leavegovernmentDate) : null"
formDataTrain.leavegovernmentDate != null :rules="[val => !!val || `${'กรุณาเลือกวันที่เข้ารับราชการ'}`]"
? date2Thai(formDataTrain.leavegovernmentDate)
: null
"
:rules="[
(val) => !!val || `${'กรุณาเลือกวันที่เข้ารับราชการ'}`,
]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(--black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(--black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -429,44 +375,19 @@ onMounted(async () => {
readonly readonly
hide-bottom-space hide-bottom-space
:label="`${'วันเดือนปีเกิด'}`" :label="`${'วันเดือนปีเกิด'}`"
:model-value=" :model-value="formDataTrain.leavebirthDate != null ? date2Thai(formDataTrain.leavebirthDate) : null"
formDataTrain.leavebirthDate != null :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
? date2Thai(formDataTrain.leavebirthDate)
: null
"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <q-icon name="event" class="cursor-pointer" style="color: var(---black)"> </q-icon>
name="event"
class="cursor-pointer"
style="color: var(---black)"
>
</q-icon>
</template> </template>
</q-input> </q-input>
</template> </template>
</datepicker> </datepicker>
<q-input <q-input v-model="formattedSalary" class="col-12 col-sm-6 col-md-3" bg-color="white" dense outlined readonly label="เงินเดือนปัจจุบัน" />
v-model="formattedSalary"
class="col-12 col-sm-6 col-md-3"
bg-color="white"
dense
outlined
readonly
label="เงินเดือนปัจจุบัน"
/>
<q-input <q-input v-model="formDataTrain.leaveSalaryText" class="col-12 col-sm-6 col-md-3" dense readonly outlined bg-color="white" label="เงินเดือนปัจจุบัน (ตัวอักษร)" />
v-model="formDataTrain.leaveSalaryText"
class="col-12 col-sm-6 col-md-3"
dense
readonly
outlined
bg-color="white"
label="เงินเดือนปัจจุบัน (ตัวอักษร)"
/>
</div> </div>
</div> </div>
@ -481,7 +402,7 @@ onMounted(async () => {
outlined outlined
label="ด้าน/หลักสูตร" label="ด้าน/หลักสูตร"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกด้าน/หลักสูตร'}`]" :rules="[val => !!val || `${'กรุณากรอกด้าน/หลักสูตร'}`]"
/> />
<q-input <q-input
@ -493,7 +414,7 @@ onMounted(async () => {
outlined outlined
label="ณ สถานที่" label="ณ สถานที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอก ณ สถานที่'}`]" :rules="[val => !!val || `${'กรุณากรอก ณ สถานที่'}`]"
/> />
<q-input <q-input
@ -505,7 +426,7 @@ onMounted(async () => {
outlined outlined
label="ประเทศ" label="ประเทศ"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกประเทศ'}`]" :rules="[val => !!val || `${'กรุณากรอกประเทศ'}`]"
/> />
<q-input <q-input
@ -517,7 +438,7 @@ onMounted(async () => {
outlined outlined
label="ด้วยทุน" label="ด้วยทุน"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'กรุณากรอกด้วยทุน'}`]" :rules="[val => !!val || `${'กรุณากรอกด้วยทุน'}`]"
/> />
<q-input <q-input
@ -531,9 +452,7 @@ onMounted(async () => {
bg-color="white" bg-color="white"
mask="(###)-###-####" mask="(###)-###-####"
label="หมายเลขโทรศัพท์ที่ติดต่อได้" label="หมายเลขโทรศัพท์ที่ติดต่อได้"
:rules="[ :rules="[val => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`]"
(val) => !!val || `${'กรุณากรอกหมายเลขโทรศัพท์ที่ติดต่อได้'}`,
]"
/> />
<q-input <q-input
@ -545,52 +464,59 @@ onMounted(async () => {
outlined outlined
label="ที่อยู่ที่ติดต่อได้ระหว่างลา" label="ที่อยู่ที่ติดต่อได้ระหว่างลา"
hide-bottom-space hide-bottom-space
:rules="[ :rules="[val => !!val || `${'กรุณากรอก ที่อยู่ที่ติดต่อได้ระหว่างลา'}`]"
(val) => !!val || `${'กรุณากรอก ที่อยู่ที่ติดต่อได้ระหว่างลา'}`,
]"
/> />
</div> </div>
</div> </div>
<q-input <q-input v-model="formDataTrain.leaveDetail" class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen" bg-color="white" dense outlined type="textarea" label="รายละเอียด" />
v-model="formDataTrain.leaveDetail"
class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen"
bg-color="white"
dense
outlined
type="textarea"
label="รายละเอียด"
/>
<div class="col-12"> <div class="col-12">
<!-- multiple --> <!-- multiple -->
<q-file <q-file v-model="formDataTrain.leaveDocument" bg-color="white" multiple dense outlined label="เอกสารประกอบ">
v-model="formDataTrain.leaveDocument"
bg-color="white"
dense
outlined
label="เอกสารประกอบ"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataTrain.leaveDocument.length == 0">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div> -->
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</div> </div>
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs"> <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.fileName }} {{ file.name }}
</q-item-label> </q-item-label>
<q-item-label caption> </q-item-label> <q-item-label caption> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -602,26 +528,10 @@ onMounted(async () => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,23 +1,22 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, watch, onMounted } from "vue"; import { ref, reactive, watch, onMounted } from "vue"
import type { FormRef } from "@/modules/05_leave/interface/request/WorkInternationalForm"; import type { FormRef } from "@/modules/05_leave/interface/request/WorkInternationalForm"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
import genReport from "@/plugins/genreport"; import genReport from "@/plugins/genreport"
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { date2Thai, dialogConfirm, fails, dateToISO, success, messageError, showLoader } = const { date2Thai, dialogConfirm, fails, dateToISO, success, messageError, showLoader, hideLoader } = mixin
mixin; const edit = ref<boolean>(true)
const edit = ref<boolean>(true); const router = useRouter()
const router = useRouter(); const isSave = ref<boolean>(false)
const isSave = ref<boolean>(false);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
@ -33,7 +32,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataWorkInternational = reactive<any>({ const formDataWorkInternational = reactive<any>({
@ -44,14 +43,14 @@ const formDataWorkInternational = reactive<any>({
leaveDetail: "", leaveDetail: "",
leaveDocument: null, leaveDocument: null,
leaveDraftDocument: [], leaveDraftDocument: [],
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = { const FormRef: FormRef = {
@ -60,90 +59,76 @@ const FormRef: FormRef = {
leaveEndDate: leaveEndDateRef, leaveEndDate: leaveEndDateRef,
leaveDetail: leaveDetailRef, leaveDetail: leaveDetailRef,
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const nameFileDraft = ref<string>(""); const nameFileDraft = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in FormRef) { for (const key in FormRef) {
if (Object.prototype.hasOwnProperty.call(FormRef, key)) { if (Object.prototype.hasOwnProperty.call(FormRef, key)) {
const property = FormRef[key]; const property = FormRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
// Validate // Validate
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
if (formDataWorkInternational.leaveDocument) { if (formDataWorkInternational.leaveDocument) {
// // formDataWorkInternational.leaveDocument.forEach((file: File) => {
// if (formDataWorkInternational.leaveDocument.length > 0) { formData.append("leaveDocument", file)
// const blob = formDataWorkInternational.leaveDocument.slice(0, formDataWorkInternational.leaveDocument[0].size) })
// const newFile = new File(blob, nameFile.value, {
// type: formDataWorkInternational.leaveDocument[0].type,
// })
// formData.append("leaveDocument", newFile)
// }
formData.append("leaveDocument", formDataWorkInternational.leaveDocument); // formData.append("leaveDocument", formDataWorkInternational.leaveDocument)
} }
if (formDataWorkInternational.leaveDraftDocument) { if (formDataWorkInternational.leaveDraftDocument) {
formData.append( formData.append("leaveDraftDocument", formDataWorkInternational.leaveDraftDocument)
"leaveDraftDocument",
formDataWorkInternational.leaveDraftDocument
);
} }
formData.append("type", formDataWorkInternational.type); // formData.append("type", formDataWorkInternational.type) //
formData.append( formData.append("leaveStartDate", dateToISO(formDataWorkInternational.leaveStartDate)) //
"leaveStartDate", formData.append("leaveEndDate", dateToISO(formDataWorkInternational.leaveEndDate)) //
dateToISO(formDataWorkInternational.leaveStartDate) formData.append("leaveWrote", formDataWorkInternational.leaveWrote) //
); // formData.append("leaveDetail", formDataWorkInternational.leaveDetail) //
formData.append( props.onSubmit(formData)
"leaveEndDate",
dateToISO(formDataWorkInternational.leaveEndDate)
); //
formData.append("leaveWrote", formDataWorkInternational.leaveWrote); //
formData.append("leaveDetail", formDataWorkInternational.leaveDetail); //
props.onSubmit(formData);
} }
} }
//download function //download function
async function onClickDownloadFile(id: string, fileName: string) { async function onClickDownloadFile(id: string, fileName: string) {
showLoader(); showLoader()
await http await http
.get(config.API.leaveReport(id)) .get(config.API.leaveReport(id))
.then(async (res) => { .then(async res => {
const data = res.data.result; const data = res.data.result
await genReport(data, fileName); await genReport(data, fileName)
}) })
.catch((err) => { .catch(err => {
messageError($q, err); messageError($q, err)
}) })
.finally(() => { .finally(() => {
hideLoader(); hideLoader()
}); })
} }
/** /**
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function FetchCheck() { async function FetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -152,35 +137,34 @@ async function FetchCheck() {
EndLeaveDate: formDataWorkInternational.leaveEndDate ?? null, EndLeaveDate: formDataWorkInternational.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
formDataWorkInternational.leaveTotal = formDataWorkInternational.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
data.totalDate - data.sumDateWork - data.sumDateHoliday;
// formDataWorkInternational.leaveLast = data.totalDate // formDataWorkInternational.leaveLast = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
const leaveDraftDocument = ref<string>(); const leaveDocumentList = ref<any>()
const leaveDraftDocument = ref<string>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataWorkInternational.leaveWrote = props.data.leaveWrote; formDataWorkInternational.leaveWrote = props.data.leaveWrote
formDataWorkInternational.leaveStartDate = new Date( formDataWorkInternational.leaveStartDate = new Date(props.data.leaveStartDate)
props.data.leaveStartDate formDataWorkInternational.leaveEndDate = new Date(props.data.leaveEndDate)
); formDataWorkInternational.leaveDetail = props.data.leaveDetail
formDataWorkInternational.leaveEndDate = new Date(props.data.leaveEndDate);
formDataWorkInternational.leaveDetail = props.data.leaveDetail;
// formDataWorkInternational.leaveDocument = props.data.leaveDocument; // formDataWorkInternational.leaveDocument = props.data.leaveDocument;
leaveDraftDocument.value = props.data.leaveDraftDocument; leaveDraftDocument.value = props.data.leaveDraftDocument
leaveDocumentList.value = props.data.leaveDocument
} }
}); })
</script> </script>
<template> <template>
@ -202,7 +186,7 @@ onMounted(() => {
v-model="formDataWorkInternational.leaveWrote" v-model="formDataWorkInternational.leaveWrote"
label="เขียนที่" label="เขียนที่"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -234,21 +218,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataWorkInternational.leaveStartDate != null ? date2Thai(formDataWorkInternational.leaveStartDate) : null"
formDataWorkInternational.leaveStartDate != null
? date2Thai(formDataWorkInternational.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -284,21 +259,12 @@ onMounted(() => {
bg-color="white" bg-color="white"
:readonly="!formDataWorkInternational.leaveStartDate" :readonly="!formDataWorkInternational.leaveStartDate"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataWorkInternational.leaveEndDate != null ? date2Thai(formDataWorkInternational.leaveEndDate) : null"
formDataWorkInternational.leaveEndDate != null
? date2Thai(formDataWorkInternational.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -334,6 +300,7 @@ onMounted(() => {
ref="fileRef" ref="fileRef"
bg-color="white" bg-color="white"
v-model="formDataWorkInternational.leaveDocument" v-model="formDataWorkInternational.leaveDocument"
multiple
@added="fileUploadDoc" @added="fileUploadDoc"
dense dense
label="เอกสารประกอบ" label="เอกสารประกอบ"
@ -345,20 +312,40 @@ onMounted(() => {
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataWorkInternational.leaveDocument.length == 0">
<div class="col-12 row" v-if="!edit"> <q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> </div> -->
<div class="q-pl-sm text-weight-bold text-dark"> <div class="col-12" v-if="data">
เอกสารเพมเต <div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div> </div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
<div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
v-for="(file, index) in formDataWorkInternational.leaveDocument"
:key="index"
class="q-my-xs"
>
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.name }} {{ file.name }}
@ -375,9 +362,7 @@ onMounted(() => {
<div v-if="data && data.id" class="q-mt-md"> <div v-if="data && data.id" class="q-mt-md">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<q-icon name="mdi-numeric-4-circle" size="20px" color="primary" /> <q-icon name="mdi-numeric-4-circle" size="20px" color="primary" />
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">ดาวนโหลด/ปโหลดแบบฟอร</div>
ดาวนโหลด/ปโหลดแบบฟอร
</div>
</div> </div>
<q-card class="bg-grey-1 q-pa-sm" bordered> <q-card class="bg-grey-1 q-pa-sm" bordered>
<div class="row"> <div class="row">
@ -386,12 +371,7 @@ onMounted(() => {
<!-- <div class="q-pl-sm text-weight-bold text-dark text-center"> <!-- <div class="q-pl-sm text-weight-bold text-dark text-center">
ดาวนโหลด ดาวนโหลด
</div> --> </div> -->
<q-btn <q-btn color="primary" icon="download" label="ดาวน์โหลดแบบฟอร์ม" @click="onClickDownloadFile(data.id, `แบบฟอร์ม${data.leaveTypeName}`)" />
color="primary"
icon="download"
label="ดาวน์โหลดแบบฟอร์ม"
@click="onClickDownloadFile(data.id, `แบบฟอร์ม${data.leaveTypeName}`)"
/>
</div> </div>
</div> </div>
<div class="col-sm-5 q-my-sm"> <div class="col-sm-5 q-my-sm">
@ -399,15 +379,7 @@ onMounted(() => {
<!-- <div class="q-pl-sm text-weight-bold text-dark text-center"> <!-- <div class="q-pl-sm text-weight-bold text-dark text-center">
ปโหลด ปโหลด
</div> --> </div> -->
<q-file <q-file v-model="formDataWorkInternational.leaveDraftDocument" use-chips dense label="อัปโหลดแบบฟอร์ม" outlined bg-color="white" accept="application/pdf">
v-model="formDataWorkInternational.leaveDraftDocument"
use-chips
dense
label="อัปโหลดแบบฟอร์ม"
outlined
bg-color="white"
accept="application/pdf"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
@ -420,13 +392,7 @@ onMounted(() => {
<!-- <div class="q-pl-sm text-weight-bold text-dark text-center"> <!-- <div class="q-pl-sm text-weight-bold text-dark text-center">
ไฟลปโหลด ไฟลปโหลด
</div> --> </div> -->
<q-btn <q-btn icon="visibility" color="blue" label="ดาวน์โหลดไฟล์" :href="leaveDraftDocument" target="_blank" />
icon="visibility"
color="blue"
label="ดาวน์โหลดไฟล์"
:href="leaveDraftDocument"
target="_blank"
/>
</div> </div>
</div> </div>
<!-- <div class="col-md-1 self-end q-mb-sm"> <!-- <div class="col-md-1 self-end q-mb-sm">
@ -442,26 +408,10 @@ onMounted(() => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,32 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted } from "vue"; import { ref, reactive, computed, onMounted } from "vue"
import type { import type { FormData, FormRef } from "@/modules/05_leave/interface/request/FollowSpouseForm"
FormData, import { useCounterMixin } from "@/stores/mixin"
FormRef, import { useLeaveStore } from "@/modules/05_leave/store"
} from "@/modules/05_leave/interface/request/FollowSpouseForm"; import { useQuasar } from "quasar"
import { useCounterMixin } from "@/stores/mixin"; import http from "@/plugins/http"
import { useLeaveStore } from "@/modules/05_leave/store"; import config from "@/app.config"
import { useQuasar } from "quasar"; import { useRouter } from "vue-router"
import http from "@/plugins/http";
import config from "@/app.config";
import { useRouter } from "vue-router";
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const router = useRouter(); const router = useRouter()
const { const { dialogConfirm, date2Thai, arabicNumberToText, calculateDurationYmd, dateToISO, fails, success, messageError } = mixin
dialogConfirm, const edit = ref<boolean>(true)
date2Thai,
arabicNumberToText,
calculateDurationYmd,
dateToISO,
fails,
success,
messageError,
} = mixin;
const edit = ref<boolean>(true);
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
@ -42,7 +30,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataFollowSpouse = reactive<any>({ const formDataFollowSpouse = reactive<any>({
@ -61,28 +49,27 @@ const formDataFollowSpouse = reactive<any>({
coupleDayTotalHistory: null, coupleDayTotalHistory: null,
coupleDayStartDateHistory: null, coupleDayStartDateHistory: null,
coupleDayEndDateHistory: null, coupleDayEndDateHistory: null,
leaveDetail: leaveDetail: "ในกรณีลาติดต่อกับครั้งก่อน รวมทั้งนี้ด้วย เป็นเวลา ...ปี, ...เดือน, ...วัน", //
"ในกรณีลาติดต่อกับครั้งก่อน รวมทั้งนี้ด้วย เป็นเวลา ...ปี, ...เดือน, ...วัน", //
leaveDocument: [], // leaveDocument: [], //
}); })
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveSalaryRef = ref<object | null>(null); const leaveSalaryRef = ref<object | null>(null)
const leaveTotalRef = ref<object | null>(null); const leaveTotalRef = ref<object | null>(null)
const coupleDayNameRef = ref<object | null>(null); const coupleDayNameRef = ref<object | null>(null)
const leaveAddressRef = ref<object | null>(null); const leaveAddressRef = ref<object | null>(null)
const leaveDetailRef = ref<object | null>(null); const leaveDetailRef = ref<object | null>(null)
const coupleDayPositionRef = ref<object | null>(null); const coupleDayPositionRef = ref<object | null>(null)
const coupleDayLevelRef = ref<object | null>(null); const coupleDayLevelRef = ref<object | null>(null)
const coupleDayLevelCountryRef = ref<object | null>(null); const coupleDayLevelCountryRef = ref<object | null>(null)
const coupleDayCountryHistoryRef = ref<object | null>(null); const coupleDayCountryHistoryRef = ref<object | null>(null)
const coupleDayTotalHistoryRef = ref<object | null>(null); const coupleDayTotalHistoryRef = ref<object | null>(null)
const coupleDayStartDateHistoryRef = ref<object | null>(null); const coupleDayStartDateHistoryRef = ref<object | null>(null)
const coupleDayEndDateHistoryRef = ref<object | null>(null); const coupleDayEndDateHistoryRef = ref<object | null>(null)
const leaveDocumentRef = ref<object | null>(null); const leaveDocumentRef = ref<object | null>(null)
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const FormRef: FormRef = { const FormRef: FormRef = {
@ -102,80 +89,52 @@ const FormRef: FormRef = {
leaveDetail: leaveDetailRef, // leaveDetail: leaveDetailRef, //
leaveAddress: leaveAddressRef, // leaveAddress: leaveAddressRef, //
leaveDocument: leaveDocumentRef, leaveDocument: leaveDocumentRef,
}; }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */ /** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in FormRef) { for (const key in FormRef) {
if (Object.prototype.hasOwnProperty.call(FormRef, key)) { if (Object.prototype.hasOwnProperty.call(FormRef, key)) {
const property = FormRef[key]; const property = FormRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
// if (formDataFollowSpouse.leaveDocument.length > 0) { formDataFollowSpouse.leaveDocument.forEach((file: File) => {
// const blob = formDataFollowSpouse.leaveDocument.slice(0, formDataFollowSpouse.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataFollowSpouse.leaveDocument[0].type, // formData.append("leaveDocument", formDataFollowSpouse.leaveDocument);
// }) formData.append("type", formDataFollowSpouse.type) //
// formData.append("leaveDocument", newFile) formData.append("leaveStartDate", dateToISO(formDataFollowSpouse.leaveStartDate)) //
// } // formData.append("leaveEndDate", dateToISO(formDataFollowSpouse.leaveEndDate)) //
formData.append("leaveDocument", formDataFollowSpouse.leaveDocument); formData.append("coupleDayStartDateHistory", dateToISO(formDataFollowSpouse.coupleDayStartDateHistory)) //
formData.append("type", formDataFollowSpouse.type); // formData.append("coupleDayEndDateHistory", dateToISO(formDataFollowSpouse.coupleDayEndDateHistory)) //
formData.append( formData.append("leaveWrote", formDataFollowSpouse.leaveWrote) //
"leaveStartDate", formData.append("leaveDetail", formDataFollowSpouse.leaveDetail) //
dateToISO(formDataFollowSpouse.leaveStartDate) formData.append("leaveSalaryText", formDataFollowSpouse.leaveSalaryText) //
); // formData.append("leaveSalary", formDataFollowSpouse.leaveSalary) //
formData.append( formData.append("coupleDayTotalHistory", formDataFollowSpouse.coupleDayTotalHistory) //
"leaveEndDate", formData.append("coupleDayCountryHistory", formDataFollowSpouse.coupleDayCountryHistory) //
dateToISO(formDataFollowSpouse.leaveEndDate) formData.append("coupleDayLevelCountry", formDataFollowSpouse.coupleDayLevelCountry) //
); // formData.append("coupleDayLevel", formDataFollowSpouse.coupleDayLevel) //
formData.append( formData.append("coupleDayPosition", formDataFollowSpouse.coupleDayPosition) //
"coupleDayStartDateHistory", formData.append("coupleDayName", formDataFollowSpouse.coupleDayName) //
dateToISO(formDataFollowSpouse.coupleDayStartDateHistory) formData.append("leaveTotal", formDataFollowSpouse.leaveTotal) //
); // props.onSubmit(formData)
formData.append(
"coupleDayEndDateHistory",
dateToISO(formDataFollowSpouse.coupleDayEndDateHistory)
); //
formData.append("leaveWrote", formDataFollowSpouse.leaveWrote); //
formData.append("leaveDetail", formDataFollowSpouse.leaveDetail); //
formData.append("leaveSalaryText", formDataFollowSpouse.leaveSalaryText); //
formData.append("leaveSalary", formDataFollowSpouse.leaveSalary); //
formData.append(
"coupleDayTotalHistory",
formDataFollowSpouse.coupleDayTotalHistory
); //
formData.append(
"coupleDayCountryHistory",
formDataFollowSpouse.coupleDayCountryHistory
); //
formData.append(
"coupleDayLevelCountry",
formDataFollowSpouse.coupleDayLevelCountry
); //
formData.append("coupleDayLevel", formDataFollowSpouse.coupleDayLevel); //
formData.append(
"coupleDayPosition",
formDataFollowSpouse.coupleDayPosition
); //
formData.append("coupleDayName", formDataFollowSpouse.coupleDayName); //
formData.append("leaveTotal", formDataFollowSpouse.leaveTotal); //
props.onSubmit(formData);
} }
} }
@ -183,7 +142,7 @@ function onValidate() {
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function fetchCheck() { async function fetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -192,82 +151,67 @@ async function fetchCheck() {
EndLeaveDate: formDataFollowSpouse.leaveEndDate ?? null, EndLeaveDate: formDataFollowSpouse.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataFollowSpouse.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday; // formDataFollowSpouse.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday;
// formDataFollowSpouse.leaveTotal = data.totalDate; // formDataFollowSpouse.leaveTotal = data.totalDate;
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveTotal() { function updateLeaveTotal() {
fetchCheck(); fetchCheck()
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataFollowSpouse.leaveStartDate, formDataFollowSpouse.leaveEndDate)
formDataFollowSpouse.leaveStartDate, formDataFollowSpouse.leaveTotal = newLeaveTotal
formDataFollowSpouse.leaveEndDate
);
formDataFollowSpouse.leaveTotal = newLeaveTotal;
} }
/** /**
* function พเดทค LeaveTotal * function พเดทค LeaveTotal
*/ */
function updateLeaveHistoryTotal() { function updateLeaveHistoryTotal() {
const newLeaveTotal = calculateDurationYmd( const newLeaveTotal = calculateDurationYmd(formDataFollowSpouse.coupleDayStartDateHistory, formDataFollowSpouse.coupleDayEndDateHistory)
formDataFollowSpouse.coupleDayStartDateHistory, formDataFollowSpouse.coupleDayTotalHistory = newLeaveTotal
formDataFollowSpouse.coupleDayEndDateHistory
);
formDataFollowSpouse.coupleDayTotalHistory = newLeaveTotal;
} }
const leaveDocumentList = ref<any>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(async () => { onMounted(async () => {
if (props.data) { if (props.data) {
formDataFollowSpouse.leaveWrote = props.data.leaveWrote; formDataFollowSpouse.leaveWrote = props.data.leaveWrote
formDataFollowSpouse.leaveStartDate = new Date(props.data.leaveStartDate); formDataFollowSpouse.leaveStartDate = new Date(props.data.leaveStartDate)
formDataFollowSpouse.leaveEndDate = new Date(props.data.leaveEndDate); formDataFollowSpouse.leaveEndDate = new Date(props.data.leaveEndDate)
formDataFollowSpouse.leaveDetail = props.data.leaveDetail; formDataFollowSpouse.leaveDetail = props.data.leaveDetail
formDataFollowSpouse.leaveDocument = props.data.leaveDocument; formDataFollowSpouse.leaveDocument = props.data.leaveDocument
formDataFollowSpouse.leaveTotal = props.data.leaveTotal; formDataFollowSpouse.leaveTotal = props.data.leaveTotal
formDataFollowSpouse.leaveSalaryText = props.data.leaveSalaryText; formDataFollowSpouse.leaveSalaryText = props.data.leaveSalaryText
formDataFollowSpouse.leaveSalary = props.data.leaveSalary; formDataFollowSpouse.leaveSalary = props.data.leaveSalary
formDataFollowSpouse.coupleDayName = props.data.coupleDayName; formDataFollowSpouse.coupleDayName = props.data.coupleDayName
formDataFollowSpouse.coupleDayPosition = props.data.coupleDayPosition; formDataFollowSpouse.coupleDayPosition = props.data.coupleDayPosition
formDataFollowSpouse.coupleDayLevel = props.data.coupleDayLevel; formDataFollowSpouse.coupleDayLevel = props.data.coupleDayLevel
formDataFollowSpouse.coupleDayLevelCountry = formDataFollowSpouse.coupleDayLevelCountry = props.data.coupleDayLevelCountry
props.data.coupleDayLevelCountry; formDataFollowSpouse.coupleDayCountryHistory = props.data.coupleDayCountryHistory
formDataFollowSpouse.coupleDayCountryHistory = formDataFollowSpouse.coupleDayTotalHistory = props.data.coupleDayTotalHistory
props.data.coupleDayCountryHistory; formDataFollowSpouse.coupleDayStartDateHistory = props.data.coupleDayStartDateHistory
formDataFollowSpouse.coupleDayTotalHistory = formDataFollowSpouse.coupleDayEndDateHistory = props.data.coupleDayEndDateHistory
props.data.coupleDayTotalHistory; leaveDocumentList.value = props.data.leaveDocument
formDataFollowSpouse.coupleDayStartDateHistory =
props.data.coupleDayStartDateHistory;
formDataFollowSpouse.coupleDayEndDateHistory =
props.data.coupleDayEndDateHistory;
const leaveTotal = await calculateDurationYmd( const leaveTotal = await calculateDurationYmd(props.data.leaveStartDate, props.data.leaveEndDate)
new Date(props.data.leaveStartDate), formDataFollowSpouse.leaveTotal = leaveTotal
new Date(props.data.leaveEndDate)
);
formDataFollowSpouse.leaveTotal = leaveTotal;
const coupleDayTotalHistory = await calculateDurationYmd( const coupleDayTotalHistory = await calculateDurationYmd(props.data.coupleDayStartDateHistory, props.data.coupleDayEndDateHistory)
new Date(props.data.coupleDayStartDateHistory), formDataFollowSpouse.coupleDayTotalHistory = coupleDayTotalHistory
new Date(props.data.coupleDayEndDateHistory)
);
formDataFollowSpouse.coupleDayTotalHistory = coupleDayTotalHistory;
} }
}); })
</script> </script>
<template> <template>
@ -289,7 +233,7 @@ onMounted(async () => {
v-model="formDataFollowSpouse.leaveWrote" v-model="formDataFollowSpouse.leaveWrote"
label="เขียนที่" label="เขียนที่"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
class="col-12 col-md-4 col-sm-12 cursor-pointer inputgreen" class="col-12 col-md-4 col-sm-12 cursor-pointer inputgreen"
@ -320,21 +264,12 @@ onMounted(async () => {
bg-color="white" bg-color="white"
:readonly="!edit" :readonly="!edit"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataFollowSpouse.leaveStartDate != null ? date2Thai(formDataFollowSpouse.leaveStartDate) : null"
formDataFollowSpouse.leaveStartDate != null
? date2Thai(formDataFollowSpouse.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -370,21 +305,12 @@ onMounted(async () => {
bg-color="white" bg-color="white"
:readonly="!formDataFollowSpouse.leaveStartDate" :readonly="!formDataFollowSpouse.leaveStartDate"
class="full-width datepicker" class="full-width datepicker"
:model-value=" :model-value="formDataFollowSpouse.leaveEndDate != null ? date2Thai(formDataFollowSpouse.leaveEndDate) : null"
formDataFollowSpouse.leaveEndDate != null
? date2Thai(formDataFollowSpouse.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -442,7 +368,7 @@ onMounted(async () => {
v-model="formDataFollowSpouse.coupleDayName" v-model="formDataFollowSpouse.coupleDayName"
label="ชื่อคู่สมรส" label="ชื่อคู่สมรส"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'ชื่อคู่สมรส'}`]" :rules="[val => !!val || `${'ชื่อคู่สมรส'}`]"
/> />
</div> </div>
<div class="col-md-3 col-sm-12"> <div class="col-md-3 col-sm-12">
@ -457,7 +383,7 @@ onMounted(async () => {
v-model="formDataFollowSpouse.coupleDayPosition" v-model="formDataFollowSpouse.coupleDayPosition"
label="ตำแหน่งคู่สมรส" label="ตำแหน่งคู่สมรส"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'ตำแหน่งคู่สมรส'}`]" :rules="[val => !!val || `${'ตำแหน่งคู่สมรส'}`]"
/> />
</div> </div>
<div class="col-md-3 col-sm-12"> <div class="col-md-3 col-sm-12">
@ -472,7 +398,7 @@ onMounted(async () => {
v-model="formDataFollowSpouse.coupleDayLevel" v-model="formDataFollowSpouse.coupleDayLevel"
label="ระดับคู่สมรส" label="ระดับคู่สมรส"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'ระดับคู่สมรส'}`]" :rules="[val => !!val || `${'ระดับคู่สมรส'}`]"
/> />
</div> </div>
<div class="col-md-3 col-sm-12"> <div class="col-md-3 col-sm-12">
@ -487,12 +413,10 @@ onMounted(async () => {
v-model="formDataFollowSpouse.coupleDayLevelCountry" v-model="formDataFollowSpouse.coupleDayLevelCountry"
label="ไปปฏิบัติราชการ ณ ประเทศ" label="ไปปฏิบัติราชการ ณ ประเทศ"
:readonly="!edit" :readonly="!edit"
:rules="[(val) => !!val || `${'ปฏิบัติราชการ ณ ประเทศ'}`]" :rules="[val => !!val || `${'ปฏิบัติราชการ ณ ประเทศ'}`]"
/> />
</div> </div>
<div class="text-weight-bold text-dark col-12"> <div class="text-weight-bold text-dark col-12">ประวการลาตดตามคสมรสครงสดทาย</div>
ประวการลาตดตามคสมรสครงสดทาย
</div>
<datepicker <datepicker
class="col-12 col-md-3 col-sm-12 inputgreen" class="col-12 col-md-3 col-sm-12 inputgreen"
menu-class-name="modalfix" menu-class-name="modalfix"
@ -519,21 +443,12 @@ onMounted(async () => {
hide-bottom-space hide-bottom-space
bg-color="white" bg-color="white"
class="full-width" class="full-width"
:model-value=" :model-value="formDataFollowSpouse.coupleDayStartDateHistory != null ? date2Thai(formDataFollowSpouse.coupleDayStartDateHistory) : null"
formDataFollowSpouse.coupleDayStartDateHistory != null
? date2Thai(formDataFollowSpouse.coupleDayStartDateHistory)
: null
"
:label="`${'ตั้งแต่วันที่'}`" :label="`${'ตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -565,21 +480,12 @@ onMounted(async () => {
hide-bottom-space hide-bottom-space
bg-color="white" bg-color="white"
class="full-width" class="full-width"
:model-value=" :model-value="formDataFollowSpouse.coupleDayEndDateHistory != null ? date2Thai(formDataFollowSpouse.coupleDayEndDateHistory) : null"
formDataFollowSpouse.coupleDayEndDateHistory != null
? date2Thai(formDataFollowSpouse.coupleDayEndDateHistory)
: null
"
:label="`${'ถึงวันที่'}`" :label="`${'ถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -608,7 +514,7 @@ onMounted(async () => {
for="coupleDayCountryHistoryRef" for="coupleDayCountryHistoryRef"
v-model="formDataFollowSpouse.coupleDayCountryHistory" v-model="formDataFollowSpouse.coupleDayCountryHistory"
label="ประเทศ" label="ประเทศ"
:rules="[(val) => !!val || `${'กรุณาเลือกประเทศ'}`]" :rules="[val => !!val || `${'กรุณาเลือกประเทศ'}`]"
/> />
<q-input <q-input
@ -630,6 +536,7 @@ onMounted(async () => {
ref="fileRef" ref="fileRef"
bg-color="white" bg-color="white"
v-model="formDataFollowSpouse.leaveDocument" v-model="formDataFollowSpouse.leaveDocument"
multiple
@added="fileUploadDoc" @added="fileUploadDoc"
dense dense
label="เอกสารประกอบ" label="เอกสารประกอบ"
@ -641,20 +548,40 @@ onMounted(async () => {
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataFollowSpouse.leaveDocument.length == 0">
<div class="col-12 row" v-if="!edit"> <q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> </div> -->
<div class="q-pl-sm text-weight-bold text-dark"> <div class="col-12" v-if="data">
เอกสารเพมเต <div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div> </div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
<div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
v-for="(file, index) in formDataFollowSpouse.leaveDocument"
:key="index"
class="q-my-xs"
>
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.name }} {{ file.name }}
@ -671,26 +598,10 @@ onMounted(async () => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -1,34 +1,33 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref, onMounted } from "vue"; import { reactive, ref, onMounted } from "vue"
import { useCounterMixin } from "@/stores/mixin"; import { useCounterMixin } from "@/stores/mixin"
import { useQuasar } from "quasar"; import { useQuasar } from "quasar"
import type { RehabilitationForm } from "@/modules/05_leave/interface/request/AddAbsence"; import type { RehabilitationForm } from "@/modules/05_leave/interface/request/AddAbsence"
import { useLeaveStore } from "@/modules/05_leave/store"; import { useLeaveStore } from "@/modules/05_leave/store"
import http from "@/plugins/http"; import http from "@/plugins/http"
import config from "@/app.config"; import config from "@/app.config"
import { useRouter } from "vue-router"; import { useRouter } from "vue-router"
import genReport from "@/plugins/genreport"; import genReport from "@/plugins/genreport"
/** Use */ /** Use */
const dataStore = useLeaveStore(); const dataStore = useLeaveStore()
const $q = useQuasar(); const $q = useQuasar()
const mixin = useCounterMixin(); const mixin = useCounterMixin()
const { date2Thai, dialogConfirm, fails, dateToISO, success, messageError, showLoader } = const { date2Thai, dialogConfirm, fails, dateToISO, success, messageError, showLoader, hideLoader } = mixin
mixin; const router = useRouter()
const router = useRouter(); const edit = ref<boolean>(true)
const edit = ref<boolean>(true); const isSave = ref<boolean>(false)
const isSave = ref<boolean>(false); const files = ref<any>(null)
const files = ref<any>(null);
/** ตัวแปร ref สำหรับแสดง validate */ /** ตัวแปร ref สำหรับแสดง validate */
const leaveStartDateRef = ref<object | null>(null); const leaveStartDateRef = ref<object | null>(null)
const leaveEndDateRef = ref<object | null>(null); const leaveEndDateRef = ref<object | null>(null)
const leaveWroteRef = ref<object | null>(null); const leaveWroteRef = ref<object | null>(null)
/** รับ props มาจากหน้าหลัก */ /** รับ props มาจากหน้าหลัก */
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Object,
default: null, default: null,
}, },
onSubmit: { onSubmit: {
@ -39,7 +38,7 @@ const props = defineProps({
type: Function, type: Function,
default: () => "", default: () => "",
}, },
}); })
/** ข้อมูล v-model ของฟอร์ม */ /** ข้อมูล v-model ของฟอร์ม */
const formDataRehabilitation = reactive<any>({ const formDataRehabilitation = reactive<any>({
@ -50,79 +49,65 @@ const formDataRehabilitation = reactive<any>({
leaveDocument: "", leaveDocument: "",
leaveDetail: "", leaveDetail: "",
leaveDraftDocument: null, leaveDraftDocument: null,
}); })
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */ /** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const formRef: RehabilitationForm = { const formRef: RehabilitationForm = {
leaveStartDate: leaveStartDateRef, leaveStartDate: leaveStartDateRef,
leaveEndDate: leaveEndDateRef, leaveEndDate: leaveEndDateRef,
leaveWrote: leaveWroteRef, leaveWrote: leaveWroteRef,
}; }
/** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */ /** ฟังก์ชั่นตรวจสอบความถูกต้องก่อน บันทึก */
function onValidate() { function onValidate() {
const hasError = []; const hasError = []
for (const key in formRef) { for (const key in formRef) {
if (Object.prototype.hasOwnProperty.call(formRef, key)) { if (Object.prototype.hasOwnProperty.call(formRef, key)) {
const property = formRef[key]; const property = formRef[key]
if (property.value && typeof property.value.validate === "function") { if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate(); const isValid = property.value.validate()
hasError.push(isValid); hasError.push(isValid)
} }
} }
} }
if (hasError.every((result) => result === true)) { if (hasError.every(result => result === true)) {
const formData = new FormData(); const formData = new FormData()
if (formDataRehabilitation.leaveDocument) { if (formDataRehabilitation.leaveDocument) {
// if (formDataRehabilitation.leaveDocument.length > 0) { formDataRehabilitation.leaveDocument.forEach((file: File) => {
// const blob = formDataRehabilitation.leaveDocument.slice(0, formDataRehabilitation.leaveDocument[0].size) formData.append("leaveDocument", file)
// const newFile = new File(blob, nameFile.value, { })
// type: formDataRehabilitation.leaveDocument[0].type, // formData.append("leaveDocument", formDataRehabilitation.leaveDocument)
// })
// formData.append("leaveDocument", newFile)
// } //
formData.append("leaveDocument", formDataRehabilitation.leaveDocument);
} }
if (formDataRehabilitation.leaveDraftDocument) { if (formDataRehabilitation.leaveDraftDocument) {
formData.append( formData.append("leaveDraftDocument", formDataRehabilitation.leaveDraftDocument)
"leaveDraftDocument",
formDataRehabilitation.leaveDraftDocument
);
} }
formData.append("type", formDataRehabilitation.type); // formData.append("type", formDataRehabilitation.type) //
formData.append( formData.append("leaveStartDate", dateToISO(formDataRehabilitation.leaveStartDate)) //
"leaveStartDate", formData.append("leaveEndDate", dateToISO(formDataRehabilitation.leaveEndDate)) //
dateToISO(formDataRehabilitation.leaveStartDate) formData.append("leaveWrote", formDataRehabilitation.leaveWrote) //
); // formData.append("leaveDetail", formDataRehabilitation.leaveDetail) //
formData.append( props.onSubmit(formData)
"leaveEndDate",
dateToISO(formDataRehabilitation.leaveEndDate)
); //
formData.append("leaveWrote", formDataRehabilitation.leaveWrote); //
formData.append("leaveDetail", formDataRehabilitation.leaveDetail); //
props.onSubmit(formData);
} }
} }
/** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */ /** ส่วนของการประกาศและเลือกไฟล์เอกสารประกอบ */
const nameFile = ref<string>(""); const nameFile = ref<string>("")
const nameFileDraft = ref<string>(""); const nameFileDraft = ref<string>("")
const fileDocDataUpload = ref<File[]>([]); const fileDocDataUpload = ref<File[]>([])
const fileUploadDoc = async (files: any) => { const fileUploadDoc = async (files: any) => {
files.forEach((file: any) => { files.forEach((file: any) => {
fileDocDataUpload.value.push(file); fileDocDataUpload.value.push(file)
}); })
}; }
/** /**
* check าลาไดไหม จาก api * check าลาไดไหม จาก api
* @param formData * @param formData
*/ */
const isLeave = ref<boolean>(true); const isLeave = ref<boolean>(true)
async function FetchCheck() { async function FetchCheck() {
await http await http
.post(config.API.leaveCheck(), { .post(config.API.leaveCheck(), {
@ -131,49 +116,51 @@ async function FetchCheck() {
EndLeaveDate: formDataRehabilitation.leaveEndDate ?? null, EndLeaveDate: formDataRehabilitation.leaveEndDate ?? null,
}) })
.then((res: any) => { .then((res: any) => {
const data = res.data.result; const data = res.data.result
isLeave.value = data.isLeave; isLeave.value = data.isLeave
if (data.isLeave === true) { if (data.isLeave === true) {
// formDataRehabilitation.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday // formDataRehabilitation.leaveTotal = data.totalDate - data.sumDateWork - data.sumDateHoliday
// formDataRehabilitation.leaveTotal = data.totalDate // formDataRehabilitation.leaveTotal = data.totalDate
} else { } else {
fails($q, "ไม่สามารถลาได้"); fails($q, "ไม่สามารถลาได้")
} }
}) })
.catch((e: any) => { .catch((e: any) => {
messageError($q, e); messageError($q, e)
}); })
} }
//download function //download function
async function onClickDownloadFile(id: string, fileName: string) { async function onClickDownloadFile(id: string, fileName: string) {
showLoader(); showLoader()
await http await http
.get(config.API.leaveReport(id)) .get(config.API.leaveReport(id))
.then(async (res) => { .then(async res => {
const data = res.data.result; const data = res.data.result
await genReport(data, fileName); await genReport(data, fileName)
}) })
.catch((err) => { .catch(err => {
messageError($q, err); messageError($q, err)
}) })
.finally(() => { .finally(() => {
hideLoader(); hideLoader()
}); })
} }
const leaveDraftDocument = ref<string>(); const leaveDocumentList = ref<any>()
const leaveDraftDocument = ref<string>()
/** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */ /** ตรวจสอบว่ามีการส่งข้อมูลเข้ามาที่ฟอร์มไหม เมื่อมีการส่งจะ map ข้อมูลเข้า v-model ของฟอร์ม */
onMounted(() => { onMounted(() => {
if (props.data) { if (props.data) {
formDataRehabilitation.leaveWrote = props.data.leaveWrote; formDataRehabilitation.leaveWrote = props.data.leaveWrote
formDataRehabilitation.leaveStartDate = new Date(props.data.leaveStartDate); formDataRehabilitation.leaveStartDate = new Date(props.data.leaveStartDate)
formDataRehabilitation.leaveEndDate = new Date(props.data.leaveEndDate); formDataRehabilitation.leaveEndDate = new Date(props.data.leaveEndDate)
formDataRehabilitation.leaveDetail = props.data.leaveDetail; formDataRehabilitation.leaveDetail = props.data.leaveDetail
// formDataRehabilitation.leaveDocument = props.data.leaveDocument; // formDataRehabilitation.leaveDocument = props.data.leaveDocument;
leaveDraftDocument.value = props.data.leaveDraftDocument; leaveDraftDocument.value = props.data.leaveDraftDocument
leaveDocumentList.value = props.data.leaveDocument
} }
}); })
</script> </script>
<template> <template>
@ -193,7 +180,7 @@ onMounted(() => {
bg-color="white" bg-color="white"
label="เขียนที่" label="เขียนที่"
hide-bottom-space hide-bottom-space
:rules="[(val) => !!val || `${'เขียนที่'}`]" :rules="[val => !!val || `${'เขียนที่'}`]"
/> />
<datepicker <datepicker
@ -222,21 +209,12 @@ onMounted(() => {
dense dense
lazy-rules lazy-rules
hide-bottom-space hide-bottom-space
:model-value=" :model-value="formDataRehabilitation.leaveStartDate != null ? date2Thai(formDataRehabilitation.leaveStartDate) : null"
formDataRehabilitation.leaveStartDate != null
? date2Thai(formDataRehabilitation.leaveStartDate)
: null
"
:label="`${'ลาตั้งแต่วันที่'}`" :label="`${'ลาตั้งแต่วันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาตั้งแต่วันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
@ -271,67 +249,65 @@ onMounted(() => {
bg-color="white" bg-color="white"
hide-bottom-space hide-bottom-space
:readonly="!formDataRehabilitation.leaveStartDate" :readonly="!formDataRehabilitation.leaveStartDate"
:model-value=" :model-value="formDataRehabilitation.leaveEndDate != null ? date2Thai(formDataRehabilitation.leaveEndDate) : null"
formDataRehabilitation.leaveEndDate != null
? date2Thai(formDataRehabilitation.leaveEndDate)
: null
"
:label="`${'ลาถึงวันที่'}`" :label="`${'ลาถึงวันที่'}`"
:rules="[(val) => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]" :rules="[val => !!val || `${'กรุณาเลือกลาถึงวันที่'}`]"
> >
<template v-slot:prepend> <template v-slot:prepend>
<q-icon <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>
</template> </template>
</q-input> </q-input>
</template> </template>
</datepicker> </datepicker>
<q-input <q-input v-model="formDataRehabilitation.leaveDetail" class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen" bg-color="white" dense outlined type="textarea" label="รายละเอียด" />
v-model="formDataRehabilitation.leaveDetail"
class="col-12 col-md-12 col-sm-12 cursor-pointer inputgreen"
bg-color="white"
dense
outlined
type="textarea"
label="รายละเอียด"
/>
<div class="col-12"> <div class="col-12">
<!-- multiple --> <!-- multiple -->
<q-file <q-file v-model="formDataRehabilitation.leaveDocument" @added="fileUploadDoc" multiple use-chips bg-color="white" dense outlined label="เอกสารประกอบ">
v-model="formDataRehabilitation.leaveDocument"
@added="fileUploadDoc"
use-chips
bg-color="white"
dense
outlined
label="เอกสารประกอบ"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
</q-file> </q-file>
<!-- <div class="col-12" v-if="formDataRehabilitation.leaveDocument.length == 0">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ </q-card>
</div> -->
<div class="col-12" v-if="data">
<div class="col-12 col-md-12 col-sm-12">
<q-card bordered>
<!-- <div class="col-12">
<q-card class="q-pa-md" bordered> ไมรายการเอกสารประกอบ{{ leaveDocumentList }} </q-card>
</div> -->
<q-list separator>
<q-item v-for="(document, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section>
<q-item-label class="row items-baseline">
<div class="col">
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
</div>
<q-btn class="col-6" :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-card>
</div>
</div>
</div> </div>
<div class="col-12 row" v-if="!edit"> <div class="col-12 col-sm-6 row" v-if="!edit">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary"> <div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">เอกสารเพมเต</div>
เอกสารเพมเต
</div>
</div> </div>
<q-card bordered flat class="full-width"> <q-card bordered flat class="full-width">
<q-list separator> <q-list separator>
<q-item v-for="file in files" :key="file.key" class="q-my-xs"> <q-item v-for="(file, index) in leaveDocumentList" :key="index" class="q-my-xs">
<q-item-section> <q-item-section>
<q-item-label class="full-width ellipsis"> <q-item-label class="full-width ellipsis">
{{ file.fileName }} {{ file.name }}
</q-item-label> </q-item-label>
<q-item-label caption> </q-item-label> <q-item-label caption> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
@ -344,9 +320,7 @@ onMounted(() => {
<div v-if="data && data.id" class="q-mt-md"> <div v-if="data && data.id" class="q-mt-md">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center">
<q-icon name="mdi-numeric-4-circle" size="20px" color="primary" /> <q-icon name="mdi-numeric-4-circle" size="20px" color="primary" />
<div class="q-pl-sm text-weight-bold text-dark"> <div class="q-pl-sm text-weight-bold text-dark">ดาวนโหลด/ปโหลดแบบฟอร</div>
ดาวนโหลด/ปโหลดแบบฟอร
</div>
</div> </div>
<q-card class="bg-grey-1 q-pa-sm" bordered> <q-card class="bg-grey-1 q-pa-sm" bordered>
<div class="row"> <div class="row">
@ -355,12 +329,7 @@ onMounted(() => {
<!-- <div class="q-pl-sm text-weight-bold text-dark text-center"> <!-- <div class="q-pl-sm text-weight-bold text-dark text-center">
ดาวนโหลด ดาวนโหลด
</div> --> </div> -->
<q-btn <q-btn color="primary" icon="download" label="ดาวน์โหลดแบบฟอร์ม" @click="onClickDownloadFile(data.id, `แบบฟอร์ม${data.leaveTypeName}`)" />
color="primary"
icon="download"
label="ดาวน์โหลดแบบฟอร์ม"
@click="onClickDownloadFile(data.id, `แบบฟอร์ม${data.leaveTypeName}`)"
/>
</div> </div>
</div> </div>
<div class="col-sm-5 q-my-sm"> <div class="col-sm-5 q-my-sm">
@ -368,15 +337,7 @@ onMounted(() => {
<!-- <div class="q-pl-sm text-weight-bold text-dark text-center"> <!-- <div class="q-pl-sm text-weight-bold text-dark text-center">
ปโหลด ปโหลด
</div> --> </div> -->
<q-file <q-file v-model="formDataRehabilitation.leaveDraftDocument" use-chips dense label="อัปโหลดแบบฟอร์ม" outlined bg-color="white" accept="application/pdf">
v-model="formDataRehabilitation.leaveDraftDocument"
use-chips
dense
label="อัปโหลดแบบฟอร์ม"
outlined
bg-color="white"
accept="application/pdf"
>
<template v-slot:prepend> <template v-slot:prepend>
<q-icon name="attach_file" color="primary" /> <q-icon name="attach_file" color="primary" />
</template> </template>
@ -389,13 +350,7 @@ onMounted(() => {
<!-- <div class="q-pl-sm text-weight-bold text-dark text-center"> <!-- <div class="q-pl-sm text-weight-bold text-dark text-center">
ไฟลปโหลด ไฟลปโหลด
</div> --> </div> -->
<q-btn <q-btn icon="visibility" color="blue" label="ดาวน์โหลดไฟล์" :href="leaveDraftDocument" target="_blank" />
icon="visibility"
color="blue"
label="ดาวน์โหลดไฟล์"
:href="leaveDraftDocument"
target="_blank"
/>
</div> </div>
</div> </div>
<!-- <div class="col-md-1 self-end q-mb-sm"> <!-- <div class="col-md-1 self-end q-mb-sm">
@ -411,26 +366,10 @@ onMounted(() => {
<q-separator class="q-mt-sm" /> <q-separator class="q-mt-sm" />
<div class="row col-12 q-pt-md"> <div class="row col-12 q-pt-md">
<q-space /> <q-space />
<q-btn <q-btn v-if="!props.data || props.data.status == 'DRAFT'" id="onSubmit" type="submit" unelevated dense class="q-px-md items-center btnBlue" label="บันทึก"
v-if="!props.data || props.data.status == 'DRAFT'"
id="onSubmit"
type="submit"
unelevated
dense
class="q-px-md items-center btnBlue"
label="บันทึก"
><q-tooltip>นทกแบบราง</q-tooltip></q-btn ><q-tooltip>นทกแบบราง</q-tooltip></q-btn
> >
<q-btn <q-btn v-if="data" id="onSubmit" type="button" unelevated dense class="q-px-md items-center q-ml-sm" color="primary" label="ยื่นใบลา" @click="onConfirm"
v-if="data"
id="onSubmit"
type="button"
unelevated
dense
class="q-px-md items-center q-ml-sm"
color="primary"
label="ยื่นใบลา"
@click="onConfirm"
><q-tooltip>นใบลา</q-tooltip></q-btn ><q-tooltip>นใบลา</q-tooltip></q-btn
> >
</div> </div>

View file

@ -4,8 +4,8 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
console.log(props); console.log(props)
</script> </script>
<template> <template>
@ -61,19 +61,19 @@ console.log(props);
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -4,7 +4,7 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
</script> </script>
<template> <template>
<q-card-section> <q-card-section>
@ -55,19 +55,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -4,7 +4,7 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
</script> </script>
<template> <template>
@ -48,19 +48,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -4,7 +4,7 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
</script> </script>
<template> <template>
@ -60,19 +60,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -4,7 +4,7 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
</script> </script>
<template> <template>
@ -39,9 +39,7 @@ const props = defineProps({
<div class="col">{{ props.data.leaveTypeDay }}</div> <div class="col">{{ props.data.leaveTypeDay }}</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8"> <div class="col text-grey-8">ลาครงสดทายในประเภทน เมอวนท</div>
ลาครงสดทายในประเภทน เมอวนท
</div>
<div class="col">{{ props.data.leaveLastStart }}</div> <div class="col">{{ props.data.leaveLastStart }}</div>
</div> </div>
<div class="row"> <div class="row">
@ -58,19 +56,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -4,7 +4,7 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
</script> </script>
<template> <template>
<q-card-section> <q-card-section>
@ -43,9 +43,7 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เงนเดอนปจจ</div> <div class="col text-grey-8">เงนเดอนปจจ</div>
<div class="col"> <div class="col">{{ props.data.leaveSalary }} ({{ props.data.leaveSalaryText }})</div>
{{ props.data.leaveSalary }} ({{ props.data.leaveSalaryText }})
</div>
</div> </div>
<div class="row"> <div class="row">
@ -79,19 +77,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -41,11 +41,20 @@ const props = defineProps({
<div class="col" v-else>-</div> <div class="col" v-else>-</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแบบฟอร</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDraftDocument"> <div class="col">
<q-btn :href="props.data.leaveDraftDocument" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px"> <q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn> <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
<div v-for="(document, index) in props.data.leaveDocument" :key="index">
<div>
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
<q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</div>
</div>
</div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -84,10 +84,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn :href="props.data.leaveDocument" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px"> <q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn> <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
<div v-for="(document, index) in props.data.leaveDocument" :key="index">
<div>
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
<q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</div>
</div>
</div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -80,10 +80,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn :href="props.data.leaveDocument" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px"> <q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn> <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
<div v-for="(document, index) in props.data.leaveDocument" :key="index">
<div>
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
<q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</div>
</div>
</div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -4,7 +4,7 @@ const props = defineProps({
type: Object, type: Object,
required: true, required: true,
}, },
}); })
</script> </script>
<template> <template>
@ -73,19 +73,19 @@ const props = defineProps({
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแนบ</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDocument"> <div class="col">
<q-btn <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
:href="props.data.leaveDocument" <div v-for="(document, index) in props.data.leaveDocument" :key="index">
target="_blank" <div>
outline {{ "เอกสารแนบฉบับที่" + (index + 1) }}
color="blue" <q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
label="ดาวน์โหลด" <q-tooltip>ดาวนโหลดไฟล</q-tooltip>
size="12px" </q-btn>
> </div>
<q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn </div>
> </div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -41,11 +41,20 @@ const props = defineProps({
<div class="col" v-else>-</div> <div class="col" v-else>-</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col text-grey-8">เอกสารแบบฟอร</div> <div class="col text-grey-8">เอกสารแนบ</div>
<div class="col" v-if="props.data.leaveDraftDocument"> <div class="col">
<q-btn :href="props.data.leaveDraftDocument" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px"> <q-tooltip>ดาวนโหลดไฟล</q-tooltip></q-btn> <div v-if="props.data.leaveDocument && props.data.leaveDocument.length > 0">
<div v-for="(document, index) in props.data.leaveDocument" :key="index">
<div>
{{ "เอกสารแนบฉบับที่" + (index + 1) }}
<q-btn :href="document" target="_blank" outline color="blue" label="ดาวน์โหลด" size="12px">
<q-tooltip>ดาวนโหลดไฟล</q-tooltip>
</q-btn>
</div>
</div>
</div>
<div v-else>-</div>
</div> </div>
<div class="col" v-else>-</div>
</div> </div>
</div> </div>
</q-card-section> </q-card-section>

View file

@ -48,7 +48,7 @@ const formData = reactive<any>({
leaveAddress: "", // leaveAddress: "", //
leaveNumber: "", // leaveNumber: "", //
leaveDetail: "", // leaveDetail: "", //
leaveDocument: "", // leaveDocument: [], //
leaveDraftDocument: "", // leaveDraftDocument: "", //
leaveLastStart: null, // ( )(Auto) leaveLastStart: null, // ( )(Auto)
leaveLastEnd: null, // ( )(Auto) leaveLastEnd: null, // ( )(Auto)
@ -216,18 +216,18 @@ function onSubmit(formData: FormData) {
}) })
.finally(() => { .finally(() => {
hideLoader() hideLoader()
fetchDataDetail(personalId.value)
}) })
}) })
} }
function onConfirm() { function onConfirm(id: string) {
console.log(personalId.value)
dialogConfirm( dialogConfirm(
$q, $q,
async () => { async () => {
showLoader() showLoader()
await http await http
.get(config.API.leaveUserSendId(personalId.value)) .put(config.API.leaveUserSendId(personalId.value), { reason: "" })
.then(() => { .then(() => {
// router.push("/leave") // router.push("/leave")
success($q, "ยื่นใบลาสำเร็จ") success($q, "ยื่นใบลาสำเร็จ")
@ -259,7 +259,7 @@ onMounted(() => {
<q-btn to="/leave" icon="mdi-arrow-left" unelevated round dense flat color="primary" class="q-mr-sm" /> <q-btn to="/leave" icon="mdi-arrow-left" unelevated round dense flat color="primary" class="q-mr-sm" />
<div> <div>
แกไขใบลา แกไขใบลา
{{ formData.leaveTypeName }} {{ personalId }} {{ formData.leaveTypeName }}
</div> </div>
</div> </div>
<q-form ref="myform" class="col-12"> <q-form ref="myform" class="col-12">