เพิ่มระบบเวลา กับ สถานะออนไลน์
This commit is contained in:
parent
ca0f98ba29
commit
289e655495
2 changed files with 68 additions and 34 deletions
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue