remove checkin out of project & Refactoring code module 01_dashboard
This commit is contained in:
parent
ec80361a81
commit
75c0e27880
9 changed files with 105 additions and 1069 deletions
34
src/modules/01_dashboard/interface/Main.ts
Normal file
34
src/modules/01_dashboard/interface/Main.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
interface InboxList {
|
||||
id: string;
|
||||
subject: string;
|
||||
body: string;
|
||||
receiverUserId: string;
|
||||
payload: Object | null;
|
||||
isOpen: boolean;
|
||||
receiveDate: Date | null;
|
||||
openDate: Date | null;
|
||||
createdFullName?: string;
|
||||
createdAt?: Date;
|
||||
}
|
||||
|
||||
interface InboxDetail {
|
||||
no: string;
|
||||
sender: string;
|
||||
subject: string;
|
||||
body: string;
|
||||
ratingModel: number;
|
||||
receiveDate?: string;
|
||||
payload: Object | null;
|
||||
isOpen: boolean;
|
||||
}
|
||||
|
||||
interface MenuMainList {
|
||||
icon: string;
|
||||
title: string;
|
||||
sub: string;
|
||||
color: string;
|
||||
path: string;
|
||||
active: boolean;
|
||||
}
|
||||
|
||||
export type { InboxList, InboxDetail, MenuMainList };
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, Static } from "vue";
|
||||
const link = ref<number>(1);
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import router from "@/router";
|
||||
import http from "@/plugins/http";
|
||||
|
|
@ -9,23 +8,21 @@ import { useCounterMixin } from "@/stores/mixin";
|
|||
import PopupReplyInbox from "@/components/PopupReplyInbox.vue";
|
||||
import PopupDetailInbox from "@/components/PopupDetailInbox.vue";
|
||||
import { tokenParsed } from "@/plugins/auth";
|
||||
import {
|
||||
InboxDetail,
|
||||
InboxList,
|
||||
MenuMainList,
|
||||
} from "@/modules/01_dashboard/interface/Main";
|
||||
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, date2Thai, messageError } = mixin;
|
||||
|
||||
const fullname = ref<string>("");
|
||||
const inboxList = ref<any>([
|
||||
// {
|
||||
// no: 1,
|
||||
// sender: "เจ้าหน้าที่ทะเบียนประวัติ",
|
||||
// subject: "ขอแก้ไขข้อมูลทะเบียนประวัติ",
|
||||
// timereceive: "13/12/2565",
|
||||
// body: "ขอแก้ไขข้อมูลทะเบียนประวัติ เรื่อง ชื่อ-นามสกุล",
|
||||
// ratingModel: 0,
|
||||
// },
|
||||
]);
|
||||
const items = ref<any>([
|
||||
const fullname = ref<string>(""); // ชื่อผู้ใช้
|
||||
const inboxList = ref<InboxDetail[]>([]); // รายการกล่องข้อความ
|
||||
const idInboxActive = ref<string>(); // Id ข้อความที่เลือก
|
||||
// รายการเมนูหลักของระบบ
|
||||
const items = ref<MenuMainList[]>([
|
||||
{
|
||||
icon: "mdi-account-group-outline",
|
||||
title: "แผนผังองค์กร",
|
||||
|
|
@ -74,14 +71,6 @@ const items = ref<any>([
|
|||
path: "/transfer",
|
||||
active: false,
|
||||
},
|
||||
/*{
|
||||
icon: "mdi-account-remove-outline",
|
||||
title: "ลาออก",
|
||||
sub: "ทำเรื่องลาออก",
|
||||
color: "orange-3",
|
||||
path: "/retire",
|
||||
active: false,
|
||||
},*/
|
||||
{
|
||||
icon: "mdi-scale-balance",
|
||||
title: "อุทธรณ์ร้องทุกข์",
|
||||
|
|
@ -114,44 +103,41 @@ const items = ref<any>([
|
|||
path: "/scholarship",
|
||||
active: false,
|
||||
},
|
||||
// {
|
||||
// icon: "mdi-school",
|
||||
// title: "ทดลองงาน",
|
||||
// sub: "รายการงานที่ได้รับมอบหมาย",
|
||||
// color: "teal-2",
|
||||
// path: "/probation",
|
||||
// active: false,
|
||||
// },
|
||||
]);
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchlistInbox(1);
|
||||
await fetchlistInbox(1); // ดึงข้อมูลกล่องข้อความ
|
||||
// ดึงข้อมูลผู้ใช้
|
||||
const user = await tokenParsed();
|
||||
if (user) {
|
||||
fullname.value = user.name;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* ฟังก์ชั่นดึงข้อมูลกล่องข้อความ
|
||||
* @param index หน้าที่โหลดข้อมูล
|
||||
*/
|
||||
const fetchlistInbox = async (index: number) => {
|
||||
index === 1 && showLoader();
|
||||
index != 0 &&
|
||||
(await http
|
||||
.get(config.API.msgInbox + `?page=${index}&pageSize=${10}`)
|
||||
.then((res) => {
|
||||
let data = res.data.result.data;
|
||||
let data: InboxList[] = res.data.result.data;
|
||||
totalInbox.value = res.data.result.total;
|
||||
let listItem: any = [];
|
||||
let listItem: InboxDetail[] = [];
|
||||
if (data && data.length > 0) {
|
||||
data.map((e: any) => {
|
||||
console.log(data);
|
||||
|
||||
data.map((e: InboxList) => {
|
||||
listItem.push({
|
||||
no: e.id ?? "",
|
||||
sender:
|
||||
e.createdFullName == "" || e.createdFullName == null
|
||||
? "เจ้าหน้าที่"
|
||||
: e.createdFullName,
|
||||
sender: !e.createdFullName ? "เจ้าหน้าที่" : e.createdFullName,
|
||||
subject: e.subject ?? "",
|
||||
timereceive: date2Thai(e.createdAt),
|
||||
body: e.body ?? "-",
|
||||
ratingModel: 0,
|
||||
receiveDate: e.receiveDate,
|
||||
receiveDate: date2Thai(e.receiveDate, false, true),
|
||||
payload: e.payload,
|
||||
isOpen: e.isOpen,
|
||||
});
|
||||
|
|
@ -159,44 +145,57 @@ const fetchlistInbox = async (index: number) => {
|
|||
inboxList.value.push(...listItem);
|
||||
}
|
||||
})
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// })
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
}));
|
||||
};
|
||||
|
||||
const transferToPage = (path?: string) => {
|
||||
/**
|
||||
* ฟังก์ชั่น redirect ไปหน้าระบบ
|
||||
* @param path ที่อยู่หน้า
|
||||
*/
|
||||
const goToPage = (path?: string) => {
|
||||
router.push(`${path}`);
|
||||
};
|
||||
|
||||
// Dialog Reply
|
||||
const modalReply = ref<boolean>(false);
|
||||
const contactNo = ref<string>();
|
||||
const modalReply = ref<boolean>(false); // เปิด/ปิด dialog ตอบกลับข้อความ/ส่งข้อความ
|
||||
const contactNo = ref<string>(); // id ข้อความที่ต้องการตอบกลับ
|
||||
/**
|
||||
* ฟังก์ชั่นเปิด dialog ตอบกลับข้อความ
|
||||
* @param id id ข้อความ
|
||||
*/
|
||||
function dialogRepleOpen(id: string) {
|
||||
contactNo.value = id;
|
||||
modalReply.value = true;
|
||||
contactNo.value = id; // กำหนด id ข้อความ
|
||||
modalReply.value = true; // เปิด dialog ตอบกลับข้อความ
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังก์ชั่นปิด dialog ตอบกลับข้อความ
|
||||
*/
|
||||
function modalReplyClose() {
|
||||
contactNo.value = "";
|
||||
modalReply.value = false;
|
||||
contactNo.value = ""; // ล้าง id ข้อความ
|
||||
modalReply.value = false; // ปิด dialog ตอบกลับข้อความ
|
||||
}
|
||||
|
||||
const dataInbox = ref<any>();
|
||||
const modalDetial = ref<boolean>(false);
|
||||
async function onClickOpenPopupDetail(data: any) {
|
||||
const dataInbox = ref<InboxDetail>(); // รายละเอียดข้อความ
|
||||
const modalDetial = ref<boolean>(false); // เปิด/ปิด dialog รายละเอียดข้อความ
|
||||
/**
|
||||
* ฟังก์ชั่นเปิด dialog รายละเอียดข้อความ
|
||||
* @param data รายละเอียดข้อความ
|
||||
*/
|
||||
async function onClickOpenPopupDetail(data: InboxDetail) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.msgInboxRead(data.no))
|
||||
.then(() => {
|
||||
const filterDate = inboxList.value.filter((r: any) => r.no == data.no);
|
||||
const filterDate = inboxList.value.filter(
|
||||
(r: InboxDetail) => r.no == data.no
|
||||
);
|
||||
for (const item of filterDate) {
|
||||
item.isOpen = true;
|
||||
}
|
||||
dataInbox.value = data;
|
||||
link.value = data.no;
|
||||
idInboxActive.value = data.no;
|
||||
modalDetial.value = !modalDetial.value;
|
||||
})
|
||||
.catch((err) => {
|
||||
|
|
@ -207,13 +206,21 @@ async function onClickOpenPopupDetail(data: any) {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังก์ชั่นกำหนดรายละเอียดข้อความ ส่งไปยัง dialog
|
||||
*/
|
||||
function updateModalDetail(val: boolean) {
|
||||
modalDetial.value = val;
|
||||
modalDetial.value = val; // กำหนดรายละเอียดข้อความที่เลือก
|
||||
}
|
||||
|
||||
const scrollTargetRef = ref<any>(null);
|
||||
const totalInbox = ref<number>(0);
|
||||
async function onLoad(index: number, done: any) {
|
||||
const scrollTargetRef = ref<any>(null); // เช็คการ scroll ของกล่องข้อความ
|
||||
const totalInbox = ref<number>(0); // จำนวนข้อความทั้งหมด
|
||||
/**
|
||||
* ฟังก์ชั่นโหลดข้อมูลกล่องข้อความ
|
||||
* @param index หน้าที่โหลดข้อมูล
|
||||
* @param done ฟังก์ชั่นเมื่อโหลดข้อมูลเสร็จ
|
||||
*/
|
||||
async function onLoad(index: number, done: Function) {
|
||||
const num = index === 1 ? 0 : index++;
|
||||
if (inboxList.value.length < totalInbox.value) {
|
||||
setTimeout(() => {
|
||||
|
|
@ -222,10 +229,6 @@ async function onLoad(index: number, done: any) {
|
|||
}, 3000);
|
||||
}
|
||||
}
|
||||
const thaiOptions: Intl.DateTimeFormatOptions = {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -245,11 +248,7 @@ const thaiOptions: Intl.DateTimeFormatOptions = {
|
|||
v-for="(item, j) in items"
|
||||
:key="j"
|
||||
>
|
||||
<q-card
|
||||
bordered
|
||||
@click="transferToPage(item.path)"
|
||||
class="noactive col-12"
|
||||
>
|
||||
<q-card bordered @click="goToPage(item.path)" class="noactive col-12">
|
||||
<div class="col-12">
|
||||
<q-avatar
|
||||
:color="item.color"
|
||||
|
|
@ -312,20 +311,14 @@ const thaiOptions: Intl.DateTimeFormatOptions = {
|
|||
clickable
|
||||
v-ripple
|
||||
class="'q-py-md q-mb-sm my-menu'"
|
||||
:active="link === item.no"
|
||||
:active="idInboxActive === item.no"
|
||||
active-class="my-menu-link"
|
||||
@click.stop.prevent="onClickOpenPopupDetail(item)"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label caption class="text-weight-light">
|
||||
{{ date2Thai(item.receiveDate) }}
|
||||
{{
|
||||
new Date(item.receiveDate).toLocaleTimeString(
|
||||
"th-TH",
|
||||
thaiOptions
|
||||
)
|
||||
}}
|
||||
น. <q-space />
|
||||
{{ item.receiveDate }}
|
||||
<q-space />
|
||||
</q-item-label>
|
||||
<q-item-label
|
||||
:class="!item.isOpen ? 'text-weight-medium' : 'text-grey-7'"
|
||||
|
|
@ -345,10 +338,6 @@ const thaiOptions: Intl.DateTimeFormatOptions = {
|
|||
>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section side top>
|
||||
<q-item-label caption>{{ item.timereceive }}</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section side top>
|
||||
<q-btn
|
||||
flat
|
||||
|
|
@ -375,54 +364,6 @@ const thaiOptions: Intl.DateTimeFormatOptions = {
|
|||
</q-infinite-scroll>
|
||||
</div>
|
||||
|
||||
<!-- <q-scroll-area style="height: 64vh" v-if="inboxList.length > 0">
|
||||
<q-list
|
||||
v-for="(contact, index) in inboxList"
|
||||
:key="index"
|
||||
class="q-px-md"
|
||||
>
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
class="q-py-md q-mb-sm my-menu"
|
||||
:active="link === contact.no"
|
||||
active-class="my-menu-link"
|
||||
@click="onClickOpenPopupDetail(contact)"
|
||||
>
|
||||
<q-item-section>
|
||||
<q-item-label>
|
||||
{{ contact.sender }}
|
||||
<q-icon
|
||||
v-if="contact.payload"
|
||||
name="mdi-paperclip"
|
||||
color="grey-6"
|
||||
size="18px"
|
||||
/></q-item-label>
|
||||
<q-item-label caption class="text-grey-6" lines="2">{{
|
||||
contact.subject
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section side top>
|
||||
<q-item-label caption>{{ contact.timereceive }}</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section side top>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="mdi-reply"
|
||||
size="10px"
|
||||
color="grey-7"
|
||||
@click="dialogRepleOpen(contact.no)"
|
||||
>
|
||||
<q-tooltip>ตอบกลับข้อความ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-scroll-area> -->
|
||||
<q-banner rounded class="bg-amber-1 text-center q-mx-sm" v-else>
|
||||
<div class="text-yellow-10">
|
||||
<q-icon
|
||||
|
|
|
|||
|
|
@ -1,61 +0,0 @@
|
|||
<script setup lang="ts">
|
||||
import Child from "@/components/TestUpgrade.vue";
|
||||
import { ref, computed, watchEffect } from "vue";
|
||||
|
||||
const count = ref<number>(0);
|
||||
const total = ref<number>(0);
|
||||
const first = ref<string>("firstName");
|
||||
const last = ref<string>("lastName");
|
||||
|
||||
const isEven = computed(() => count.value % 2 === 0);
|
||||
|
||||
// watchEffect(() => isEven.value && submit()); // logs true
|
||||
|
||||
const inputValue = ref<string>("");
|
||||
function submit() {
|
||||
console.log("test");
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-card class="q-pa-md">
|
||||
<!-- Parent.vue -->
|
||||
<div class="q-mb-md">
|
||||
<div>Parent count is: {{ count }}</div>
|
||||
<q-btn @click="count = 0">Reset count</q-btn>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<div class="q-mb-md">
|
||||
<Child
|
||||
v-model="count"
|
||||
v-model:total="total"
|
||||
v-model:firstname.lastNameModifiers="first"
|
||||
v-model:lastname.uppercase="last"
|
||||
:name2="inputValue"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- <div class="q-mb-md">
|
||||
<q-btn @click="refs.update">count ++</q-btn>
|
||||
</div> -->
|
||||
</q-card>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card class="q-pa-md">
|
||||
<!-- Parent.vue -->
|
||||
<div class="q-mb-md q-gutter-sm">
|
||||
<div><h4>Test Vue</h4></div>
|
||||
<div>
|
||||
<q-input outlined dense type="text" v-model="inputValue"></q-input>
|
||||
</div>
|
||||
<q-btn @click="submit">submit</q-btn>
|
||||
</div>
|
||||
|
||||
<!-- <div class="q-mb-md">
|
||||
<Child :name="first" />
|
||||
</div> -->
|
||||
</q-card>
|
||||
</template>
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
<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,161 +0,0 @@
|
|||
<template>
|
||||
<div class="q-pb-sm row">
|
||||
<div class="items-center col-12 row q-gutter-sm">
|
||||
<!-- ค้นหาข้อความใน table -->
|
||||
<datepicker menu-class-name="modalfix" v-model="yearly" :locale="'th'" autoApply year-picker :enableTimePicker="false">
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{ parseInt(value + 543) }}</template>
|
||||
<template #trigger>
|
||||
<q-input hide-bottom-space outlined dense lazy-rules :model-value="yearly + 543" :rules="[val => !!val || `${'กรุณาเลือกปีพ.ศ.'}`]" :label="`${'ปีพ.ศ.'}`" style="width: 150px">
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="event" class="cursor-pointer" color="primary"> </q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
<q-space />
|
||||
<q-input standout dense :model-value="inputfilter" ref="filterRef" @update:model-value="updateInput" outlined debounce="300" placeholder="ค้นหา" class="gt-xs" style="max-width: 200px">
|
||||
<template v-slot:append>
|
||||
<q-icon v-if="inputfilter == ''" name="search" />
|
||||
<q-icon v-if="inputfilter !== ''" name="clear" class="cursor-pointer" @click="resetFilter" />
|
||||
</template>
|
||||
</q-input>
|
||||
<!-- แสดงคอลัมน์ใน table -->
|
||||
<q-select
|
||||
:model-value="inputvisible"
|
||||
@update:model-value="updateVisible"
|
||||
:display-value="$q.lang.table.columns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
:options="attrs.columns"
|
||||
options-dense
|
||||
option-value="name"
|
||||
map-options
|
||||
emit-value
|
||||
style="min-width: 150px"
|
||||
class="gt-xs"
|
||||
>
|
||||
<template> </template>
|
||||
</q-select>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<q-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
class="custom-table2"
|
||||
v-bind="attrs"
|
||||
virtual-scroll
|
||||
:virtual-scroll-sticky-size-start="48"
|
||||
dense
|
||||
:pagination-label="paginationLabel"
|
||||
:pagination="initialPagination"
|
||||
:rows-per-page-options="[0]"
|
||||
:grid="grid"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<span class="text-weight-medium" v-html="col.label" />
|
||||
</q-th>
|
||||
<q-th auto-width v-if="inputShow" />
|
||||
</q-tr>
|
||||
</template>
|
||||
<template #body="props">
|
||||
<slot v-bind="props" name="columns"></slot>
|
||||
</template>
|
||||
<template #item="props">
|
||||
<slot v-bind="props" name="item"></slot>
|
||||
</template>
|
||||
</q-table>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref, useAttrs } from "vue"
|
||||
const attrs = ref<any>(useAttrs())
|
||||
const table = ref<any>(null)
|
||||
const filterRef = ref<any>(null)
|
||||
const initialPagination = ref({
|
||||
rowsPerPage: 0,
|
||||
})
|
||||
const yearly = ref<number>(new Date().getFullYear())
|
||||
|
||||
const props = defineProps({
|
||||
count: Number,
|
||||
pass: Number,
|
||||
notpass: Number,
|
||||
|
||||
inputfilter: String,
|
||||
name: String,
|
||||
icon: String,
|
||||
inputvisible: Array,
|
||||
editvisible: Boolean,
|
||||
grid: Boolean,
|
||||
|
||||
inputShow: Boolean,
|
||||
})
|
||||
|
||||
const emit = defineEmits(["update:inputfilter", "update:inputvisible", "update:editvisible"])
|
||||
const updateInput = (value: string | number | null) => {
|
||||
emit("update:inputfilter", value)
|
||||
}
|
||||
const updateVisible = (value: []) => {
|
||||
emit("update:inputvisible", value)
|
||||
}
|
||||
|
||||
const paginationLabel = (start: string, end: string, total: string) => {
|
||||
return start + "-" + end + " ใน " + total
|
||||
}
|
||||
|
||||
const resetFilter = () => {
|
||||
// reset ค่าที่ค้นหาเมื่อกดปุ่ม X ในกล่องค้นหา
|
||||
emit("update:inputfilter", "")
|
||||
filterRef.value.focus()
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.icon-color {
|
||||
color: #4154b3;
|
||||
}
|
||||
|
||||
.custom-table2 {
|
||||
.q-table tr:nth-child(odd) td {
|
||||
background: white;
|
||||
}
|
||||
|
||||
.q-table tr:nth-child(even) td {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.q-table thead tr {
|
||||
background: #ecebeb;
|
||||
}
|
||||
|
||||
.q-table thead tr th {
|
||||
position: sticky;
|
||||
}
|
||||
|
||||
.q-table td:nth-of-type(2) {
|
||||
z-index: 3 !important;
|
||||
}
|
||||
|
||||
.q-table th:nth-of-type(2),
|
||||
.q-table td:nth-of-type(2) {
|
||||
position: sticky;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* this will be the loading indicator */
|
||||
.q-table thead tr:last-child th {
|
||||
/* height of all previous header rows */
|
||||
top: 48px;
|
||||
}
|
||||
|
||||
.q-table thead tr:first-child th {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/**
|
||||
* Router Checkin
|
||||
*/
|
||||
|
||||
const Checkin = () => import("@/modules/04_checkin/views/Checkin.vue")
|
||||
const History = () => import("@/modules/04_checkin/views/history.vue")
|
||||
|
||||
/* const Checkout = () => import("@/modules/04_checkin/views/Checkout.vue");
|
||||
*/
|
||||
export default [
|
||||
{
|
||||
path: "/check-in",
|
||||
name: "Checkin",
|
||||
component: Checkin,
|
||||
meta: {
|
||||
Auth: true,
|
||||
Key: [7],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "/check-in/history",
|
||||
name: "History",
|
||||
component: History,
|
||||
meta: {
|
||||
Auth: true,
|
||||
Key: [7],
|
||||
},
|
||||
},
|
||||
/* {
|
||||
path: "/check-out",
|
||||
name: "Checkout",
|
||||
component: Checkout,
|
||||
meta: {
|
||||
Auth: true,
|
||||
Key: [7],
|
||||
},
|
||||
}, */
|
||||
]
|
||||
|
|
@ -1,417 +0,0 @@
|
|||
<template>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-11">
|
||||
<q-card flat class="row col-12 cardNone">
|
||||
<div :class="getClass(checkIn)">
|
||||
<div class="col-2">
|
||||
<q-btn
|
||||
icon="mdi-arrow-left"
|
||||
unelevated
|
||||
round
|
||||
dense
|
||||
flat
|
||||
color="white"
|
||||
@click="router.go(-1)"
|
||||
/>
|
||||
</div>
|
||||
<span class="text-body1 text-weight-bold col-8 text-center">
|
||||
<span v-if="checkIn">ลงเวลาเข้างาน</span>
|
||||
<span v-else>ลงเวลาออกงาน</span>
|
||||
</span>
|
||||
<div class="col-2 text-right">
|
||||
<q-btn
|
||||
icon="mdi-history"
|
||||
unelevated
|
||||
rounded
|
||||
dense
|
||||
flat
|
||||
color="white"
|
||||
:label="$q.screen.gt.xs ? 'ประวัติการลงเวลา' : ''"
|
||||
:class="$q.screen.gt.xs ? 'q-px-sm' : ''"
|
||||
@click="router.push('/check-in/history')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 q-pa-md text-grey-9">
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-12 row q-py-sm justify-center">
|
||||
<div
|
||||
class="col-xs-12 col-sm-10 text-h6 text-center text-weight-bold"
|
||||
>
|
||||
{{ Thai }}
|
||||
</div>
|
||||
<div class="row col-12 justify-center q-py-sm">
|
||||
<div class="colunm">
|
||||
<div class="text-h3 text-weight-bold">
|
||||
{{ formattedH }}<span class="q-ma-md">:</span>
|
||||
</div>
|
||||
<!-- <div>ชั่วโมง</div> -->
|
||||
</div>
|
||||
<div class="colunm">
|
||||
<div class="text-h3 text-weight-bold">
|
||||
{{ formattedM }}<span class="q-ma-md">:</span>
|
||||
</div>
|
||||
<!-- <div>นาที</div> -->
|
||||
</div>
|
||||
<div class="colunm">
|
||||
<div class="text-h3 text-weight-bold">{{ formattedS }}</div>
|
||||
<!-- <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-xs-12 col-md-11 row q-col-gutter-md">
|
||||
<div class="col-12 col-sm-8">
|
||||
<q-card
|
||||
bordered
|
||||
flat
|
||||
class="col-12 bg-grey-2 shadow-0"
|
||||
:style="$q.screen.gt.xs ? 'height: 350px;' : 'height: 220px;'"
|
||||
>
|
||||
<!-- <mapCheckin /> -->
|
||||
<q-img
|
||||
src="@/assets/map1.png"
|
||||
:style="
|
||||
$q.screen.gt.xs ? 'height: 350px;' : 'height: 168px;'
|
||||
"
|
||||
></q-img>
|
||||
<div class="q-pa-md text-weight-medium text-grey-8">
|
||||
พื้นที่ใกล้เคียง
|
||||
<span class="q-px-sm">:</span>
|
||||
{{ location }}
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="col-12 col-sm-4">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
class="cardImg col-12 bg-grey-2 items-center row cursor-pointer shadow-0"
|
||||
@click="photo()"
|
||||
:style="$q.screen.gt.xs ? 'height: 350px;' : 'height: 220px;'"
|
||||
>
|
||||
<div class="column col-12" v-if="!camera">
|
||||
<div class="text-center">
|
||||
<q-icon
|
||||
name="mdi-camera"
|
||||
size="100px"
|
||||
color="blue-grey-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="hasPhoto">
|
||||
<video
|
||||
ref="video"
|
||||
autoplay
|
||||
:style="
|
||||
$q.screen.gt.xs
|
||||
? 'width: 375px; height: 350px;'
|
||||
: 'width: 245px; height: 220px;'
|
||||
"
|
||||
></video>
|
||||
<canvas
|
||||
ref="canvas"
|
||||
:style="
|
||||
$q.screen.gt.xs
|
||||
? 'width: 375px; height: 350px;'
|
||||
: 'width: 252px; height: 190px;'
|
||||
"
|
||||
></canvas>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<q-img
|
||||
:src="img"
|
||||
:style="
|
||||
$q.screen.gt.xs
|
||||
? 'width: 375px; height: 350px; border-radius: 5px;'
|
||||
: 'width: 245px; height: 218px; border-radius: 5px;'
|
||||
"
|
||||
></q-img>
|
||||
<canvas ref="canvas"></canvas>
|
||||
</div>
|
||||
|
||||
<div class="absolute-bottom-right q-ma-md">
|
||||
<q-btn
|
||||
round
|
||||
push
|
||||
icon="mdi-camera"
|
||||
size="md"
|
||||
color="positive"
|
||||
@click="capturePhoto"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="col-12 q-mb-md">
|
||||
<q-card
|
||||
bordered
|
||||
flat
|
||||
:class="
|
||||
$q.screen.gt.xs
|
||||
? 'q-px-md q-py-sm row items-center shadow-0'
|
||||
: 'q-pa-md row items-center shadow-0'
|
||||
"
|
||||
>
|
||||
<div class="text-weight-bold">สถานที่ทำงาน</div>
|
||||
<div
|
||||
:class="
|
||||
$q.screen.gt.xs
|
||||
? 'row q-gutter-md q-pl-md col-sm-6 col-md-3'
|
||||
: 'column col-12'
|
||||
"
|
||||
>
|
||||
<q-radio
|
||||
v-model="workplace"
|
||||
checked-icon="task_alt"
|
||||
unchecked-icon="panorama_fish_eye"
|
||||
val="in-place"
|
||||
label="ในสถานที่"
|
||||
/>
|
||||
<q-radio
|
||||
v-model="workplace"
|
||||
checked-icon="task_alt"
|
||||
unchecked-icon="panorama_fish_eye"
|
||||
val="off-site"
|
||||
label="นอกสถานที่"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-4">
|
||||
<q-select
|
||||
v-if="workplace == 'off-site'"
|
||||
dense
|
||||
class="q-ml-md"
|
||||
outlined
|
||||
v-model="model"
|
||||
:options="options"
|
||||
prefix="ระบุสถานที่ :"
|
||||
/>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-right" v-if="camera">
|
||||
<div class="col-12">
|
||||
<q-separator />
|
||||
</div>
|
||||
<div class="col-12 q-pa-md">
|
||||
<q-btn
|
||||
:label="checkIn == true ? 'ลงเวลาเข้างาน' : 'ลงเวลาออกงาน'"
|
||||
:color="checkIn == true ? 'primary' : 'red-9'"
|
||||
push
|
||||
size="14px"
|
||||
:class="$q.screen.gt.xs ? 'q-px-md' : 'full-width'"
|
||||
@click="confirm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-dialog v-model="dialogTime">
|
||||
<q-card class="full-width cardNone">
|
||||
<div :class="getClass(checkIn)">
|
||||
<div class="text-body1 text-center col-12 text-weight-bold">
|
||||
<span v-if="checkIn">ลงเวลาเข้างานของคุณ</span>
|
||||
<span v-else>ลงเวลาออกงานของคุณ</span>
|
||||
</div>
|
||||
</div>
|
||||
<q-card-section class="row col-12 justify-center">
|
||||
<div class="bg-grey-2 rounded-borders q-pa-md col-11">
|
||||
<div class="col-12 text-subtitle1 text-center text-weight-medium">
|
||||
{{ Thai }}
|
||||
</div>
|
||||
<div class="row col-12 justify-center q-pt-sm">
|
||||
<div class="text-h3 text-weight-bold">
|
||||
{{ formattedH }}<span class="q-ma-md">:</span>
|
||||
</div>
|
||||
<div class="text-h3 text-weight-bold">{{ formattedM }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 text-center row q-pt-md">
|
||||
<div class="col-12 text-subtitle1 text-weight-medium text-secondary">
|
||||
{{ location }}
|
||||
</div>
|
||||
<div class="col-12 text-grey-7">{{ coordinates }}</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-actions align="center" class="q-mb-md row">
|
||||
<q-btn
|
||||
class="col-xs-11 col-sm-6"
|
||||
push
|
||||
label="ตกลง"
|
||||
color="secondary"
|
||||
v-close-popup
|
||||
/>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { QTableProps } from "quasar";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { useRouter } from "vue-router";
|
||||
import moment from "moment";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
const mixin = useCounterMixin();
|
||||
const { dateThai } = mixin;
|
||||
// import mapCheckin from "../components/mapCheck.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const $q = useQuasar();
|
||||
const dateNow = ref(new Date());
|
||||
const Thai = ref(dateThai(dateNow.value));
|
||||
|
||||
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 checkIn = ref(true); //เช็คการเช็คอิน ถ้าลงเวลาครั้งแรกเป็นเช็คอิน(สีเขียว) true แต่ถ้าครั้ง 2 เป็นเช็คเอ้าท์(สีแดง) false
|
||||
|
||||
const camera = ref(false);
|
||||
const dialogTime = ref(false);
|
||||
|
||||
const photo = () => {
|
||||
camera.value = true;
|
||||
camera.value && setupCamera();
|
||||
};
|
||||
const confirm = () => {
|
||||
dialogTime.value = true;
|
||||
};
|
||||
const mediaStream = ref<MediaStream | null>(null);
|
||||
const video = ref<HTMLVideoElement | null>(null);
|
||||
const canvas = ref<HTMLCanvasElement | null>(null);
|
||||
const hasPhoto = ref<boolean>(true);
|
||||
const img = ref<any>();
|
||||
|
||||
function capturePhoto() {
|
||||
const videoElement = video.value;
|
||||
const canvasElement = canvas.value;
|
||||
if (!videoElement || !canvasElement) {
|
||||
console.error("Video or Canvas element not available");
|
||||
return;
|
||||
}
|
||||
const context = canvasElement.getContext("2d");
|
||||
if (!context) {
|
||||
console.error("Canvas context not available");
|
||||
return;
|
||||
}
|
||||
const desiredWidth = 189;
|
||||
const desiredHeight = 190;
|
||||
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 = "high";
|
||||
}
|
||||
|
||||
// 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;
|
||||
console.log(img.value);
|
||||
|
||||
if (mediaStream.value) {
|
||||
mediaStream.value.getTracks().forEach((track) => track.stop());
|
||||
videoElement.srcObject = null;
|
||||
hasPhoto.value = false;
|
||||
}
|
||||
}
|
||||
const setupCamera = async () => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
|
||||
if (video.value) {
|
||||
video.value.srcObject = stream;
|
||||
}
|
||||
mediaStream.value = stream;
|
||||
} catch (error) {
|
||||
console.error("Error accessing camera:", error);
|
||||
}
|
||||
};
|
||||
|
||||
// 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();
|
||||
const formattedS = ref();
|
||||
const formattedM = ref();
|
||||
const formattedH = ref();
|
||||
|
||||
onMounted(() => {
|
||||
updateClock();
|
||||
});
|
||||
|
||||
// อัพเดทเวลา
|
||||
function updateClock() {
|
||||
const date = Date.now();
|
||||
let hh = moment(date).format("HH");
|
||||
let mm = moment(date).format("mm");
|
||||
let ss = moment(date).format("ss");
|
||||
formattedS.value = ss;
|
||||
formattedM.value = mm;
|
||||
formattedH.value = hh;
|
||||
}
|
||||
setInterval(updateClock, 1000); // เรียกอัพเดททุกๆ 1 วิ
|
||||
|
||||
const getClass = (val: boolean) => {
|
||||
return {
|
||||
"bg-primary 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,
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.q-card.cardImg:hover {
|
||||
border: 1px solid #02a998 !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
<template>
|
||||
<div class="col-12 row justify-center">
|
||||
<div class="col-xs-12 col-sm-12 col-md-11">
|
||||
<q-card flat class="row col-12 cardNone">
|
||||
<div class="bg-secondary text-white col-12 row items-center q-px-md q-py-sm">
|
||||
<div class="col-2">
|
||||
<q-btn icon="mdi-arrow-left" unelevated round dense flat color="white" @click="router.go(-1)" />
|
||||
</div>
|
||||
<q-space />
|
||||
<span class="text-body1 text-weight-bold col-8 text-center">ประวัติการลงเวลา</span>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
<div class="col-12 q-pa-md text-grey-9">
|
||||
<Table
|
||||
:style="$q.screen.gt.xs ? 'max-height: 64vh' : ''"
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
:filter="filter"
|
||||
:visible-columns="visibleColumns"
|
||||
v-model:inputfilter="filter"
|
||||
v-model:inputvisible="visibleColumns"
|
||||
:pagination="initialPagination"
|
||||
:inputShow="false"
|
||||
:grid="$q.screen.gt.xs ? false : true"
|
||||
>
|
||||
<template #columns="props">
|
||||
<q-tr :props="props">
|
||||
<q-td key="no" :props="props">
|
||||
{{ props.rowIndex + 1 }}
|
||||
</q-td>
|
||||
<q-td key="date" :props="props">
|
||||
{{ props.row.date }}
|
||||
</q-td>
|
||||
<q-td key="in" :props="props">
|
||||
{{ props.row.in }}
|
||||
</q-td>
|
||||
<q-td key="loIn" :props="props">
|
||||
{{ props.row.loIn }}
|
||||
</q-td>
|
||||
<q-td key="out" :props="props">
|
||||
{{ props.row.out }}
|
||||
</q-td>
|
||||
<q-td key="loOut" :props="props">
|
||||
{{ props.row.loOut }}
|
||||
</q-td>
|
||||
<q-td key="status" :props="props">
|
||||
<span :class="props.row.status == 'ลงเวลาเรียบร้อย' ? 'text-blue' : 'text-orange'">{{ props.row.status }}</span>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template #item="props">
|
||||
<div class="q-pa-xs col-xs-12 col-sm-6 col-md-4 col-lg-3 grid-style-transition">
|
||||
<q-card bordered flat class="q-py-sm shadow-0">
|
||||
<q-list dense>
|
||||
<q-item v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{ col.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side>
|
||||
<q-item-label>
|
||||
<span v-if="col.name == 'status'" :class="props.row.status == 'ลงเวลาเรียบร้อย' ? 'text-blue' : 'text-orange'">{{ col.value }}</span>
|
||||
<span v-else class="text-black">{{ col.value }}</span>
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import type { QTableProps } from "quasar"
|
||||
import { ref } from "vue"
|
||||
import { useRouter } from "vue-router"
|
||||
import Table from "@/modules/04_checkin/components/tableHistory.vue"
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const filter = ref<string>("")
|
||||
const visibleColumns = ref<String[]>(["no", "date", "in", "loIn", "out", "loOut", "status"])
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "no",
|
||||
align: "left",
|
||||
label: "ลำดับ",
|
||||
sortable: true,
|
||||
field: "no",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width:5%;",
|
||||
},
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วัน/เดือน/ปี",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width:15%;",
|
||||
},
|
||||
{
|
||||
name: "in",
|
||||
align: "left",
|
||||
label: "เวลาเข้างาน",
|
||||
sortable: true,
|
||||
field: "in",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width:15%;",
|
||||
},
|
||||
{
|
||||
name: "loIn",
|
||||
align: "left",
|
||||
label: "พิกัด",
|
||||
sortable: true,
|
||||
field: "loIn",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "out",
|
||||
align: "left",
|
||||
label: "เวลาออกงาน",
|
||||
sortable: true,
|
||||
field: "out",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width:15%;",
|
||||
},
|
||||
{
|
||||
name: "loOut",
|
||||
align: "left",
|
||||
label: "พิกัด",
|
||||
sortable: true,
|
||||
field: "loOut",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
align: "left",
|
||||
label: "สถานะ",
|
||||
sortable: true,
|
||||
field: "status",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width:10%;",
|
||||
},
|
||||
])
|
||||
const rows = ref<any>([
|
||||
{ no: "1", date: "13/08/66", in: "11:20", loIn: "สำนักงาน ก.ก ", out: "", loOut: "", status: "" },
|
||||
{ no: "2", date: "12/08/66", in: "08:04", loIn: "สำนักงาน ก.ก ", out: "17:01", loOut: "สำนักงาน ก.ก ", status: "ลงเวลาเรียบร้อย" },
|
||||
{ no: "3", date: "11/08/66", in: "08:34", loIn: "สำนักงาน ก.ก ", out: "17:36", loOut: "สำนักงาน ก.ก ", status: "สาย ทำงานครบ" },
|
||||
{ no: "4", date: "10/08/66", in: "08:48", loIn: "สำนักงาน ก.ก ", out: "17:00", loOut: "สำนักงาน ก.ก ", status: "สาย ทำงานไม่ครบ" },
|
||||
])
|
||||
const initialPagination = ref({
|
||||
rowsPerPage: 0,
|
||||
})
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue