เพิ่มระบบเวลา กับ สถานะออนไลน์

This commit is contained in:
Net 2024-02-16 16:20:18 +07:00
parent ca0f98ba29
commit 289e655495
2 changed files with 68 additions and 34 deletions

View file

@ -12,8 +12,36 @@ const content = ref<string>("");
const searchInput = ref<string>(""); const searchInput = ref<string>("");
const currentIssuePage = ref<number>(1); const currentIssuePage = ref<number>(1);
const totalPageIssue = ref<number>(); const totalPageIssue = ref<number>();
const createdByUser = ref<string>("");
const { scrollContainer } = storeToRefs(store); const { scrollContainer } = storeToRefs(store);
function dateIssue(timestamp: string): string {
const parsedTimestamp = moment(timestamp);
const diff = moment().diff(parsedTimestamp);
if (diff < 1000) {
return "just now";
} else if (diff < 60000) {
return `${Math.floor(diff / 1000)}s`;
} else if (diff < 3600000) {
return `${Math.floor(diff / 60000)}m`;
} else if (diff < 86400000) {
return `${Math.floor(diff / 3600000)}h`;
} else {
const beYear = parsedTimestamp.year() + 543;
const formattedDate = parsedTimestamp.clone().year(beYear).format("DD MMM");
return formattedDate;
}
}
function getOnlineStatus(option: "icon" | "status", userId: string) {
const isOnline: boolean = store.userStatus.some((u) =>
u.userId.includes(userId)
);
if (option === "icon") return isOnline ? "green" : "grey";
if (option === "status") return isOnline ? "ออนไลน์" : "ออฟไลน์";
}
onMounted(async () => { onMounted(async () => {
await store.fetchIssue(); await store.fetchIssue();
totalPageIssue.value = Math.ceil((store.currentTotalIssue || 0) / 30); totalPageIssue.value = Math.ceil((store.currentTotalIssue || 0) / 30);
@ -29,11 +57,16 @@ const onLoad = (async (_: any, done: any) => {
</script> </script>
<template> <template>
<div class="flex q-mt-md"> <div class="flex">
<p class="text-h6 text-weight-medium align-center">ถาม - ตอบ</p> <p class="text-h6 text-weight-medium align-center">ถาม - ตอบ</p>
<q-space /> <q-space />
<p> <p>
<q-btn dense size="16px" flat text-color="teal"> <q-btn
dense
size="16px"
color="primary"
class="button-link-no-deco q-px-md"
>
<router-link to="/support/category"> ดการประเภทของปญหา </router-link> <router-link to="/support/category"> ดการประเภทของปญหา </router-link>
</q-btn> </q-btn>
</p> </p>
@ -70,6 +103,14 @@ const onLoad = (async (_: any, done: any) => {
{{ store.currentCategory }} {{ store.currentCategory }}
</q-badge></q-item-label </q-badge></q-item-label
> >
<span>
<q-icon
name="mdi-circle"
size="10px"
:color="getOnlineStatus('icon', createdByUser)"
/>
{{ getOnlineStatus("status", createdByUser) }}
</span>
</q-item-section> </q-item-section>
<q-space /> <q-space />
@ -102,6 +143,7 @@ const onLoad = (async (_: any, done: any) => {
store.currentTitle = item.title; store.currentTitle = item.title;
store.correntStatusIssue = item.status; store.correntStatusIssue = item.status;
store.currentCategory = item.category.name; store.currentCategory = item.category.name;
createdByUser = item.createdByUserId;
store.issue store.issue
? (store.issue.result = store.issue.result.map((v) => { ? (store.issue.result = store.issue.result.map((v) => {
if (v.id === item.id) { if (v.id === item.id) {
@ -150,7 +192,9 @@ const onLoad = (async (_: any, done: any) => {
/> />
<div v-else class="column"> <div v-else class="column">
<span class="col text-caption text-grey">20 s</span> <span class="col text-caption text-grey">{{
dateIssue(item.updatedAt)
}}</span>
<div class="col"> <div class="col">
<q-badge <q-badge
@ -325,6 +369,7 @@ const onLoad = (async (_: any, done: any) => {
.container-input { .container-input {
display: grid; display: grid;
grid-template-areas: "input-chat btn"; grid-template-areas: "input-chat btn";
grid-template-rows: 1fr; grid-template-rows: 1fr;
grid-template-columns: 1fr 100px; grid-template-columns: 1fr 100px;
} }
@ -372,4 +417,9 @@ const onLoad = (async (_: any, done: any) => {
/* grid-template-columns: 1fr 2fr; */ /* grid-template-columns: 1fr 2fr; */
grid: 50px 450px / 1fr 2fr; grid: 50px 450px / 1fr 2fr;
} }
.button-link-no-deco >>> a {
text-decoration: none;
color: inherit;
}
</style> </style>

View file

@ -1,5 +1,5 @@
import { defineStore } from "pinia"; import { defineStore } from "pinia";
import { ref, onMounted, nextTick } from "vue"; import { ref } from "vue";
import { io } from "socket.io-client"; import { io } from "socket.io-client";
import http from "@/plugins/http"; import http from "@/plugins/http";
import config from "@/app.config"; import config from "@/app.config";
@ -13,7 +13,7 @@ import type {
SupportIssueCategoryResponse, SupportIssueCategoryResponse,
} from "@/modules/00_support/interface/index/Main"; } from "@/modules/00_support/interface/index/Main";
import keycloak from "@/plugins/keycloak"; import keycloak from "@/plugins/keycloak";
import { useQuasar, type QTableProps } from "quasar"; import { useQuasar } from "quasar";
export const useSupportStore = defineStore("supportServiceStore", () => { export const useSupportStore = defineStore("supportServiceStore", () => {
const { showLoader, hideLoader, messageError } = useCounterMixin(); const { showLoader, hideLoader, messageError } = useCounterMixin();
@ -22,7 +22,7 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
const issue = ref<SupportIssueResponse>(); const issue = ref<SupportIssueResponse>();
const message = ref<SupportMessageResponse>(); const message = ref<SupportMessageResponse>();
const messageStatus = ref<SupportMessageStatus>(); const messageStatus = ref<SupportMessageStatus>();
const statusUser = ref<SupportStatusUser[]>([]); const userStatus = ref<SupportStatusUser[]>([]);
const currentIssue = ref<string>(""); const currentIssue = ref<string>("");
const currentTitle = ref<string>(""); const currentTitle = ref<string>("");
const currentCategoryId = ref<string>(""); const currentCategoryId = ref<string>("");
@ -34,29 +34,6 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
const currentTotalIssue = ref<number>(); const currentTotalIssue = ref<number>();
const currentCategory = ref<string>(); const currentCategory = ref<string>();
const columnsCategory = [
{
name: "id",
label: "id",
align: "center",
field: "id",
sortable: true,
},
{
name: "name",
align: "center",
label: "name",
field: "name",
sortable: true,
},
{
name: "actions",
align: "center",
label: "",
field: "",
},
] satisfies QTableProps["columns"];
const rowsCategory = ref<SupportIssueCategoryResponse>(); const rowsCategory = ref<SupportIssueCategoryResponse>();
function scrollToEnd(position: Number = 1) { function scrollToEnd(position: Number = 1) {
@ -71,11 +48,11 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
}); });
socket.on("users", (data: SupportStatusUser[]) => { socket.on("users", (data: SupportStatusUser[]) => {
statusUser.value = data; userStatus.value = data;
}); });
socket.on("online", (r) => { socket.on("online", (r) => {
statusUser.value.push({ userStatus.value.push({
socketId: r.socketId, socketId: r.socketId,
userId: r.userId, userId: r.userId,
name: r.name, name: r.name,
@ -85,7 +62,7 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
socket.on("offline", (socketId: string) => { socket.on("offline", (socketId: string) => {
if (socketId === socket.id) return; if (socketId === socket.id) return;
statusUser.value = statusUser.value.filter((v) => v.socketId !== socketId); userStatus.value = userStatus.value.filter((v) => v.socketId !== socketId);
}); });
socket.on("notify-message", (r) => { socket.on("notify-message", (r) => {
@ -94,10 +71,13 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
if (v.id === r.issueId) { if (v.id === r.issueId) {
v.unreadCount++; v.unreadCount++;
v.lastMessage = r.content; v.lastMessage = r.content;
v.updatedAt = r.updatedAt;
} }
return v; return v;
}); });
} }
console.log(r);
}); });
socket.on("read", (r) => { socket.on("read", (r) => {
@ -114,7 +94,9 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
if (issue.value) { if (issue.value) {
issue.value.result = issue.value.result.map((v) => { issue.value.result = issue.value.result.map((v) => {
if (v.id === r.issueId) v.lastMessage = r.content; if (v.id === r.issueId) {
v.lastMessage = r.content;
}
return v; return v;
}); });
} }
@ -124,6 +106,8 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
}); });
function sendMessage(content: string, to: string) { function sendMessage(content: string, to: string) {
console.log(to);
socket.emit("message", { to, content }); socket.emit("message", { to, content });
scrollToEnd(); scrollToEnd();
} }
@ -309,7 +293,7 @@ export const useSupportStore = defineStore("supportServiceStore", () => {
correntStatusIssue, correntStatusIssue,
currentCategory, currentCategory,
rowsCategory, rowsCategory,
columnsCategory, userStatus,
fetchIssue, fetchIssue,
fetchMessage, fetchMessage,
fetchMessageStatus, fetchMessageStatus,