From 61e322ea6ae95f2f6dd4fce631c43071bcdab331 Mon Sep 17 00:00:00 2001 From: adriano Date: Fri, 6 May 2022 19:49:45 -0300 Subject: [PATCH] =?UTF-8?q?codifica=C3=A7=C3=A3o=20completa=20para=20regis?= =?UTF-8?q?tro=20do=20online=20offline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 2 + backend/src/controllers/ReportController.ts | 17 +- .../helpers/SchedulingNotifySendMessage.ts | 2 +- backend/src/helpers/WhoIsOnlineMonitor.ts | 148 ++++++++++++++++-- backend/src/libs/socket.ts | 117 ++++++++++---- backend/src/server.ts | 2 +- .../CreateOrUpdateOnlineUserService.ts | 9 +- .../UserServices/ListUserParamiterService.ts | 54 +++++++ .../ListUsersOnlineOfflineService.ts | 72 +++++++++ .../WbotServices/wbotMessageListener.ts | 2 +- .../components/NotificationsPopOver/index.js | 38 ++++- frontend/src/components/TicketsList/index.js | 3 +- 12 files changed, 407 insertions(+), 59 deletions(-) create mode 100644 backend/src/services/UserServices/ListUserParamiterService.ts create mode 100644 backend/src/services/UserServices/ListUsersOnlineOfflineService.ts diff --git a/backend/package.json b/backend/package.json index 8055daf..9041ddb 100644 --- a/backend/package.json +++ b/backend/package.json @@ -38,6 +38,7 @@ "sequelize-cli": "^5.5.1", "sequelize-typescript": "^1.1.0", "socket.io": "^3.0.5", + "uuid": "^8.3.2", "whatsapp-web.js": "github:pedroslopez/whatsapp-web.js", "yup": "^0.32.8" }, @@ -54,6 +55,7 @@ "@types/multer": "^1.4.4", "@types/node": "^14.11.8", "@types/supertest": "^2.0.10", + "@types/uuid": "^8.3.4", "@types/validator": "^13.1.0", "@types/yup": "^0.29.8", "@typescript-eslint/eslint-plugin": "^4.4.0", diff --git a/backend/src/controllers/ReportController.ts b/backend/src/controllers/ReportController.ts index 61d5beb..817b068 100644 --- a/backend/src/controllers/ReportController.ts +++ b/backend/src/controllers/ReportController.ts @@ -5,8 +5,18 @@ import AppError from "../errors/AppError"; import ShowTicketReport from "../services/TicketServices/ShowTicketReport"; import ShowMessageReport from "../services/MessageServices/ShowMessageReport"; -import onlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService"; +import onlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService"; +import User from "../models/User"; +import Queue from "../models/Queue"; +import UserOnlineTime from "../models/UserOnlineTime"; +import { Op, Sequelize } from "sequelize"; +import format from 'date-fns/format'; +import ptBR from 'date-fns/locale/pt-BR'; +import { splitDateTime } from "../helpers/SplitDateTime"; +import ListUserOnlineOffline from "../services/UserServices/ListUsersOnlineOfflineService"; +import ListUserParamiterService from "../services/UserServices/ListUserParamiterService"; + type IndexQuery = { userId: string; @@ -15,10 +25,7 @@ type IndexQuery = { }; -export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise => { - - - //const test = await onlineUserService({userId: 3, status: 'offline'}) +export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise => { if (req.user.profile !== "master" && req.user.profile !== "admin") { diff --git a/backend/src/helpers/SchedulingNotifySendMessage.ts b/backend/src/helpers/SchedulingNotifySendMessage.ts index 5a42223..0622a6e 100644 --- a/backend/src/helpers/SchedulingNotifySendMessage.ts +++ b/backend/src/helpers/SchedulingNotifySendMessage.ts @@ -23,7 +23,7 @@ const monitor = async () => { let fullDate = `${year}-${month}-${day}`; let dateParm = `${fullDate} ${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:00` - console.log(dateParm); + //console.log(dateParm); const { schedulingNotifies, count, hasMore } = await ListSchedulingNotifyService({ searchParam: dateParm, pageNumber: "1" }); diff --git a/backend/src/helpers/WhoIsOnlineMonitor.ts b/backend/src/helpers/WhoIsOnlineMonitor.ts index bc6598d..2f6381d 100644 --- a/backend/src/helpers/WhoIsOnlineMonitor.ts +++ b/backend/src/helpers/WhoIsOnlineMonitor.ts @@ -1,29 +1,148 @@ - -import { getIO } from "../libs/socket"; -// import usersOnline from '../libs/socket' - -let whoIsOnline_monitor:any; +import e from "express"; +import { bool, number } from "yup"; +import { getIO } from "../libs/socket"; +import Queue from "../models/Queue"; +import ListUserParamiterService from "../services/UserServices/ListUserParamiterService"; -const monitor = async () => { - - const io = getIO(); - io.emit("isOnline"); +import createOrUpdateOnlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService"; +import { splitDateTime } from "../helpers/SplitDateTime"; +import format from 'date-fns/format'; +import ptBR from 'date-fns/locale/pt-BR'; +import ListUserOnlineOffline from "../services/UserServices/ListUsersOnlineOfflineService"; +import { check } from "prettier"; - //const test = require('./../libs/socket'); - // console.log('*usersOnline: ', test.listOnlineUsers) +let whoIsOnline_monitor: any; +// const listUserId:any[] = [{'id':8, status: 'offline'},{'id':3, status: 'offline'},{'id':5, status: 'offline'}] +let listUserId: any[] = [] +let count = 0 +let countTest = 0 +let uuid: any = 0 +let dateTime = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) +let checked: boolean = false +let count2 = 0 + +const setOfflineAllUsers = async () => { + + const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate, status: 'online' }) + + console.log(' onlineUsers: ', onlineUsers) + + if (onlineUsers.length > 0) { + onlineUsers.forEach(async user => { + await createOrUpdateOnlineUserService({ userId: user.userId, status: 'offline' }) + }); + } +} + + +const monitor = async () => { + + const test = require('./../libs/socket'); + + console.log(' TEST OBJ', test.ob) + + //test del + + if(countTest > 5){ + countTest = 0 + } + + if (countTest == 0) { + + //console.log('NEW USERS QUERY EMITER!') + + listUserId = await ListUserParamiterService({ profile: 'user' }) + + //console.log('----------- listUserId: ', listUserId) + + } + + countTest++ + // + + if(listUserId.length == 0){ + return; + } + + + listUserId.forEach((u) => { + const io = getIO(); + io.emit("isOnline", { action: "online", userId: u.id }); + }); + + + if(test.ob){ + + if (count > 1) { + count = 0 + } + + if (count == 0) { + // uuid = test.uuid + uuid = test.ob.uuid + } + + if (count == 1) { + if (uuid) { + if (uuid == test.ob.uuid) { + + console.log('ALL USERS CLIENTS OFFLINE 1...........') + + await setOfflineAllUsers() + test.ob.listOnline = [] + test.ob.listOnline2 = [] + test.ob.uuid = undefined + checked = true + } + else { + console.log('*usersOnline: ', test.ob.listOnline) + checked = false + count2 = 0 + } + } + else { + console.log('ALL USERS CLIENTS OFFLINE 2...........') + + if(!checked){ + await setOfflineAllUsers() + checked = true + } + + } + } + + console.log(' | count: ',count, ' | test.ob.listOnline: ', test.ob.listOnline) + + count++ + + } + else { + console.log('ALL USERS CLIENTS OFFLINE 3...........') + + if(!checked && count2>10){ + await setOfflineAllUsers() + checked = true + } + + if(count2 < 12){ + count2++ + } + + console.log('>>>>>>>>>>>>>>>>>>> count2: ', count2) + } }; -export const startWhoIsOnlinegMonitor =async (mileseconds: number) => { +export const startWhoIsOnlinegMonitor = async (mileseconds: number) => { whoIsOnline_monitor = setInterval(monitor, mileseconds) } - -export const stopWhoIsOnlineMonitor =async ( ) => { + +export const stopWhoIsOnlineMonitor = async () => { clearInterval(whoIsOnline_monitor) @@ -32,4 +151,3 @@ export const stopWhoIsOnlineMonitor =async ( ) => { - \ No newline at end of file diff --git a/backend/src/libs/socket.ts b/backend/src/libs/socket.ts index 3ee2ce8..384fb6a 100644 --- a/backend/src/libs/socket.ts +++ b/backend/src/libs/socket.ts @@ -3,53 +3,111 @@ import { Server } from "http"; import AppError from "../errors/AppError"; import { logger } from "../utils/logger"; +import { v4 as uuidv4 } from 'uuid'; +import ListUserParamiterService from "../services/UserServices/ListUserParamiterService"; + + let io: SocketIO; //test del -let listOnlineUsers:any[]=[] -let count:number = 0 -// +import createOrUpdateOnlineUserService from "../services/UserServices/CreateOrUpdateOnlineUserService"; +import { splitDateTime } from "../helpers/SplitDateTime"; +import format from 'date-fns/format'; +import ptBR from 'date-fns/locale/pt-BR'; +import ListUserOnlineOffline from "../services/UserServices/ListUsersOnlineOfflineService"; +let count: number = 0 +let listOnline: any[] = [] +let listOnline2: any[] = [] + +let countOnline: number = 0 +//let obj = { DESCENT_STEPS: 5000, ALPHA: 0.0005} + +let obj:any = { listOnline: [], listOnline2: [], uuid: null} + + +let dateTime = splitDateTime(new Date(format(new Date(), 'yyyy-MM-dd HH:mm:ss', { locale: ptBR }))) + +// + export const initIO = (httpServer: Server): SocketIO => { io = new SocketIO(httpServer, { cors: { origin: process.env.FRONTEND_URL } - }); - + }); + io.on("connection", socket => { - logger.info("Client Connected"); - - - socket.on("online", (userId: string) => { - - - logger.info(`CLIENT ID ${userId}` ); + logger.info("Client Connected"); - const indexUser = listOnlineUsers.findIndex((e) => e.userId == userId) + socket.on("online", async (userId: string) => { - if(indexUser == -1){ - //listOnlineUsers.push({userId: userId, status: 'online'}) - } + + console.log(' ----------------------------- listOnlie: ', obj.listOnline) - count++ + const indexUser = obj.listOnline.findIndex((e:any) => e.id == userId) - //console.log('count: ', count) + if (indexUser == -1) { + obj.listOnline.push({ 'id': userId }) - if(count >= listOnlineUsers.length){ - //console.log('listOnlineUsers1: ', listOnlineUsers) + const onlineUser = await createOrUpdateOnlineUserService({ userId: userId, status: 'online' }) - count = 0 + const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate, status: 'online' }) + + countOnline = onlineUsers.length + + console.log(' PUSHED NEW ID: ', userId) } - //console.log('listOnlineUsers1: ', listOnlineUsers) - - - - }); + + const index = obj.listOnline2.findIndex((e:any) => e.id == userId) + + if (index == -1) { + obj.listOnline2.push({ 'id': userId }) + } + + + if (count > (countOnline - 1)) { + + var difference = obj.listOnline.filter((x:any) => !obj.listOnline2.map((e:any) => e.id).includes(x.id)); + + console.log('############> difference: ', difference) + + if (difference.length > 0) { + + difference.forEach(async (x:any) => { + + let index = obj.listOnline.findIndex((e:any) => e.id == x.id) + + if (index != -1) { + obj.listOnline.splice(index, 1) + const onlineUser = await createOrUpdateOnlineUserService({ userId: x.id, status: 'offline' }) + + const onlineUsers = await ListUserOnlineOffline({ date: dateTime.fullDate, status: 'online' }) + + countOnline = onlineUsers.length + } + }) + + } + + obj.listOnline2 = [] + count = 0 + } + + + obj.uuid = uuidv4() + + exports.ob = obj + + count++ + + + + }); socket.on("joinChatBox", (ticketId: string) => { logger.info("A client joined a ticket channel"); @@ -79,7 +137,8 @@ export const getIO = (): SocketIO => { } return io; }; - -exports.listOnlineUsers = listOnlineUsers - + +// exports.listOnlineUsers = listUserId +// exports.listUserId + \ No newline at end of file diff --git a/backend/src/server.ts b/backend/src/server.ts index 6486169..37a78aa 100644 --- a/backend/src/server.ts +++ b/backend/src/server.ts @@ -16,4 +16,4 @@ StartAllWhatsAppsSessions(); gracefulShutdown(server); startSchedulingMonitor(5000) -startWhoIsOnlinegMonitor(3000) +startWhoIsOnlinegMonitor(5000) diff --git a/backend/src/services/UserServices/CreateOrUpdateOnlineUserService.ts b/backend/src/services/UserServices/CreateOrUpdateOnlineUserService.ts index cc3e047..b79f496 100644 --- a/backend/src/services/UserServices/CreateOrUpdateOnlineUserService.ts +++ b/backend/src/services/UserServices/CreateOrUpdateOnlineUserService.ts @@ -39,8 +39,10 @@ const CreateOrUpdateUserOnlineTime = async ({ if(userOnlineTime){ try{ + + let oldStatus = userOnlineTime.status - if(status === 'offline'){ + if(oldStatus=='online' && status === 'offline'){ //updatedAt let newtTime = intervalToDuration({ start: userOnlineTime.updatedAt, end: new Date()}) console.log('TESTANDO INTERVAL DURATION: ', newtTime) @@ -80,9 +82,12 @@ const CreateOrUpdateUserOnlineTime = async ({ await userOnlineTime.update({ status, onlineTime: mySQLDateString }) } - else if(status === 'online'){ + else if(oldStatus=='offline' && status === 'online'){ await userOnlineTime.update({ status }) } + else{ + console.log('NOT UPDATED THE USER: ', userOnlineTime.userId) + } }catch(err){ diff --git a/backend/src/services/UserServices/ListUserParamiterService.ts b/backend/src/services/UserServices/ListUserParamiterService.ts new file mode 100644 index 0000000..70f985a --- /dev/null +++ b/backend/src/services/UserServices/ListUserParamiterService.ts @@ -0,0 +1,54 @@ + +import { Op, Sequelize } from "sequelize"; +import User from "../../models/User"; + +interface Request { + userId?: string | number; + profile?: string; + } + + +const ListUser = async ({profile, userId}: Request): Promise => { + + let where_clause = {} + + if(userId && profile){ + where_clause = { + [Op.and]: [ + {userId: userId}, + {profile: profile} + ] + } + } + else if(userId){ + where_clause = { + [Op.and]: [ + {userId: userId}, + ] + } + } + else if(profile){ + where_clause = { + profile: profile + } + } + + + const users = await User.findAll({ + where: where_clause, + raw:true, + attributes: ['id', 'name', 'email'], + + order: [["id", "ASC"]], + }) + + + return users; +}; + +export default ListUser; + + + + + \ No newline at end of file diff --git a/backend/src/services/UserServices/ListUsersOnlineOfflineService.ts b/backend/src/services/UserServices/ListUsersOnlineOfflineService.ts new file mode 100644 index 0000000..cca0fe0 --- /dev/null +++ b/backend/src/services/UserServices/ListUsersOnlineOfflineService.ts @@ -0,0 +1,72 @@ + +import UserOnlineTime from "../../models/UserOnlineTime"; +import { Op, Sequelize } from "sequelize"; + +interface Request { + userId?: string | number; + status?: string; + date: string; + } + + +const ListUserOnlineOffline = async ({date, userId, status}: Request): Promise => { + + let where_clause = {} + + if(userId && status){ + where_clause = { + [Op.and]: [ + {userId: userId}, + {status: status}, + { + "$createdAt$": Sequelize.where(Sequelize.fn("date", Sequelize.col("createdAt")), `${date}`) + }, + ] + } + } + else if(userId){ + where_clause = { + [Op.and]: [ + {userId: userId}, + { + "$createdAt$": Sequelize.where(Sequelize.fn("date", Sequelize.col("createdAt")), `${date}`) + }, + ] + } + } + else if(status){ + where_clause = { + [Op.and]: [ + {status: status}, + { + "$createdAt$": Sequelize.where(Sequelize.fn("date", Sequelize.col("createdAt")), `${date}`) + }, + ] + } + } + else{ + where_clause = { + [Op.and]: [ + { + "$createdAt$": Sequelize.where(Sequelize.fn("date", Sequelize.col("createdAt")), `${date}`) + }, + ] + } + } + + const users = await UserOnlineTime.findAll({ + where: where_clause, + raw:true, + order: [["id", "ASC"]], + }) + + + return users; +}; + +export default ListUserOnlineOffline; + + + + + \ No newline at end of file diff --git a/backend/src/services/WbotServices/wbotMessageListener.ts b/backend/src/services/WbotServices/wbotMessageListener.ts index 0dc3150..3daacfb 100644 --- a/backend/src/services/WbotServices/wbotMessageListener.ts +++ b/backend/src/services/WbotServices/wbotMessageListener.ts @@ -275,7 +275,7 @@ const verifyQueue = async ( } - console.log('TICKET MESSAGE ON QUEUE CHOICE: ', ticket_message) + //console.log('TICKET MESSAGE ON QUEUE CHOICE: ', ticket_message) // } diff --git a/frontend/src/components/NotificationsPopOver/index.js b/frontend/src/components/NotificationsPopOver/index.js index b1bdbfc..d84c192 100644 --- a/frontend/src/components/NotificationsPopOver/index.js +++ b/frontend/src/components/NotificationsPopOver/index.js @@ -77,10 +77,40 @@ const NotificationsPopOver = () => { ticketIdRef.current = ticketIdUrl; }, [ticketIdUrl]); + + + useEffect(() => { + + const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + + socket.on("isOnline", (data) => { + + // console.log('___________data.userId: ', data.userId) + + if(data.action === "online"){ + + if(data.userId === user.id){ + + socket.emit("online", user.id) + } + + } + + }); + + return () => { + socket.disconnect(); + }; + }, []); + + + + useEffect(() => { const socket = openSocket(process.env.REACT_APP_BACKEND_URL); - socket.on("connect", () => socket.emit("joinNotification")); + socket.on("connect", () => socket.emit("joinNotification")); + socket.on("ticket", data => { if (data.action === "updateUnread" || data.action === "delete") { @@ -114,9 +144,9 @@ const NotificationsPopOver = () => { (data.ticket.userId === user?.id || !data.ticket.userId) ) { - console.log(`data.ticket.userId: ${data.ticket.userId }\n - data.ticket.status: ${data.ticket.status}\n - data.ticket.userId: ${data.ticket.userId }`) + // console.log(`data.ticket.userId: ${data.ticket.userId }\n + // data.ticket.status: ${data.ticket.status}\n + // data.ticket.userId: ${data.ticket.userId }`) setNotifications(prevState => { const ticketIndex = prevState.findIndex(t => t.id === data.ticket.id); diff --git a/frontend/src/components/TicketsList/index.js b/frontend/src/components/TicketsList/index.js index def8de2..3079ee8 100644 --- a/frontend/src/components/TicketsList/index.js +++ b/frontend/src/components/TicketsList/index.js @@ -196,7 +196,8 @@ const reducer = (state, action) => { socket.emit("joinTickets", status); } else { socket.emit("joinNotification"); - } + } + }); socket.on("ticket", data => {