เช็คเวลาต้องลงเวลาเข้าหรือออกงาน (USER)
This commit is contained in:
parent
3083ea8dcb
commit
07b02a7818
4 changed files with 128 additions and 22 deletions
|
|
@ -9,5 +9,6 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
|
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyBzPSF5NxUZ1G8DKBnJvJPTqCR0Ct2xf58&libraries=places"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,11 @@ const center = ref<any>()
|
||||||
const location = ref<string>('')
|
const location = ref<string>('')
|
||||||
const test = ref()
|
const test = ref()
|
||||||
|
|
||||||
// hook
|
const emit = defineEmits(["update:location"]);
|
||||||
onMounted(() => {
|
const updateLocation = (location: any, namePOI: string) => {
|
||||||
findNearestPlace()
|
// ส่ง event ไปยัง parent component เพื่ออัพเดทค่า props
|
||||||
})
|
emit("update:location", location, namePOI);
|
||||||
|
};
|
||||||
|
|
||||||
// หาตำแหน่ง
|
// หาตำแหน่ง
|
||||||
function findNearestPlace() {
|
function findNearestPlace() {
|
||||||
|
|
@ -25,7 +26,6 @@ function findNearestPlace() {
|
||||||
// ส่ง Location ไปยัง API เพื่อหาสถานที่ที่ใกล้ที่สุด
|
// ส่ง Location ไปยัง API เพื่อหาสถานที่ที่ใกล้ที่สุด
|
||||||
findNearestPlaceFromAPI(userLocation)
|
findNearestPlaceFromAPI(userLocation)
|
||||||
center.value = userLocation
|
center.value = userLocation
|
||||||
console.log(center.value)
|
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
|
|
@ -36,6 +36,8 @@ function findNearestPlace() {
|
||||||
console.error('เบราว์เซอร์ไม่รองรับการระบุตำแหน่ง')
|
console.error('เบราว์เซอร์ไม่รองรับการระบุตำแหน่ง')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function findNearestPlaceFromAPI(userLocation: any) {
|
function findNearestPlaceFromAPI(userLocation: any) {
|
||||||
const placesService = new google.maps.places.PlacesService(
|
const placesService = new google.maps.places.PlacesService(
|
||||||
document.createElement('div')
|
document.createElement('div')
|
||||||
|
|
@ -49,15 +51,22 @@ function findNearestPlaceFromAPI(userLocation: any) {
|
||||||
|
|
||||||
placesService.nearbySearch(request, (results: any, status: any) => {
|
placesService.nearbySearch(request, (results: any, status: any) => {
|
||||||
if (status === google.maps.places.PlacesServiceStatus.OK) {
|
if (status === google.maps.places.PlacesServiceStatus.OK) {
|
||||||
console.log('Nearby places:', results[0])
|
// console.log('Nearby places:', results[0])
|
||||||
const place = results[0]
|
const place = results[0]
|
||||||
location.value = place.name
|
location.value = place.name
|
||||||
test.value = place.geometry.location
|
test.value = place.geometry.location
|
||||||
|
updateLocation(center.value,location.value)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
console.error('Error fetching nearby places:', status)
|
console.error('Error fetching nearby places:', status)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hook
|
||||||
|
onMounted(() => {
|
||||||
|
findNearestPlace()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import CustomComponent from '@/components/CustomDialog.vue'
|
import CustomComponent from '@/components/CustomDialog.vue'
|
||||||
|
import { Loading, QSpinnerCube } from "quasar";
|
||||||
|
|
||||||
export const useCounterMixin = defineStore('mixin', () => {
|
export const useCounterMixin = defineStore('mixin', () => {
|
||||||
function date2Thai(srcDate: Date, isFullMonth = false, isTime = false) {
|
function date2Thai(srcDate: Date, isFullMonth = false, isTime = false) {
|
||||||
|
|
@ -70,6 +71,19 @@ export const useCounterMixin = defineStore('mixin', () => {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const showLoader = () => {
|
||||||
|
Loading.show({
|
||||||
|
spinner: QSpinnerCube,
|
||||||
|
spinnerSize: 140,
|
||||||
|
spinnerColor: "primary",
|
||||||
|
backgroundColor: "white",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const hideLoader = () => {
|
||||||
|
Loading.hide();
|
||||||
|
};
|
||||||
|
|
||||||
function covertDateObject(date: string) {
|
function covertDateObject(date: string) {
|
||||||
if (date) {
|
if (date) {
|
||||||
const dateParts = date.split('/')
|
const dateParts = date.split('/')
|
||||||
|
|
@ -116,6 +130,8 @@ export const useCounterMixin = defineStore('mixin', () => {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
date2Thai,
|
date2Thai,
|
||||||
|
showLoader,
|
||||||
|
hideLoader,
|
||||||
covertDateObject,
|
covertDateObject,
|
||||||
dialogConfirm,
|
dialogConfirm,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,11 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted } from 'vue'
|
import { ref,reactive, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useQuasar } from 'quasar'
|
import { useQuasar } from 'quasar'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import Camera from 'simple-vue-camera'
|
import Camera from 'simple-vue-camera'
|
||||||
|
import http from "@/plugins/http";
|
||||||
|
import config from "@/app.config";
|
||||||
|
|
||||||
// import Type
|
// import Type
|
||||||
import type { FormRef } from '@/interface/response/checkin'
|
import type { FormRef } from '@/interface/response/checkin'
|
||||||
|
|
@ -13,23 +15,35 @@ import MapCheck from '@/components/MapCheckin.vue'
|
||||||
import { useCounterMixin } from '@/stores/mixin'
|
import { useCounterMixin } from '@/stores/mixin'
|
||||||
|
|
||||||
const mixin = useCounterMixin()
|
const mixin = useCounterMixin()
|
||||||
const { date2Thai, dialogConfirm } = mixin
|
const { date2Thai, showLoader,hideLoader } = mixin
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const $q = useQuasar()
|
const $q = useQuasar()
|
||||||
|
|
||||||
const stetusCheckin = ref(true)
|
|
||||||
|
|
||||||
onMounted(() => {
|
const stetusCheckin = ref<boolean>(true)
|
||||||
updateClock()
|
const checkInId = ref<string|null> (null)
|
||||||
})
|
/** function เช็คเวลาต้องลงเวลาเข้าหรือออกงาน */
|
||||||
|
async function fetchCheckTime() {
|
||||||
|
showLoader()
|
||||||
|
await http.get(config.API.checkTime())
|
||||||
|
.then((res) => {
|
||||||
|
const data = res.data.result
|
||||||
|
stetusCheckin.value = data.checkInId ? false :true;
|
||||||
|
checkInId.value = data.checkInId ? data.checkInId : ""
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
}).finally(() => {
|
||||||
|
hideLoader();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
//time
|
/** ref อัพเดทเวลา*/
|
||||||
const dateNow = ref<Date>(new Date())
|
const dateNow = ref<Date>(new Date())
|
||||||
const Thai = ref<Date>(dateNow.value)
|
const Thai = ref<Date>(dateNow.value)
|
||||||
const formattedS = ref()
|
const formattedS = ref()
|
||||||
const formattedM = ref()
|
const formattedM = ref()
|
||||||
const formattedH = ref()
|
const formattedH = ref()
|
||||||
|
/** function อัพเดทเวลา*/
|
||||||
function updateClock() {
|
function updateClock() {
|
||||||
const date = Date.now()
|
const date = Date.now()
|
||||||
const hh = moment(date).format('HH')
|
const hh = moment(date).format('HH')
|
||||||
|
|
@ -41,9 +55,24 @@ function updateClock() {
|
||||||
}
|
}
|
||||||
setInterval(updateClock, 1000)
|
setInterval(updateClock, 1000)
|
||||||
|
|
||||||
|
// const lat = ref<number>()
|
||||||
|
// const lng = ref<number>()
|
||||||
|
// const POI = ref<string>("")
|
||||||
|
const formLocation = reactive({
|
||||||
|
lat: null,
|
||||||
|
lng: null,
|
||||||
|
POI: "",
|
||||||
|
})
|
||||||
|
async function updateLocation(location:any,namePOI:string) {
|
||||||
|
formLocation.lat = location.lat
|
||||||
|
formLocation.lng = location.lng
|
||||||
|
formLocation.POI = namePOI
|
||||||
|
}
|
||||||
|
|
||||||
//location
|
//location
|
||||||
|
const remark = ref<string>('')
|
||||||
const location = ref<string>('')
|
const location = ref<string>('')
|
||||||
const coordinates = ref<string>('13° 43’ 45” N 100° 31’ 26” E')
|
const coordinates = ref<string>('')
|
||||||
const workplace = ref<string>('in-place')
|
const workplace = ref<string>('in-place')
|
||||||
const useLocation = ref<string | null>('')
|
const useLocation = ref<string | null>('')
|
||||||
const model = ref<string | null>('')
|
const model = ref<string | null>('')
|
||||||
|
|
@ -62,28 +91,48 @@ function selectLocation() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//camera
|
//camera
|
||||||
|
|
||||||
const camera = ref<InstanceType<typeof Camera>>()
|
const camera = ref<InstanceType<typeof Camera>>()
|
||||||
const cameraIsOn = ref<boolean>(false)
|
const cameraIsOn = ref<boolean>(false)
|
||||||
|
const fileImg = ref<any>()
|
||||||
const img = ref<any>(undefined)
|
const img = ref<any>(undefined)
|
||||||
const photoWidth = ref<number>(350)
|
const photoWidth = ref<number>(350)
|
||||||
const photoHeight = ref<number>(350)
|
const photoHeight = ref<number>(350)
|
||||||
|
|
||||||
const openCamera = () => {
|
const openCamera = async () => {
|
||||||
cameraIsOn.value ? camera.value?.stop() : camera.value?.start()
|
// change camera device
|
||||||
|
if (cameraIsOn.value) {
|
||||||
|
camera.value?.stop()
|
||||||
|
} else {
|
||||||
|
await camera.value?.start()
|
||||||
|
changeCamera()
|
||||||
|
}
|
||||||
cameraIsOn.value = !cameraIsOn.value
|
cameraIsOn.value = !cameraIsOn.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// change camera device
|
||||||
|
const changeCamera = async () => {
|
||||||
|
const devices: any = await camera.value?.devices(['videoinput'])
|
||||||
|
const device = await devices[0]
|
||||||
|
camera.value?.changeCamera(device.deviceId)
|
||||||
|
|
||||||
|
}
|
||||||
async function capturePhoto() {
|
async function capturePhoto() {
|
||||||
const imageBlob: any = await camera.value?.snapshot(
|
const imageBlob: any = await camera.value?.snapshot(
|
||||||
{ width: photoWidth.value, height: photoHeight.value },
|
{ width: photoWidth.value, height: photoHeight.value },
|
||||||
'image/png',
|
'image/png',
|
||||||
0.5
|
0.5
|
||||||
)
|
)
|
||||||
|
console.log(imageBlob);
|
||||||
|
const fileName = 'photo.image';
|
||||||
|
|
||||||
|
const file = new File([imageBlob], fileName, { type: 'image/png' });
|
||||||
|
fileImg.value = file
|
||||||
|
|
||||||
//ไฟล์รูป
|
//ไฟล์รูป
|
||||||
camera.value?.stop()
|
camera.value?.stop()
|
||||||
const url = URL.createObjectURL(imageBlob)
|
const url = URL.createObjectURL(imageBlob)
|
||||||
img.value = url
|
img.value = url
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshPhoto() {
|
function refreshPhoto() {
|
||||||
|
|
@ -98,6 +147,8 @@ const objectRef: FormRef = {
|
||||||
model: modelRef,
|
model: modelRef,
|
||||||
useLocation: useLocationRef,
|
useLocation: useLocationRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function validateForm() {
|
function validateForm() {
|
||||||
const hasError = []
|
const hasError = []
|
||||||
for (const key in objectRef) {
|
for (const key in objectRef) {
|
||||||
|
|
@ -117,10 +168,33 @@ function validateForm() {
|
||||||
}
|
}
|
||||||
// ยืนยันการลงเวลา
|
// ยืนยันการลงเวลา
|
||||||
const dialogTime = ref<boolean>(false)
|
const dialogTime = ref<boolean>(false)
|
||||||
const confirm = () => {
|
async function confirm () {
|
||||||
|
const isLocation = workplace.value === "in-place";
|
||||||
|
const formdata = new FormData();
|
||||||
|
formdata.append("lat", formLocation.lat);
|
||||||
|
formdata.append("lon", formLocation.lng);
|
||||||
|
formdata.append("POI", formLocation.POI);
|
||||||
|
formdata.append("isLocation", isLocation.toString());
|
||||||
|
formdata.append("locationName", useLocation.value);
|
||||||
|
formdata.append("Img", fileImg.value);
|
||||||
|
formdata.append("remark", remark.value);
|
||||||
|
formdata.append("CheckInId", checkInId.value);
|
||||||
|
await http.post(config.API.checkin(),formdata)
|
||||||
|
.then(async(res) => {
|
||||||
|
const data = res.data.result
|
||||||
|
console.log(res.data.result);
|
||||||
|
const dateTimeString = data.date.toString()
|
||||||
|
const timeOnly = dateTimeString.split(" ")[1];
|
||||||
|
console.log(timeOnly);
|
||||||
|
dialogTime.value = true
|
||||||
|
await fetchCheckTime()
|
||||||
|
}).catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
|
||||||
// ยิงไปที่ api แล้วแสดง popup
|
// ยิงไปที่ api แล้วแสดง popup
|
||||||
dialogTime.value = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// class
|
// class
|
||||||
const getClass = (val: boolean) => {
|
const getClass = (val: boolean) => {
|
||||||
|
|
@ -129,6 +203,12 @@ const getClass = (val: boolean) => {
|
||||||
'bg-red-9 text-white col-12 row items-center q-px-md q-py-sm': !val,
|
'bg-red-9 text-white col-12 row items-center q-px-md q-py-sm': !val,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** Hook*/
|
||||||
|
onMounted(async() => {
|
||||||
|
await fetchCheckTime()
|
||||||
|
|
||||||
|
updateClock()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -192,7 +272,7 @@ const getClass = (val: boolean) => {
|
||||||
|
|
||||||
<div class="col-xs-12 col-md-11 row q-col-gutter-md">
|
<div class="col-xs-12 col-md-11 row q-col-gutter-md">
|
||||||
<div class="col-12 col-sm-8">
|
<div class="col-12 col-sm-8">
|
||||||
<MapCheck />
|
<MapCheck @update:location="updateLocation" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-sm-4">
|
<div class="col-12 col-sm-4">
|
||||||
<q-card flat bordered class="card-container">
|
<q-card flat bordered class="card-container">
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue