แก้ไขการแสดงเวลา (support)
This commit is contained in:
parent
fc369de729
commit
e910d252aa
5 changed files with 260 additions and 225 deletions
|
|
@ -1,19 +1,25 @@
|
|||
import env from "../index"
|
||||
import env from "../index";
|
||||
|
||||
const support = `${env.API_URL_SUPPORT}`
|
||||
const support = `${env.API_URL_SUPPORT}`;
|
||||
|
||||
export default {
|
||||
supportMessageStatus: (id: string) => `${support}/issue/${id}/message-status`,
|
||||
supportMessageStatus: (id: string) => `${support}/issue/${id}/message-status`,
|
||||
|
||||
supportMessage: (id: string, pageSize: number = 999, page: number = 1) => `${support}/issue/${id}/message?pageSize=${pageSize}&page=${page}`,
|
||||
supportMessage: (id: string, pageSize: number = 999, page: number = 1) =>
|
||||
`${support}/issue/${id}/message?pageSize=${pageSize}&page=${page}`,
|
||||
|
||||
supportIssueUserId: (userId: string) => `${support}/issue?userId=${userId}`,
|
||||
supportIssueUserId: (userId: string) => `${support}/issue?userId=${userId}`,
|
||||
|
||||
supportIssue: (pageSize: number = 999, page: number = 1) => `${support}/issue?pageSize=${pageSize}&page=${page}`,
|
||||
supportIssue: (pageSize: number = 999, page: number = 1) =>
|
||||
`${support}/issue?pageSize=${pageSize}&page=${page}`,
|
||||
|
||||
supportSearchIssue: (search: string, pageSize: number = 999, page: number = 1) => `${support}/issue?pageSize=${pageSize}&page=${page}&search=${search}`,
|
||||
supportSearchIssue: (
|
||||
search: string,
|
||||
pageSize: number = 999,
|
||||
page: number = 1
|
||||
) => `${support}/issue?pageSize=${pageSize}&page=${page}&search=${search}`,
|
||||
|
||||
supportIssueCategory: `${support}/issue-category`,
|
||||
supportNewIssue: `${support}/issue`,
|
||||
supportSocket: `${support}`,
|
||||
}
|
||||
supportIssueCategory: `${support}/issue-category`,
|
||||
supportNewIssue: `${support}/issue`,
|
||||
supportSocket: `${new URL(support).origin}`,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ function dateChat(timestamp: string) {
|
|||
const diff = moment().diff(parsedTimestamp);
|
||||
|
||||
if (diff < 86400000) {
|
||||
const formattedDate = parsedTimestamp.format("HH:mm:") + " น.";
|
||||
const formattedDate = parsedTimestamp.format("HH:mm") + " น.";
|
||||
return formattedDate;
|
||||
} else {
|
||||
const beYear = parsedTimestamp.year() + 543;
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
import { ref } from "vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useSupportStore } from "@/modules/00_support/store/Main";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import ChatMessage from "@/modules/00_support/components/ChatMessage.vue";
|
||||
|
||||
const store = useSupportStore();
|
||||
const content = ref<string>("");
|
||||
const { date2Thai } = useCounterMixin();
|
||||
const { scrollContainer } = storeToRefs(store);
|
||||
|
||||
function getOnlineStatus(option: "icon" | "status") {
|
||||
|
|
@ -13,6 +15,11 @@ function getOnlineStatus(option: "icon" | "status") {
|
|||
if (option === "icon") return isAdmin ? "green" : "grey";
|
||||
if (option === "status") return isAdmin ? "ออนไลน์" : "ออฟไลน์";
|
||||
}
|
||||
|
||||
const thaiOptions: Intl.DateTimeFormatOptions = {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
|
@ -57,7 +64,21 @@ function getOnlineStatus(option: "icon" | "status") {
|
|||
name="mdi-information-outline"
|
||||
size="24px"
|
||||
color="grey"
|
||||
/>
|
||||
>
|
||||
<q-tooltip class="column">
|
||||
<span>{{ store.currentTitle }}</span>
|
||||
<span>
|
||||
{{ date2Thai(store.currentIssueDate) }}
|
||||
{{
|
||||
new Date(store.currentIssueDate).toLocaleTimeString(
|
||||
"th-TH",
|
||||
thaiOptions
|
||||
)
|
||||
}}
|
||||
น. <q-space />
|
||||
</span>
|
||||
</q-tooltip>
|
||||
</q-icon>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
|
|
|
|||
|
|
@ -1,238 +1,245 @@
|
|||
import { defineStore } from "pinia"
|
||||
import { ref } from "vue"
|
||||
import { io } from "socket.io-client"
|
||||
import { useQuasar } from "quasar"
|
||||
import http from "@/plugins/http"
|
||||
import config from "@/app.config"
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
import { io } from "socket.io-client";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import type {
|
||||
SupportMessageResponse,
|
||||
SupportIssueResponse,
|
||||
SupportIssueCategoryResponse,
|
||||
SupportMessageStatusResponse,
|
||||
SupportUserStatus,
|
||||
SupportMessageStatus,
|
||||
} from "@/modules/00_support/interface/index/Main"
|
||||
import keycloak from "@/plugins/keycloak"
|
||||
import { useCounterMixin } from "@/stores/mixin"
|
||||
SupportMessageResponse,
|
||||
SupportIssueResponse,
|
||||
SupportIssueCategoryResponse,
|
||||
SupportMessageStatusResponse,
|
||||
SupportUserStatus,
|
||||
SupportMessageStatus,
|
||||
} from "@/modules/00_support/interface/index/Main";
|
||||
import keycloak from "@/plugins/keycloak";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
export const useSupportStore = defineStore("supportServiceStore", () => {
|
||||
const { showLoader, hideLoader, messageError } = useCounterMixin()
|
||||
const $q = useQuasar()
|
||||
const openChat = ref<boolean>(false)
|
||||
const icon = ref<string>("mdi-account-check")
|
||||
const userId = ref<string | undefined>(keycloak.subject)
|
||||
const userStatus = ref<SupportUserStatus[]>([])
|
||||
const issue = ref<SupportIssueResponse>()
|
||||
const issueCategory = ref<SupportIssueCategoryResponse>()
|
||||
const messageStatus = ref<SupportMessageStatusResponse>()
|
||||
const message = ref<SupportMessageResponse>()
|
||||
const currentIssue = ref<string>("")
|
||||
const currentTitle = ref<string>("")
|
||||
const items = ref<any>([{}, {}, {}, {}, {}, {}, {}])
|
||||
const scrollContainer = ref()
|
||||
const { showLoader, hideLoader, messageError } = useCounterMixin();
|
||||
const $q = useQuasar();
|
||||
const openChat = ref<boolean>(false);
|
||||
const icon = ref<string>("mdi-account-check");
|
||||
const userId = ref<string | undefined>(keycloak.subject);
|
||||
const userStatus = ref<SupportUserStatus[]>([]);
|
||||
const issue = ref<SupportIssueResponse>();
|
||||
const issueCategory = ref<SupportIssueCategoryResponse>();
|
||||
const messageStatus = ref<SupportMessageStatusResponse>();
|
||||
const message = ref<SupportMessageResponse>();
|
||||
const currentIssue = ref<string>("");
|
||||
const currentIssueDate = ref<any>("");
|
||||
const currentTitle = ref<string>("");
|
||||
const items = ref<any>([{}, {}, {}, {}, {}, {}, {}]);
|
||||
const scrollContainer = ref();
|
||||
|
||||
const socket = io(config.API.supportSocket, {
|
||||
auth: { token: keycloak.token },
|
||||
autoConnect: false,
|
||||
path: "/api/v1/support/socket/",
|
||||
})
|
||||
const socket = io(config.API.supportSocket, {
|
||||
auth: { token: keycloak.token },
|
||||
autoConnect: false,
|
||||
path: "/api/v1/support/socket/",
|
||||
});
|
||||
|
||||
socket.on("users", (data: SupportUserStatus[]) => {
|
||||
userStatus.value = data
|
||||
})
|
||||
socket.on("users", (data: SupportUserStatus[]) => {
|
||||
userStatus.value = data;
|
||||
});
|
||||
|
||||
socket.on("online", r => {
|
||||
userStatus.value.push({
|
||||
socketId: r.socketId,
|
||||
userId: r.userId,
|
||||
name: r.name,
|
||||
role: r.role,
|
||||
})
|
||||
// console.log("online: ", userStatus.value);
|
||||
})
|
||||
socket.on("online", (r) => {
|
||||
userStatus.value.push({
|
||||
socketId: r.socketId,
|
||||
userId: r.userId,
|
||||
name: r.name,
|
||||
role: r.role,
|
||||
});
|
||||
// console.log("online: ", userStatus.value);
|
||||
});
|
||||
|
||||
socket.on("offline", (socketId: string) => {
|
||||
if (socketId === socket.id) return
|
||||
userStatus.value = userStatus.value.filter(v => v.socketId !== socketId)
|
||||
// console.log("offline: ", userStatus.value);
|
||||
})
|
||||
socket.on("offline", (socketId: string) => {
|
||||
if (socketId === socket.id) return;
|
||||
userStatus.value = userStatus.value.filter((v) => v.socketId !== socketId);
|
||||
// console.log("offline: ", userStatus.value);
|
||||
});
|
||||
|
||||
socket.on("notify-message", r => {
|
||||
if (issue.value) {
|
||||
issue.value.result = issue.value.result.map(v => {
|
||||
if (v.id === r.issueId) {
|
||||
v.unreadCount++
|
||||
v.lastMessage = r.content
|
||||
}
|
||||
return v
|
||||
})
|
||||
}
|
||||
})
|
||||
socket.on("notify-message", (r) => {
|
||||
if (issue.value) {
|
||||
issue.value.result = issue.value.result.map((v) => {
|
||||
if (v.id === r.issueId) {
|
||||
v.unreadCount++;
|
||||
v.lastMessage = r.content;
|
||||
}
|
||||
if (currentIssue.value === r.issueId) {
|
||||
v.unreadCount = 0;
|
||||
}
|
||||
return v;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
socket.on("message", r => {
|
||||
message.value?.result.message.push(r)
|
||||
socket.on("message", (r) => {
|
||||
message.value?.result.message.push(r);
|
||||
|
||||
if (issue.value) {
|
||||
issue.value.result = issue.value.result.map(v => {
|
||||
if (v.id === r.issueId) v.lastMessage = r.content
|
||||
return v
|
||||
})
|
||||
}
|
||||
socket.emit("mark-read", { issueId: currentIssue.value })
|
||||
scrollToEnd()
|
||||
// console.log(r.id);
|
||||
// console.log(message.value?.result.message);
|
||||
})
|
||||
if (issue.value) {
|
||||
issue.value.result = issue.value.result.map((v) => {
|
||||
if (v.id === r.issueId) v.lastMessage = r.content;
|
||||
return v;
|
||||
});
|
||||
}
|
||||
socket.emit("mark-read", { issueId: currentIssue.value });
|
||||
scrollToEnd();
|
||||
// console.log(r.id);
|
||||
// console.log(message.value?.result.message);
|
||||
});
|
||||
|
||||
socket.on("read", (r: SupportMessageStatus) => {
|
||||
if (messageStatus.value) {
|
||||
messageStatus.value.result = messageStatus.value.result.map(v => {
|
||||
if (v.fromUserId !== r.fromUserId) return r
|
||||
return v
|
||||
})
|
||||
}
|
||||
// console.log("event(read):", messageStatus.value);
|
||||
})
|
||||
socket.on("read", (r: SupportMessageStatus) => {
|
||||
if (messageStatus.value) {
|
||||
messageStatus.value.result = messageStatus.value.result.map((v) => {
|
||||
if (v.fromUserId !== r.fromUserId) return r;
|
||||
return v;
|
||||
});
|
||||
}
|
||||
// console.log("event(read):", messageStatus.value);
|
||||
});
|
||||
|
||||
function scrollToEnd(position: Number = 1) {
|
||||
setTimeout(() => {
|
||||
scrollContainer.value?.setScrollPercentage("vertical", position)
|
||||
}, 150)
|
||||
}
|
||||
function scrollToEnd(position: Number = 1) {
|
||||
setTimeout(() => {
|
||||
scrollContainer.value?.setScrollPercentage("vertical", position);
|
||||
}, 150);
|
||||
}
|
||||
|
||||
function sendMessage(content: string, to: string) {
|
||||
// console.log(content);
|
||||
// console.log(to);
|
||||
if (content.trim() !== "") {
|
||||
socket.emit("message", { to, content })
|
||||
scrollToEnd()
|
||||
}
|
||||
}
|
||||
function sendMessage(content: string, to: string) {
|
||||
// console.log(content);
|
||||
// console.log(to);
|
||||
if (content.trim() !== "") {
|
||||
socket.emit("message", { to, content });
|
||||
scrollToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchMessageStatus(issueId: string) {
|
||||
showLoader()
|
||||
const res = await http
|
||||
.get(config.API.supportMessageStatus(issueId))
|
||||
.catch(err => {
|
||||
messageError($q, err)
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader()
|
||||
})
|
||||
if (res && res.data) {
|
||||
messageStatus.value = res.data
|
||||
// console.log(messageStatus.value);
|
||||
}
|
||||
}
|
||||
async function fetchMessageStatus(issueId: string) {
|
||||
showLoader();
|
||||
const res = await http
|
||||
.get(config.API.supportMessageStatus(issueId))
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
if (res && res.data) {
|
||||
messageStatus.value = res.data;
|
||||
// console.log(messageStatus.value);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchMessage(issueId: string) {
|
||||
showLoader()
|
||||
const res = await http
|
||||
.get(config.API.supportMessage(issueId))
|
||||
.catch(err => {
|
||||
messageError($q, err)
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader()
|
||||
})
|
||||
if (res && res.data) {
|
||||
message.value = await res.data
|
||||
message.value?.result.message.reverse()
|
||||
socket.emit("join-issue", { issueId })
|
||||
socket.emit("mark-read", { issueId })
|
||||
scrollToEnd()
|
||||
}
|
||||
}
|
||||
async function fetchMessage(issueId: string) {
|
||||
showLoader();
|
||||
const res = await http
|
||||
.get(config.API.supportMessage(issueId))
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
if (res && res.data) {
|
||||
message.value = await res.data;
|
||||
message.value?.result.message.reverse();
|
||||
socket.emit("join-issue", { issueId });
|
||||
socket.emit("mark-read", { issueId });
|
||||
scrollToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchIssue() {
|
||||
if (!userId.value) return
|
||||
showLoader()
|
||||
const res = await http
|
||||
.get(config.API.supportIssueUserId(userId.value))
|
||||
.catch(err => {
|
||||
messageError($q, err)
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader()
|
||||
})
|
||||
async function fetchIssue() {
|
||||
if (!userId.value) return;
|
||||
showLoader();
|
||||
const res = await http
|
||||
.get(config.API.supportIssueUserId(userId.value))
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
|
||||
if (res && res.data) {
|
||||
issue.value = res.data
|
||||
// console.log(JSON.stringify(res.data, null, 2));
|
||||
}
|
||||
}
|
||||
if (res && res.data) {
|
||||
issue.value = res.data;
|
||||
// console.log(JSON.stringify(res.data, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchIssueCategory() {
|
||||
showLoader()
|
||||
async function fetchIssueCategory() {
|
||||
showLoader();
|
||||
|
||||
const res = await http
|
||||
.get(config.API.supportIssueCategory)
|
||||
.catch(err => {
|
||||
messageError($q, err)
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader()
|
||||
})
|
||||
const res = await http
|
||||
.get(config.API.supportIssueCategory)
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
|
||||
if (res && res.data) {
|
||||
issueCategory.value = res.data
|
||||
// console.log(JSON.stringify(res.data, null, 2));
|
||||
}
|
||||
}
|
||||
if (res && res.data) {
|
||||
issueCategory.value = res.data;
|
||||
// console.log(JSON.stringify(res.data, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
async function newIssue(title: string, categoryId: string) {
|
||||
showLoader()
|
||||
async function newIssue(title: string, categoryId: string) {
|
||||
showLoader();
|
||||
|
||||
const requestBody = {
|
||||
title: title,
|
||||
categoryId: categoryId,
|
||||
}
|
||||
const requestBody = {
|
||||
title: title,
|
||||
categoryId: categoryId,
|
||||
};
|
||||
|
||||
const res = await http
|
||||
.post(config.API.supportNewIssue, requestBody)
|
||||
.catch(err => {
|
||||
messageError($q, err)
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader()
|
||||
})
|
||||
const res = await http
|
||||
.post(config.API.supportNewIssue, requestBody)
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
|
||||
if (res) {
|
||||
fetchIssue()
|
||||
// console.log(JSON.stringify(res.data, null, 2));
|
||||
}
|
||||
}
|
||||
if (res) {
|
||||
fetchIssue();
|
||||
// console.log(JSON.stringify(res.data, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
async function searchIssue(searchData: string) {
|
||||
const res = await http.get(config.API.supportSearchIssue(searchData)).catch(err => {
|
||||
messageError($q, err)
|
||||
})
|
||||
if (res && res.data) {
|
||||
issue.value = res.data
|
||||
// console.log(issue.value);
|
||||
}
|
||||
}
|
||||
async function searchIssue(searchData: string) {
|
||||
const res = await http
|
||||
.get(config.API.supportSearchIssue(searchData))
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
});
|
||||
if (res && res.data) {
|
||||
issue.value = res.data;
|
||||
// console.log(issue.value);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
userId,
|
||||
issue,
|
||||
issueCategory,
|
||||
message,
|
||||
messageStatus,
|
||||
userStatus,
|
||||
currentIssue,
|
||||
currentTitle,
|
||||
fetchIssue,
|
||||
fetchIssueCategory,
|
||||
fetchMessageStatus,
|
||||
fetchMessage,
|
||||
sendMessage,
|
||||
newIssue,
|
||||
searchIssue,
|
||||
openChat,
|
||||
items,
|
||||
socket,
|
||||
scrollContainer,
|
||||
icon,
|
||||
}
|
||||
})
|
||||
return {
|
||||
userId,
|
||||
issue,
|
||||
issueCategory,
|
||||
message,
|
||||
messageStatus,
|
||||
userStatus,
|
||||
currentIssue,
|
||||
currentIssueDate,
|
||||
currentTitle,
|
||||
fetchIssue,
|
||||
fetchIssueCategory,
|
||||
fetchMessageStatus,
|
||||
fetchMessage,
|
||||
sendMessage,
|
||||
newIssue,
|
||||
searchIssue,
|
||||
openChat,
|
||||
items,
|
||||
socket,
|
||||
scrollContainer,
|
||||
icon,
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ watch(searchData, () => {
|
|||
$q.screen.gt.xs ? '' : (store.openChat = true);
|
||||
store.currentIssue = item.id;
|
||||
store.currentTitle = item.title;
|
||||
store.currentIssueDate = item.createdAt
|
||||
store.issue
|
||||
? (store.issue.result = store.issue.result.map(
|
||||
(v) => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue