openStreetMap
This commit is contained in:
parent
70b40cf36c
commit
23e44b01bd
4 changed files with 307 additions and 141 deletions
115
package.json
115
package.json
|
|
@ -3,63 +3,68 @@
|
|||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p build-only",
|
||||
"preview": "vite preview",
|
||||
"test:unit": "vitest --environment jsdom --root src/",
|
||||
"test:e2e": "start-server-and-test preview :4173 'cypress run --e2e'",
|
||||
"test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||
"dev": "vite",
|
||||
"build": "run-p build-only",
|
||||
"preview": "vite preview",
|
||||
"test:unit": "vitest --environment jsdom --root src/",
|
||||
"test:e2e": "start-server-and-test preview :4173 'cypress run --e2e'",
|
||||
"test:e2e:dev": "start-server-and-test 'vite dev --port 4173' :4173 'cypress open --e2e'",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.vitest.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fullcalendar/core": "^6.0.1",
|
||||
"@fullcalendar/daygrid": "^6.0.1",
|
||||
"@fullcalendar/interaction": "^6.0.2",
|
||||
"@fullcalendar/list": "^6.0.2",
|
||||
"@fullcalendar/react": "^6.0.1",
|
||||
"@fullcalendar/timegrid": "^6.0.2",
|
||||
"@fullcalendar/vue3": "^6.0.1",
|
||||
"@quasar/extras": "^1.15.8",
|
||||
"@tato30/vue-pdf": "^1.5.1",
|
||||
"@vuepic/vue-datepicker": "^3.6.3",
|
||||
"bma-org-chart": "^0.0.7",
|
||||
"keycloak-js": "^20.0.2",
|
||||
"moment": "^2.29.4",
|
||||
"pinia": "^2.0.29",
|
||||
"quasar": "^2.11.1",
|
||||
"structure-chart": "^0.0.9",
|
||||
"vue": "^3.2.45",
|
||||
"vue-router": "^4.1.6",
|
||||
"vue3-datepicker": "^0.3.4",
|
||||
"vue3-pdfjs": "^0.1.6"
|
||||
"@fullcalendar/core": "^6.0.1",
|
||||
"@fullcalendar/daygrid": "^6.0.1",
|
||||
"@fullcalendar/interaction": "^6.0.2",
|
||||
"@fullcalendar/list": "^6.0.2",
|
||||
"@fullcalendar/react": "^6.0.1",
|
||||
"@fullcalendar/timegrid": "^6.0.2",
|
||||
"@fullcalendar/vue3": "^6.0.1",
|
||||
"@quasar/extras": "^1.15.8",
|
||||
"@tato30/vue-pdf": "^1.5.1",
|
||||
"@types/geojson": "^7946.0.10",
|
||||
"@vuepic/vue-datepicker": "^3.6.3",
|
||||
"bma-org-chart": "^0.0.7",
|
||||
"keycloak-js": "^20.0.2",
|
||||
"moment": "^2.29.4",
|
||||
"ol": "^7.5.2",
|
||||
"ol-contextmenu": "^5.2.1",
|
||||
"ol-ext": "^4.0.11",
|
||||
"pinia": "^2.0.29",
|
||||
"quasar": "^2.11.1",
|
||||
"structure-chart": "^0.0.9",
|
||||
"vue": "^3.2.45",
|
||||
"vue-router": "^4.1.6",
|
||||
"vue3-datepicker": "^0.3.4",
|
||||
"vue3-openlayers": "^1.2.2",
|
||||
"vue3-pdfjs": "^0.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@quasar/vite-plugin": "^1.3.0",
|
||||
"@rushstack/eslint-patch": "^1.1.4",
|
||||
"@types/jsdom": "^20.0.1",
|
||||
"@types/node": "^18.11.12",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/test-utils": "^2.2.6",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"cypress": "^12.0.2",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-vue": "^9.3.0",
|
||||
"jsdom": "^20.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"sass": "^1.32.12",
|
||||
"start-server-and-test": "^1.15.2",
|
||||
"typescript": "~4.7.4",
|
||||
"vite": "^4.0.0",
|
||||
"vitest": "^0.25.6",
|
||||
"vue-table-to-excel": "^1.0.6",
|
||||
"vue-tsc": "^1.0.12"
|
||||
"@quasar/vite-plugin": "^1.3.0",
|
||||
"@rushstack/eslint-patch": "^1.1.4",
|
||||
"@types/jsdom": "^20.0.1",
|
||||
"@types/leaflet": "^1.9.4",
|
||||
"@types/node": "^18.11.12",
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@vitejs/plugin-vue-jsx": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^7.0.0",
|
||||
"@vue/eslint-config-typescript": "^11.0.0",
|
||||
"@vue/test-utils": "^2.2.6",
|
||||
"@vue/tsconfig": "^0.1.3",
|
||||
"cypress": "^12.0.2",
|
||||
"eslint": "^8.22.0",
|
||||
"eslint-plugin-cypress": "^2.12.1",
|
||||
"eslint-plugin-vue": "^9.3.0",
|
||||
"jsdom": "^20.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.7.1",
|
||||
"sass": "^1.32.12",
|
||||
"start-server-and-test": "^1.15.2",
|
||||
"typescript": "~4.7.4",
|
||||
"vite": "^4.0.0",
|
||||
"vitest": "^0.25.6",
|
||||
"vue-table-to-excel": "^1.0.6",
|
||||
"vue-tsc": "^1.0.12"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import "@vuepic/vue-datepicker/dist/main.css"
|
|||
|
||||
import "quasar/src/css/index.sass"
|
||||
import http from "./plugins/http"
|
||||
import OpenLayersMap from "vue3-openlayers";
|
||||
|
||||
// import './assets/main.css'
|
||||
|
||||
|
|
@ -25,6 +26,7 @@ app.use(Quasar, {
|
|||
},
|
||||
lang: th,
|
||||
})
|
||||
app.use(OpenLayersMap /* options */);
|
||||
|
||||
app.component(
|
||||
"datepicker",
|
||||
|
|
|
|||
100
src/modules/04_checkin/componenst/mapCheck.vue
Normal file
100
src/modules/04_checkin/componenst/mapCheck.vue
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<template>
|
||||
<div>
|
||||
<div id="map"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted } from "vue";
|
||||
import Map from "ol/Map";
|
||||
import View from "ol/View";
|
||||
import { fromLonLat } from "ol/proj";
|
||||
import { Tile as TileLayer } from "ol/layer";
|
||||
import { OSM } from "ol/source";
|
||||
import Feature from "ol/Feature";
|
||||
import Point from "ol/geom/Point";
|
||||
import Circle from "ol/geom/Circle";
|
||||
import VectorLayer from "ol/layer/Vector";
|
||||
import VectorSource from "ol/source/Vector";
|
||||
import { Style, Icon, Fill, Stroke } from "ol/style";
|
||||
|
||||
onMounted(() => {
|
||||
const map = new Map({
|
||||
target: "map",
|
||||
layers: [
|
||||
new TileLayer({
|
||||
source: new OSM(),
|
||||
}),
|
||||
],
|
||||
view: new View({
|
||||
center: fromLonLat([98.981716, 18.7883]),
|
||||
zoom: 12,
|
||||
}),
|
||||
});
|
||||
|
||||
if ("geolocation" in navigator) {
|
||||
navigator.geolocation.getCurrentPosition((position) => {
|
||||
console.log(position);
|
||||
const lon = position.coords.longitude;
|
||||
const lat = position.coords.latitude;
|
||||
const coordinates = fromLonLat([lon, lat]);
|
||||
|
||||
currentLocationFeature.setGeometry(new Point(coordinates));
|
||||
map.getView().setCenter(coordinates);
|
||||
});
|
||||
}
|
||||
|
||||
// สร้าง feature สำหรับตำแหน่งปัจจุบัน
|
||||
const currentLocationFeature = new Feature({
|
||||
geometry: new Point(fromLonLat([98.981716, 18.7883])),
|
||||
});
|
||||
|
||||
currentLocationFeature.setStyle(
|
||||
new Style({
|
||||
image: new Icon({
|
||||
src: "https://assets.untappd.com/site/beer_logos_hd/beer-4817317_108bb_hd.jpeg",
|
||||
scale: 0.02,
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
const currentLocationLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [currentLocationFeature],
|
||||
}),
|
||||
});
|
||||
|
||||
map.addLayer(currentLocationLayer);
|
||||
|
||||
// สร้างวงรอบ
|
||||
const circleFeature = new Feature({
|
||||
geometry: new Circle(fromLonLat([98.981716, 18.7883]), 1000),
|
||||
});
|
||||
|
||||
circleFeature.setStyle(
|
||||
new Style({
|
||||
fill: new Fill({
|
||||
color: "rgba(2, 169, 152, 0.2)",
|
||||
}),
|
||||
stroke: new Stroke({
|
||||
color: "rgb(2, 169, 152)",
|
||||
width: 2,
|
||||
}),
|
||||
})
|
||||
);
|
||||
const circleLayer = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
features: [circleFeature],
|
||||
}),
|
||||
});
|
||||
|
||||
map.addLayer(circleLayer);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,83 +1,138 @@
|
|||
<template>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-11">
|
||||
<div class="toptitle text-white col-12 row items-center">
|
||||
<q-btn
|
||||
icon="mdi-arrow-left"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
flat
|
||||
color="primary"
|
||||
class="q-mr-sm"
|
||||
@click="router.go(-1)"
|
||||
/>
|
||||
เช็คอิน
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-card bordered class="q-pa-md">
|
||||
<div class="col-12 row justify-center q-pb-sm">
|
||||
<div class="col-xs-12 col-sm-10 text-h6 text-primary text-center text-weight-bold">เวลาในขณะนี้</div>
|
||||
<div class="row col-12 justify-center q-py-md">
|
||||
<div class="colunm">
|
||||
<div class="text-h2 text-weight-bold">{{ formattedH }}<span class="q-ma-md">:</span></div>
|
||||
<div>ชั่วโมง</div>
|
||||
</div>
|
||||
<div class="colunm">
|
||||
<div class="text-h2 text-weight-bold">{{ formattedM }}<span class="q-ma-md">:</span></div>
|
||||
<div>นาที</div>
|
||||
</div>
|
||||
<div class="colunm">
|
||||
<div class="text-h2 text-weight-bold">{{ formattedS }} </div>
|
||||
<div>วินาที</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="col-12 text-center text-weight-medium items-center text-dark q-pt-md"><q-icon color="primary" name="mdi-calendar-outline" class="q-mr-sm"/>วันที่ {{dateNow}}</div> -->
|
||||
<div class="col-12 row q-col-gutter-md">
|
||||
<div class="col-12 col-sm-8">
|
||||
<q-card bordered flat class="col-12 bg-grey-3">
|
||||
<q-img src="@/assets/map1.png" :style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"> </q-img>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<q-card flat class="col-12 bg-grey-3 items-center row" :style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'">
|
||||
<div class="column col-12" v-if="!camera">
|
||||
<div class="text-center"><q-icon name="mdi-image-off-outline" size="100px" color="grey-7" /></div>
|
||||
<div class="text-center q-pt-md text-grey-7">ไม่มีรูปภาพ</div>
|
||||
</div>
|
||||
<q-img v-else src="@/assets/camera.jpg" :style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"> </q-img>
|
||||
<div class="absolute-bottom-right q-ma-md">
|
||||
<q-btn round push icon="mdi-camera" size="md" color="positive" @click="photo()" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-right q-pt-md" v-if="camera">
|
||||
<q-btn label="ยืนยันเวลาเข้างาน" color="blue" push size="16px" :class="$q.screen.gt.xs ? 'q-px-md' : 'full-width'" @click="confirm" />
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-dialog v-model="dialogTime">
|
||||
<q-card class="q-px-lg full-width">
|
||||
<q-card-section>
|
||||
<div class="text-h6 text-center q-pt-md">เวลาเข้างานของคุณคือ</div>
|
||||
</q-card-section>
|
||||
<q-card-section style="max-height: 50vh">
|
||||
<div class="row col-12 justify-center q-pb-md">
|
||||
<div class="text-h2 text-weight-bold">{{ formattedH }}<span class="q-ma-md">:</span></div>
|
||||
<div class="text-h2 text-weight-bold">{{ formattedM }}</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-11">
|
||||
<div class="toptitle text-white col-12 row items-center">
|
||||
<q-btn
|
||||
icon="mdi-arrow-left"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
flat
|
||||
color="primary"
|
||||
class="q-mr-sm"
|
||||
@click="router.go(-1)"
|
||||
/>
|
||||
เช็คอิน
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-card bordered class="q-pa-md">
|
||||
<div class="col-12 row justify-center q-pb-sm">
|
||||
<div
|
||||
class="col-xs-12 col-sm-10 text-h6 text-primary text-center text-weight-bold"
|
||||
>
|
||||
เวลาในขณะนี้
|
||||
</div>
|
||||
<div class="row col-12 justify-center q-py-md">
|
||||
<div class="colunm">
|
||||
<div class="text-h2 text-weight-bold">
|
||||
{{ formattedH }}<span class="q-ma-md">:</span>
|
||||
</div>
|
||||
<div>ชั่วโมง</div>
|
||||
</div>
|
||||
<div class="colunm">
|
||||
<div class="text-h2 text-weight-bold">
|
||||
{{ formattedM }}<span class="q-ma-md">:</span>
|
||||
</div>
|
||||
<div>นาที</div>
|
||||
</div>
|
||||
<div class="colunm">
|
||||
<div class="text-h2 text-weight-bold">{{ formattedS }}</div>
|
||||
<div>วินาที</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="col-12 text-center text-weight-medium items-center text-dark q-pt-md"><q-icon color="primary" name="mdi-calendar-outline" class="q-mr-sm"/>วันที่ {{dateNow}}</div> -->
|
||||
<div class="col-12 row q-col-gutter-md">
|
||||
<div class="col-12 col-sm-8">
|
||||
<q-card
|
||||
bordered
|
||||
flat
|
||||
class="col-12 bg-grey-3"
|
||||
:style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"
|
||||
>
|
||||
<!-- <mapCheckin /> -->
|
||||
<q-img
|
||||
src="@/assets/map1.png"
|
||||
:style="
|
||||
$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'
|
||||
"
|
||||
>
|
||||
</q-img>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<q-card
|
||||
flat
|
||||
class="col-12 bg-grey-3 items-center row"
|
||||
:style="$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'"
|
||||
>
|
||||
<div class="column col-12" v-if="!camera">
|
||||
<div class="text-center">
|
||||
<q-icon
|
||||
name="mdi-image-off-outline"
|
||||
size="100px"
|
||||
color="grey-7"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-center q-pt-md text-grey-7">
|
||||
ไม่มีรูปภาพ
|
||||
</div>
|
||||
</div>
|
||||
<q-img
|
||||
v-else
|
||||
src="@/assets/camera.jpg"
|
||||
:style="
|
||||
$q.screen.gt.xs ? 'height: 400px;' : 'height: 220px;'
|
||||
"
|
||||
>
|
||||
</q-img>
|
||||
<div class="absolute-bottom-right q-ma-md">
|
||||
<q-btn
|
||||
round
|
||||
push
|
||||
icon="mdi-camera"
|
||||
size="md"
|
||||
color="positive"
|
||||
@click="photo()"
|
||||
/>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-right q-pt-md" v-if="camera">
|
||||
<q-btn
|
||||
label="ยืนยันเวลาเข้างาน"
|
||||
color="blue"
|
||||
push
|
||||
size="16px"
|
||||
:class="$q.screen.gt.xs ? 'q-px-md' : 'full-width'"
|
||||
@click="confirm"
|
||||
/>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-card-actions align="center" class="q-mb-md">
|
||||
<q-btn push label="ตกลง" color="primary" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
<q-dialog v-model="dialogTime">
|
||||
<q-card class="q-px-lg full-width">
|
||||
<q-card-section>
|
||||
<div class="text-h6 text-center q-pt-md">เวลาเข้างานของคุณคือ</div>
|
||||
</q-card-section>
|
||||
<q-card-section style="max-height: 50vh">
|
||||
<div class="row col-12 justify-center q-pb-md">
|
||||
<div class="text-h2 text-weight-bold">
|
||||
{{ formattedH }}<span class="q-ma-md">:</span>
|
||||
</div>
|
||||
<div class="text-h2 text-weight-bold">{{ formattedM }}</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="center" class="q-mb-md">
|
||||
<q-btn push label="ตกลง" color="primary" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
|
@ -85,7 +140,8 @@ import type { QTableProps } from "quasar";
|
|||
import { ref, onMounted } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { useRouter } from "vue-router";
|
||||
import moment, { Moment } from 'moment'
|
||||
import moment, { Moment } from "moment";
|
||||
// import mapCheckin from "../componenst/mapCheck.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const $q = useQuasar();
|
||||
|
|
@ -97,16 +153,19 @@ const map = ref(null);
|
|||
const camera = ref(false);
|
||||
const dialogTime = ref(false);
|
||||
|
||||
const photo = () => { camera.value = true };
|
||||
const confirm = () => { dialogTime.value = true };
|
||||
const photo = () => {
|
||||
camera.value = true;
|
||||
};
|
||||
const confirm = () => {
|
||||
dialogTime.value = true;
|
||||
};
|
||||
|
||||
var date = Date.now()
|
||||
let formattedH = (moment(date)).format('HH')
|
||||
let formattedM = (moment(date)).format('mm')
|
||||
let formattedS = (moment(date)).format('ss')
|
||||
var date = Date.now();
|
||||
let formattedH = moment(date).format("HH");
|
||||
let formattedM = moment(date).format("mm");
|
||||
let formattedS = moment(date).format("ss");
|
||||
|
||||
const time = new Date().toLocaleTimeString();
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue