Files
invesa-node/index.js
T
2026-10-29 14:13:06 +07:00

125 lines
5.3 KiB
JavaScript

const express = require('express');
const { createServer } = require('node:http');
const { join } = require('node:path');
const { Server } = require('socket.io');
const mysql = require('mysql2/promise');
const dotenv = require('@dotenvx/dotenvx');
const { PoolConnection } = require('mysql2');
const app = express();
const server = createServer(app);
const io = new Server(server, { 'path': '/io' });
dotenv.config();
const db = mysql.createPool({
host: process.env.DB_HOST || '127.0.0.1',
user: process.env.DB_USER || 'mariadb',
password: process.env.DB_PASSWORD || '',
database: process.env.DB_NAME || '',
port: process.env.DB_PORT || 3306,
});
const app_port = process.env.APP_PORT || 3000;
io.on('connection', (socket) => {
let pollPPOB = null;
let pollSuper = null;
let pollMonitor = null;
// get ip address
const forwardedIp = socket.handshake.headers["x-forwarded-for"];
//const cloudflareIp = socket.handshake.headers["cf-connecting-ip"];
const clientIp = forwardedIp ? forwardedIp.split(',')[0] : socket.handshake.address;
//console.log("Real Client IP:", clientIp);
// PPOB
socket.on('ppob-check', (ajson) => {
if (!ajson || typeof ajson !== 'object') return socket.emit('ppob-error', { 'message': 'Invalid payload format' });
const { CabID, UserID } = ajson;
if (!CabID || !UserID) return socket.emit('ppob-error', { 'message': 'Missing required CabID and UserID' });
if (pollPPOB) clearInterval(pollPPOB);
pollPPOB = setInterval(async () => {
try {
const [rows, fields] = await db.query("SELECT No_TX,Status FROM ppob_tx WHERE No_TX IN (SELECT No_TX FROM ppob_pend WHERE CabID=? AND UserID=?)", [ CabID, UserID ]);
socket.emit('ppob-data', { 'prabayar': rows });
} catch (error) {
console.error("db query failed :", error);
}
}, 1500);
});
socket.on('ppob-update', (ajson) => {
if (!ajson || typeof ajson !== 'object') return socket.emit('ppob-error', { 'message': 'Invalid payload format' });
const { CabID, UserID } = ajson;
if (!CabID || !UserID) return socket.emit('ppob-error', { 'message': 'Missing required CabID and UserID' });
try {
db.execute("DELETE FROM ppob_pend WHERE Status=4 AND CabID=? AND UserID=?", [ CabID, UserID ]);
} catch (error) {
console.error("db execute failed :", error);
}
});
socket.on('ppob-done', () => {
if (pollPPOB) clearInterval(pollPPOB);
pollPPOB = null;
});
// SUPERVISI
socket.on('super-check', (ajson) => {
if (pollSuper) return;
pollSuper = setInterval(async () => {
try {
const [rows, fields] = await db.query({sql: "SELECT A.AuthID,O.Nama Nama_User,A.Tanggal,M.Judul,A.Catatan,A.REQ,'<a class=\"table-icon unlock2\" title=\"Proses\"><i class=\"bi-unlock2\"></i></a>' Aksi FROM (SELECT AuthID,UserID,Kode,DATE_FORMAT(Tanggal,'%d-%m-%Y %H:%i:%s') Tanggal,REQ,Catatan FROM app_auth WHERE Auth=0) A LEFT JOIN app_operator O ON (A.UserID=O.UserID) LEFT JOIN app_menu M ON (A.Kode=M.Kode)", rowsAsArray: true});
socket.emit('super-data', { 'data': rows });
} catch (error) {
console.error("db query failed :", error);
}
}, 1500);
});
socket.on('super-done', () => {
if (pollSuper) clearInterval(pollSuper);
pollSuper = null;
});
// MONITOR
socket.on('monitor-check', (ajson) => {
if (!ajson || typeof ajson !== 'object') return socket.emit('monitor-error', { 'message': 'Invalid payload format' });
const { CabID, UserID } = ajson;
if (pollMonitor) return;
pollMonitor = setInterval(async () => {
try {
const adata = { 'total': 0, 'thank': 0 };
const [row_pos, fields_pos] = await db.query("SELECT * FROM disp_login WHERE CabID=? AND IP=? ORDER BY Date DESC", [ CabID, clientIp ]);
if (row_pos.length) {
const [row_total, fields_total] = await db.query("SELECT SUM(-Qty*(Harga_Jual-Disk_Rupiah)) Total FROM tmp_inv_detail WHERE No_Ref=? AND Unix=?", [ row_pos[0].No_Pos, row_pos[0].Unix ]);
const [row_thank, fields_thank] = await db.query("SELECT IF(No_Cetak='',0,1) Ada FROM disp_login WHERE CabID=? AND UserID=? AND Unix=?", [ CabID, row_pos[0].UserID, row_pos[0].Unix ]);
if (row_total.length) adata.total = row_total[0].Total || 0;
if (row_thank.length) adata.thank = row_thank[0].Ada || 0;
}
socket.emit('monitor-data', { 'data': adata });
} catch (error) {
console.error("db query failed :", error);
}
}, 1500);
});
socket.on('monitor-done', () => {
if (pollMonitor) clearInterval(pollMonitor);
pollMonitor = null;
});
// DISCONNECT
socket.on('disconnect', () => {
if (pollPPOB) clearInterval(pollPPOB);
if (pollSuper) clearInterval(pollSuper);
if (pollMonitor) clearInterval(pollMonitor);
});
});
app.get('/', (req, res) => {
res.sendFile(join(__dirname, 'public', 'index.html'));
});
app.use(express.static('public'));
server.listen(app_port, () => {
console.log('Server running at http://localhost:' + app_port);
});