diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue index fb6da1c..63e1f13 100644 --- a/src/components/HelloWorld.vue +++ b/src/components/HelloWorld.vue @@ -38,7 +38,7 @@
- {{ date2Thai(Thai) }} + {{ Thai }}
@@ -79,61 +79,29 @@
- -
+ +
-
- - +
+ +
- -
- - +
+ +
-
+
@@ -178,15 +155,36 @@ label="นอกสถานที่" />
-
+
+
+
+
@@ -194,18 +192,21 @@
-
+
+

+ *หมายเหตุ คลิกลงเวลาเข้างานแล้วระบบจะลงเวลาทันที +

@@ -259,23 +260,26 @@ import { ref, onMounted } from "vue"; import { useCounterMixin } from "@/stores/mixin"; import { useRouter } from "vue-router"; import moment, { Moment } from "moment"; +import type { FormRef } from "@/modules/checkin/interface/response/checkin"; const mixin = useCounterMixin(); const { date2Thai } = mixin; const router = useRouter(); -const dateNow = ref(new Date()); -const Thai = ref(dateNow.value); +const dateNow = ref(new Date()); +const Thai = ref(date2Thai(dateNow.value)); const checkIn = ref(true); //เช็คการเช็คอิน ถ้าลงเวลาครั้งแรกเป็นเช็คอิน(สีเขียว) true แต่ถ้าครั้ง 2 เป็นเช็คเอ้าท์(สีแดง) -const location = ref("สำนักงาน ก.ก"); -const coordinates = ref("13° 43’ 45” N 100° 31’ 26” E"); -const workplace = ref("in-place"); -const model = ref(null); -const options = ref([ +const location = ref("สำนักงาน ก.ก"); +const coordinates = ref("13° 43’ 45” N 100° 31’ 26” E"); +const workplace = ref("in-place"); +const useLocation = ref(""); +const model = ref(""); +const options = ref([ "ปฏิบัติงานที่บ้าน", "ลืมลงเวลาปฏิบัติงาน", "ไปประชุม/อบรม/สัมมนา/ปฏิบัติงานที่บ้านนอกสถานที่", "ขออนุญาตออกนอกสถานที่", + "อื่นๆ", ]); const camera = ref(false); @@ -285,12 +289,14 @@ const mediaStream = ref(null); const video = ref(null); const canvas = ref(null); const hasPhoto = ref(true); -const img = ref(); +const img = ref(null); -const videoWidth = ref(335); -const videoHeight = ref(350); -const canvasWidth = ref(335); -const canvasHeight = ref(350); +const useLocationRef = ref(null); +const modelRef = ref(null); +const objectRef: FormRef = { + model: modelRef, + useLocation: useLocationRef, +}; const photo = () => { camera.value = true; @@ -312,7 +318,49 @@ function capturePhoto() { console.error("Canvas context not available"); return; } - context.drawImage(videoElement, 0, 0, 335, 270); + const desiredWidth = 150; + const desiredHeight = 200; + const zoomFactor = 10; + + const videoAspectRatio = videoElement.videoWidth / videoElement.videoHeight; + const canvasAspectRatio = desiredWidth / desiredHeight; + + let drawWidth, drawHeight; + + if (videoAspectRatio > canvasAspectRatio) { + drawWidth = desiredWidth * zoomFactor; + drawHeight = (desiredWidth * zoomFactor) / videoAspectRatio; + } else { + drawWidth = desiredHeight * zoomFactor * videoAspectRatio; + drawHeight = desiredHeight * zoomFactor; + } + + canvasElement.width = drawWidth; + canvasElement.height = drawHeight; + if (context) { + context.imageSmoothingEnabled = true; + context.imageSmoothingQuality = "low"; + } + + // context.drawImage( + // videoElement, + // 0, + // 0, + // canvasElement.width, + // canvasElement.height + // ); + context.drawImage( + videoElement, + 0, + 0, + videoElement.videoWidth, + videoElement.videoHeight, + 0, + 0, + drawWidth, + drawHeight + ); + //ไฟล์รูป const dataURL = canvasElement.toDataURL(".image/.png"); img.value = dataURL; @@ -335,6 +383,10 @@ const setupCamera = async () => { console.error("Error accessing camera:", error); } }; +function refreshPhoto() { + hasPhoto.value = true; + img.value = ""; +} // const time = new Date().toLocaleTimeString(); const formattedS = ref(); @@ -356,6 +408,32 @@ function updateClock() { } setInterval(updateClock, 1000); +function selectLocation() { + if (model.value === "อื่นๆ") { + useLocation.value = ""; + } else { + useLocation.value = model.value; + } +} + +function validateForm() { + const hasError = []; + for (const key in objectRef) { + if (Object.prototype.hasOwnProperty.call(objectRef, key)) { + const property = objectRef[key]; + if (property.value && typeof property.value.validate === "function") { + const isValid = property.value.validate(); + hasError.push(isValid); + } + } + } + if (hasError.every((result) => result === true)) { + confirm(); + } else { + console.log("ไม่ผ่าน "); + } +} + const getClass = (val: boolean) => { return { "bg-primary text-white col-12 row items-center q-px-md q-py-sm": val, @@ -369,4 +447,38 @@ const getClass = (val: boolean) => { .q-card.cardImg:hover { border: 1px solid #02a998 !important; } + +.center-icon { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} +.card-container { + position: relative; + overflow: hidden; + height: 350px; /* Adjust as needed */ + background: #f6f5f5; +} + +.video-container, +.image-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.video-element, +.image-element { + width: 100%; + height: 100%; + object-fit: cover; + border-radius: 5px; /* Adjust as needed */ +} + +.canvas-element { + display: none; /* Adjust as needed */ +} diff --git a/src/modules/checkin/componenst/tableHistory.vue b/src/modules/checkin/componenst/tableHistory.vue index 1fdd3e5..ffc7b39 100644 --- a/src/modules/checkin/componenst/tableHistory.vue +++ b/src/modules/checkin/componenst/tableHistory.vue @@ -196,5 +196,8 @@ const resetFilter = () => { .q-table thead tr:first-child th { top: 0; } + .text-caption { + text-align: left; + } } diff --git a/src/modules/checkin/interface/response/checkin.ts b/src/modules/checkin/interface/response/checkin.ts new file mode 100644 index 0000000..23300b3 --- /dev/null +++ b/src/modules/checkin/interface/response/checkin.ts @@ -0,0 +1,7 @@ +interface FormRef { + model: object | null; + useLocation: object | null; + [key: string]: any; +} + +export type { FormRef };