From fc369de7297ad4fd4f6ff3e21d5bbcb748ec4e83 Mon Sep 17 00:00:00 2001 From: Kittapath Date: Fri, 16 Feb 2024 14:31:05 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B8=95=E0=B9=88=E0=B8=AD=20socket=20?= =?UTF-8?q?=E0=B8=81=E0=B8=B1=E0=B8=9Aserver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 63 +++- src/api/index.ts | 77 +++-- src/api/support/api.support.ts | 29 +- src/modules/00_support/store/Main.ts | 425 +++++++++++++-------------- 4 files changed, 317 insertions(+), 277 deletions(-) diff --git a/package-lock.json b/package-lock.json index 63387c3..91582e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "moment": "^2.29.4", "pinia": "^2.0.29", "quasar": "^2.11.1", + "socket.io-client": "^4.7.4", "structure-chart": "^0.0.9", "vue": "^3.4.15", "vue-router": "^4.1.6", @@ -1191,6 +1192,11 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + }, "node_modules/@tato30/vue-pdf": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/@tato30/vue-pdf/-/vue-pdf-1.6.2.tgz", @@ -2894,7 +2900,6 @@ }, "node_modules/debug": { "version": "4.3.4", - "devOptional": true, "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -3056,6 +3061,26 @@ "once": "^1.4.0" } }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz", + "integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/enquirer": { "version": "2.3.6", "dev": true, @@ -5456,7 +5481,6 @@ }, "node_modules/ms": { "version": "2.1.2", - "devOptional": true, "license": "MIT" }, "node_modules/muggle-string": { @@ -6702,6 +6726,32 @@ "dev": true, "license": "MIT" }, + "node_modules/socket.io-client": { + "version": "4.7.4", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.4.tgz", + "integrity": "sha512-wh+OkeF0rAVCrABWQBaEjLfb7DVPotMbu0cgWgyR0v6eA4EoVnAwcIeIbcdTE3GT/H3kbdLl7OoH2+asoDRIIg==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.2", + "engine.io-client": "~6.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "dev": true, @@ -7804,7 +7854,6 @@ }, "node_modules/ws": { "version": "8.11.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10.0.0" @@ -7835,6 +7884,14 @@ "dev": true, "license": "MIT" }, + "node_modules/xmlhttprequest-ssl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", + "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/yallist": { "version": "3.1.1", "dev": true, diff --git a/src/api/index.ts b/src/api/index.ts index bd53cbe..f3da588 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,53 +1,44 @@ /**config api */ -import { ref } from "vue"; +import { ref } from "vue" -const env = ref(process.env.NODE_ENV || "development"); -export const apiUrlConfig = import.meta.env.VITE_API_URI_CONFIG; -export const apiUrlConfigPublish = import.meta.env.VITE_API_PUBLISH_URL; +const env = ref(process.env.NODE_ENV || "development") +export const apiUrlConfig = import.meta.env.VITE_API_URI_CONFIG +export const apiUrlConfigPublish = import.meta.env.VITE_API_PUBLISH_URL // if (process.env.VUE_APP_TEST) { // env = "test"; // } const config = ref({ - development: { - // API_URI: "https://localhost:7260/api", - API_URI: "https://bma-ehr.frappet.synology.me/api/v1", - API_URL_SUPPORT: "http://192.168.1.10:3000/api/v1/support", - API_SUPPORT_SOCKET: "http://192.168.1.10:3000/", - MEET_URI: "meet.frappet.com", - LINK_EVALUATE_PUBLISH: "https://bma-ehr-publish.frappet.synology.me", - }, - test: { - API_URI: "http://localhost:5010/api/v1", - MEET_URI: "meet.frappet.com", - }, - production: { - API_URI: apiUrlConfig, - API_URL_SUPPORT: "http://192.168.1.10:3000/api/v1/support", - API_SUPPORT_SOCKET: "http://192.168.1.10:3000/", - API_URI_ORG_TREE: - "https://s3cluster.frappet.com/bma-ehr-fpt/organization/strueture/tree_20230707_115124.json", - MEET_URI: "meet.frappet.com", - LINK_EVALUATE_PUBLISH: apiUrlConfigPublish, - }, -}); + development: { + // API_URI: "https://localhost:7260/api", + API_URI: "https://bma-ehr.frappet.synology.me/api/v1", + API_URL_SUPPORT: "https://bma-ehr.frappet.synology.me/api/v1/support", + MEET_URI: "meet.frappet.com", + LINK_EVALUATE_PUBLISH: "https://bma-ehr-publish.frappet.synology.me", + }, + test: { + API_URI: "http://localhost:5010/api/v1", + MEET_URI: "meet.frappet.com", + }, + production: { + API_URI: apiUrlConfig, + API_URL_SUPPORT: `${apiUrlConfig}/support`, + API_URI_ORG_TREE: "https://s3cluster.frappet.com/bma-ehr-fpt/organization/strueture/tree_20230707_115124.json", + MEET_URI: "meet.frappet.com", + LINK_EVALUATE_PUBLISH: apiUrlConfigPublish, + }, +}) -const API_URI = ref(config.value[env.value].API_URI); -const API_URL_SUPPORT = ref(config.value[env.value].API_URL_SUPPORT); -const API_SUPPORT_SOCKET = ref( - config.value[env.value].API_SUPPORT_SOCKET -); -const MEET_URI = ref(config.value[env.value].MEET_URI); -const LINK_EVALUATE_PUBLISH = ref( - config.value[env.value].LINK_EVALUATE_PUBLISH -); +const API_URI = ref(config.value[env.value].API_URI) +const API_URL_SUPPORT = ref(config.value[env.value].API_URL_SUPPORT) +const MEET_URI = ref(config.value[env.value].MEET_URI) +const LINK_EVALUATE_PUBLISH = ref(config.value[env.value].LINK_EVALUATE_PUBLISH) export default { - env: env.value, - config: config.value, - API_URI: API_URI.value, - API_URL_SUPPORT: API_URL_SUPPORT.value, - API_SUPPORT_SOCKET: API_SUPPORT_SOCKET.value, - MEET_URI: MEET_URI.value, - LINK_EVALUATE_PUBLISH: LINK_EVALUATE_PUBLISH.value, -}; + env: env.value, + config: config.value, + API_URI: API_URI.value, + API_URL_SUPPORT: API_URL_SUPPORT.value, + MEET_URI: MEET_URI.value, + LINK_EVALUATE_PUBLISH: LINK_EVALUATE_PUBLISH.value, +} diff --git a/src/api/support/api.support.ts b/src/api/support/api.support.ts index 5e2e63d..68025dd 100644 --- a/src/api/support/api.support.ts +++ b/src/api/support/api.support.ts @@ -1,26 +1,19 @@ -import env from "../index"; +import env from "../index" -const support = `${env.API_URL_SUPPORT}`; -const socket = `${env.API_SUPPORT_SOCKET}`; +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: `${socket}`, -}; + supportIssueCategory: `${support}/issue-category`, + supportNewIssue: `${support}/issue`, + supportSocket: `${support}`, +} diff --git a/src/modules/00_support/store/Main.ts b/src/modules/00_support/store/Main.ts index 32ab66d..36f8fd8 100644 --- a/src/modules/00_support/store/Main.ts +++ b/src/modules/00_support/store/Main.ts @@ -1,239 +1,238 @@ -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(false); - const icon = ref("mdi-account-check"); - const userId = ref(keycloak.subject); - const userStatus = ref([]); - const issue = ref(); - const issueCategory = ref(); - const messageStatus = ref(); - const message = ref(); - const currentIssue = ref(""); - const currentTitle = ref(""); - const items = ref([{}, {}, {}, {}, {}, {}, {}]); - const scrollContainer = ref(); + const { showLoader, hideLoader, messageError } = useCounterMixin() + const $q = useQuasar() + const openChat = ref(false) + const icon = ref("mdi-account-check") + const userId = ref(keycloak.subject) + const userStatus = ref([]) + const issue = ref() + const issueCategory = ref() + const messageStatus = ref() + const message = ref() + const currentIssue = ref("") + const currentTitle = ref("") + const items = ref([{}, {}, {}, {}, {}, {}, {}]) + const scrollContainer = ref() - const socket = io(config.API.supportSocket, { - auth: { token: keycloak.token }, - autoConnect: false, - }); + 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 + } + 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, + currentTitle, + fetchIssue, + fetchIssueCategory, + fetchMessageStatus, + fetchMessage, + sendMessage, + newIssue, + searchIssue, + openChat, + items, + socket, + scrollContainer, + icon, + } +})