From 46c911919509cdd2b6260bf2b0962e67eca7ad84 Mon Sep 17 00:00:00 2001 From: adriano Date: Sun, 28 Aug 2022 22:09:00 -0300 Subject: [PATCH] =?UTF-8?q?Cria=C3=A7=C3=A3o=20do=20broker=20para=20otimiz?= =?UTF-8?q?a=C3=A7=C3=A3o=20do=20csv=20export=20all=20finalizada!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/controllers/ReportController.ts | 96 ++++----- backend/src/database/index.ts | 6 +- backend/src/models/User.ts | 8 +- backend/src/routes/reportRoutes.ts | 2 + frontend/package.json | 4 +- frontend/src/pages/Report/index.js | 216 +++++++++++++++----- frontend/src/services/apiBroker.js | 10 + 7 files changed, 220 insertions(+), 122 deletions(-) create mode 100644 frontend/src/services/apiBroker.js diff --git a/backend/src/controllers/ReportController.ts b/backend/src/controllers/ReportController.ts index d67833f..6baa17f 100644 --- a/backend/src/controllers/ReportController.ts +++ b/backend/src/controllers/ReportController.ts @@ -22,9 +22,11 @@ import ShowUserServiceReport from "../services/UserServices/ShowUserServiceRepor import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue"; import ShowQueuesByUser from "../services/UserServices/ShowQueuesByUser"; -import { filter } from "bluebird"; + +// import { filter } from "bluebird"; +import { getIO } from "../libs/socket"; type IndexQuery = { userId: string; @@ -33,6 +35,11 @@ type IndexQuery = { pageNumber: string; }; +type ReportOnQueue = { + userId: string; + identifier: string; +} + export const reportUserByDateStartDateEnd = async (req: Request, res: Response): Promise => { @@ -42,14 +49,8 @@ export const reportUserByDateStartDateEnd = async (req: Request, res: Response): const { userId, startDate, endDate, pageNumber } = req.query as IndexQuery - - console.log('PAGE NUMBER: ', pageNumber) - - const { tickets, count, hasMore } = await ShowTicketReport({ userId, startDate, endDate, pageNumber }); - // return res.status(200).json(data_query); - return res.status(200).json({ tickets, count, hasMore }); }; @@ -87,7 +88,7 @@ export const reportUserService = async (req: Request, res: Response): Promise { @@ -141,33 +128,6 @@ export const reportUserService = async (req: Request, res: Response): Promise e.userId == user.id && !e.queueName) - // let openByUserIn = openQueueInOut.filter((e: any) => e.userId == user.id && e.queueName) - - // if (openByUserOut && openByUserOut.length > 0) { - // user.openTicketByUserOut = openByUserOut - // } - // if (openByUserIn && openByUserIn.length > 0) { - // user.openTicketByUserIn = openByUserIn - // } - - // let closedByUserOut = closedQueueInOut.filter((e: any) => e.userId == user.id && !e.queueName) - // let closedByUserIn = closedQueueInOut.filter((e: any) => e.userId == user.id && e.queueName) - - // if (closedByUserOut && closedByUserOut.length > 0) { - // user.closedTicketByUserOut = closedByUserOut - // } - // if (closedByUserIn && closedByUserIn.length > 0) { - // user.closedTicketByUserIn = closedByUserIn - // } - - - - - // OPEN, CLOSED TICKETS STARTED BY USERS let openClosedOutQueue = {} let open = openCloseOutQueue.filter((e) => e.userId == user.id && e.status == 'open') @@ -187,16 +147,10 @@ export const reportUserService = async (req: Request, res: Response): Promise e.userId == user.id) if (openClosedInQueue && openClosedInQueue.length > 0) { - user.openClosedInQueue = openClosedInQueue + user.openClosedInQueue = openClosedInQueue } - - - - - - index = onlineUsers.findIndex((e: any) => e.userId == user.id) if (index != -1) { @@ -229,9 +183,9 @@ export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Re const { userId, startDate, endDate } = req.query as IndexQuery - let data_query_messages = await ShowMessageReport(userId, startDate, endDate); + let data_query_messages = await ShowMessageReport(userId, startDate, endDate); - for (var i = 0; i < data_query_messages.length; i++) { + for (var i = 0; i < data_query_messages.length; i++) { if (data_query_messages[i].fromMe) { data_query_messages[i].fromMe = 'Atendente' @@ -240,7 +194,7 @@ export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Re data_query_messages[i].fromMe = 'Cliente' } - data_query_messages[i].id = (i+1) + data_query_messages[i].id = (i + 1) console.log('data_query_messages: ', data_query_messages[i]) } @@ -251,5 +205,27 @@ export const reportMessagesUserByDateStartDateEnd = async (req: Request, res: Re +export const reportOnQueue = async (req: Request, res: Response): Promise => { + + // console.log(req.body) + + const { adminId, identifier, queueStatus, file } = req.body + + const io = getIO(); + io.emit("queryOnQueueStatus", { + action: "update", + queryOnQueue: { + adminId: adminId, + identifier: identifier, + queueStatus: queueStatus, + file: file + } + }); + + return res.status(200).json({ message: 'ok' }) +}; + + + diff --git a/backend/src/database/index.ts b/backend/src/database/index.ts index 6d2e8ca..9749831 100644 --- a/backend/src/database/index.ts +++ b/backend/src/database/index.ts @@ -13,9 +13,7 @@ import QuickAnswer from "../models/QuickAnswer"; import SchedulingNotify from "../models/SchedulingNotify"; import StatusChatEnd from "../models/StatusChatEnd"; -import UserOnlineTime from "../models/UserOnlineTime"; - - +import UserOnlineTime from "../models/UserOnlineTime"; // eslint-disable-next-line const dbConfig = require("../config/database"); // import dbConfig from "../config/database"; @@ -37,7 +35,7 @@ const models = [ SchedulingNotify, StatusChatEnd, - UserOnlineTime, + UserOnlineTime, ]; sequelize.addModels(models); diff --git a/backend/src/models/User.ts b/backend/src/models/User.ts index 571d4af..63ab78f 100644 --- a/backend/src/models/User.ts +++ b/backend/src/models/User.ts @@ -17,7 +17,7 @@ import { hash, compare } from "bcryptjs"; import Ticket from "./Ticket"; import Queue from "./Queue"; import UserQueue from "./UserQueue"; -import UserOnlineTime from "./UserOnlineTime"; +import UserOnlineTime from "./UserOnlineTime"; @Table class User extends Model { @@ -54,11 +54,9 @@ class User extends Model { @HasMany(() => Ticket) tickets: Ticket[]; - - //test del + @HasMany(() => UserOnlineTime) - UserOnlineTime: UserOnlineTime[]; - // + UserOnlineTime: UserOnlineTime[]; @BelongsToMany(() => Queue, () => UserQueue) queues: Queue[]; diff --git a/backend/src/routes/reportRoutes.ts b/backend/src/routes/reportRoutes.ts index 857a6ba..0c84aba 100644 --- a/backend/src/routes/reportRoutes.ts +++ b/backend/src/routes/reportRoutes.ts @@ -9,6 +9,8 @@ const reportRoutes = express.Router(); reportRoutes.get("/reports", isAuth, ReportController.reportUserByDateStartDateEnd); +reportRoutes.post("/reports/onqueue", ReportController.reportOnQueue); + reportRoutes.get("/reports/user/services", isAuth, ReportController.reportUserService); reportRoutes.get("/reports/messages", isAuth, ReportController.reportMessagesUserByDateStartDateEnd); diff --git a/frontend/package.json b/frontend/package.json index 80e12d7..a077e60 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -5,7 +5,7 @@ "dependencies": { "@date-io/date-fns": "^1.3.13", "@emotion/react": "^11.7.1", - "@emotion/styled": "^11.6.0", + "@emotion/styled": "^11.6.0", "@material-ui/core": "^4.12.1", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.56", @@ -17,10 +17,12 @@ "@testing-library/user-event": "^12.1.7", "axios": "^0.21.1", "date-fns": "^2.28.0", + "dotenv": "^16.0.1", "emoji-mart": "^3.0.1", "formik": "^2.2.0", "i18next": "^19.8.2", "i18next-browser-languagedetector": "^6.0.1", + "js-file-download": "^0.4.12", "markdown-to-jsx": "^7.1.0", "material-table": "^1.69.3", "mic-recorder-to-mp3": "^2.2.2", diff --git a/frontend/src/pages/Report/index.js b/frontend/src/pages/Report/index.js index c3cc642..8a3d620 100644 --- a/frontend/src/pages/Report/index.js +++ b/frontend/src/pages/Report/index.js @@ -18,13 +18,18 @@ import MaterialTable from 'material-table'; import LogoutIcon from '@material-ui/icons/CancelOutlined'; +import apiBroker from "../../services/apiBroker"; +import fileDownload from 'js-file-download' +import fs from 'fs' + import { CSVLink } from "react-csv"; // import CircularProgress from '@mui/material/CircularProgress'; import openSocket from "socket.io-client"; +import { set } from "date-fns"; const report = [{ 'value': '1', 'label': 'Atendimento por atendentes' }, { 'value': '2', 'label': 'Usuários online/offline' }] @@ -96,9 +101,6 @@ let columns = [ const reducerQ = (state, action) => { - - - if (action.type === "DELETE_USER_STATUS") { const userId = action.payload; @@ -339,6 +341,9 @@ const Report = () => { const [profile, setProfile] = useState('') const [dataRows, setData] = useState([]); + const [onQueueStatus, setOnQueueProcessStatus] = useState(undefined) + const [csvFile, setCsvFile] = useState() + @@ -477,32 +482,103 @@ const Report = () => { }, [reportOption]) + + useEffect(() => { + + const delayDebounceFn = setTimeout(() => { + + const fetchReportOnQueue = async () => { + try { + + const queryOnQueue = await apiBroker.get("/reports/status/query/onqueue", { + params: { + adminId: userA.id, + baseURL: process.env.REACT_APP_BACKEND_URL, + identifier: 'csv' + } + }); + + + if (queryOnQueue.data) { + setCsvFile(queryOnQueue.data.app.file) + setOnQueueProcessStatus(queryOnQueue.data.app.status) + } + else { + setOnQueueProcessStatus('empty') + } + + console.log('>>>>> queryOnqueue: ', queryOnQueue.data) + + + + } catch (err) { + console.log(err); + } + }; + + fetchReportOnQueue(); + + }, 500); + return () => clearTimeout(delayDebounceFn); + + }, []) + + + const handleCSVDownload = async () => { + + try { + + let res = await apiBroker.get(`/reports/download/${csvFile}`, { responseType: 'blob' }); + + if (res) { + fileDownload(res.data, `${csvFile}`); + + setOnQueueProcessStatus('empty') + } + + } catch (err) { + console.log(err); + } + + } + + const handleCSVMessages = () => { const fetchQueries = async () => { try { - const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, }); + // const dataQuery = await api.get("/reports/messages", { params: { userId, startDate, endDate }, }); - console.log('dataQuery messages: ', dataQuery.data) - - if (dataQuery.data.length > 0) { - - let dataCSVFormat = dataQuery.data; - - for (var i = 0; i < dataCSVFormat.length; i++) { - if (dataCSVFormat[i].fromMe) { - dataCSVFormat[i].fromMe = 'Atendente' + const querySavedOnQueue = await apiBroker.post("/reports/messages", + { + app: { + adminId: userA.id, + baseURL: process.env.REACT_APP_BACKEND_URL, + frontURL: process.env.REACT_APP_FRONTEND_URL, + identifier: 'csv' + }, + query_params: { + userId: userId, + startDate: startDate, + endDate: endDate } - else { - dataCSVFormat[i].fromMe = 'Cliente' - } - } + }); - setDataCSV(dataCSVFormat) - setIsMount(false); - } + console.log('dataQuery messages: ', querySavedOnQueue.data.queueStatus) + + const onQueueStatus = querySavedOnQueue.data.queueStatus + + setOnQueueProcessStatus(onQueueStatus) + + // if (onQueueStatus.data.length > 0) { + + // let dataCSVFormat = queueStatus.data; + + + // setIsMount(false); + // } } catch (err) { console.log(err); @@ -532,9 +608,24 @@ const Report = () => { useEffect(() => { + const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + + socket.on("queryOnQueueStatus", (data) => { + if (data.action === 'update') { + + if (String(data.queryOnQueue.adminId) === String(userA.id)) { + + setCsvFile(data.queryOnQueue.file) + setOnQueueProcessStatus(data.queryOnQueue.queueStatus) + + } + + } + }) + if (reportOption === '2') { - const socket = openSocket(process.env.REACT_APP_BACKEND_URL); + // const socket = openSocket(process.env.REACT_APP_BACKEND_URL); socket.on("onlineStatus", (data) => { @@ -563,9 +654,10 @@ const Report = () => { } }); - return () => { - socket.disconnect(); - }; + + // return () => { + // socket.disconnect(); + // }; } else if (reportOption === "1") { @@ -573,6 +665,10 @@ const Report = () => { setTicketsPageNumber(1) } + return () => { + socket.disconnect(); + }; + }, [reportOption, startDate, endDate, userId]); @@ -641,6 +737,48 @@ const Report = () => { }; + const renderSwitch = (param) => { + switch (param) { + case 'empty': + return ( + <> + + ); + + case 'pending' || 'processing': + return ( + <> + PROCESSING... + ); + + case 'success': + return ( + <> + + ); + + default: + return (<>WAITING...); + } + } + + return ( {
- {reportOption === '1' && - + {reportOption === '1' &&
- {/* */} - -
- -
+ {renderSwitch(onQueueStatus)}
} diff --git a/frontend/src/services/apiBroker.js b/frontend/src/services/apiBroker.js new file mode 100644 index 0000000..e484407 --- /dev/null +++ b/frontend/src/services/apiBroker.js @@ -0,0 +1,10 @@ +import axios from "axios"; + +const apiBroker = axios.create({ + baseURL: process.env.REACT_APP_URL_API_BROKER, + headers: { + Authorization: `Bearer ${process.env.REACT_APP_API_BROKER_TOKEN}` + } +}); + +export default apiBroker;