nodebb-plugin-niki-loyalty 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/library.js +15 -90
- package/package.json +1 -1
- package/static/widgets/niki-kasa-debug.html +1020 -0
- package/static/widgets/niki-kasa-isolated.html +419 -0
- package/static/widgets/niki-kasa-simple.html +623 -0
- package/static/widgets/niki-kasa-widget.html +506 -0
- package/templates/niki-kasa.tpl +54 -409
package/library.js
CHANGED
|
@@ -319,112 +319,37 @@ Plugin.init = async function (params) {
|
|
|
319
319
|
}
|
|
320
320
|
});
|
|
321
321
|
|
|
322
|
-
// 3) KASA HISTORY -
|
|
322
|
+
// 3) KASA HISTORY - BASİT VERSİYON
|
|
323
323
|
router.get('/api/niki-loyalty/kasa-history', middleware.ensureLoggedIn, async (req, res) => {
|
|
324
324
|
try {
|
|
325
325
|
const isAdmin = await user.isAdministrator(req.uid);
|
|
326
326
|
const isMod = await user.isGlobalModerator(req.uid);
|
|
327
|
-
if (!isAdmin && !isMod) return res.status(403).json(
|
|
328
|
-
|
|
329
|
-
// Query parametreleri
|
|
330
|
-
const { startDate, endDate, search, rewardType, exportAll } = req.query;
|
|
327
|
+
if (!isAdmin && !isMod) return res.status(403).json([]);
|
|
331
328
|
|
|
332
329
|
const raw = await db.getListRange('niki:kasa:history', 0, -1);
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// Personel bilgilerini de al
|
|
336
|
-
const staffUids = [...new Set(rows.map(r => parseInt(r.staff, 10)).filter(n => Number.isFinite(n) && n > 0))];
|
|
337
|
-
const custUids = rows.map(r => parseInt(r.cuid, 10)).filter(n => Number.isFinite(n) && n > 0);
|
|
338
|
-
const allUids = [...new Set([...staffUids, ...custUids])];
|
|
330
|
+
const rows = (raw || []).map(safeParseMaybeJson).filter(Boolean).reverse();
|
|
339
331
|
|
|
340
|
-
const
|
|
332
|
+
const uids = rows.map(r => parseInt(r.cuid, 10)).filter(n => Number.isFinite(n) && n > 0);
|
|
333
|
+
const users = await user.getUsersFields(uids, ['uid', 'username', 'userslug', 'picture', 'icon:bgColor']);
|
|
341
334
|
const userMap = {};
|
|
342
|
-
(
|
|
335
|
+
(users || []).forEach(u => userMap[u.uid] = u);
|
|
343
336
|
|
|
344
337
|
const rp = nconf.get('relative_path') || '';
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
let enriched = rows.map(r => {
|
|
348
|
-
const custUser = userMap[r.cuid] || {};
|
|
349
|
-
const staffUser = userMap[r.staff] || {};
|
|
338
|
+
const enriched = rows.map(r => {
|
|
339
|
+
const u = userMap[r.cuid] || {};
|
|
350
340
|
return {
|
|
351
341
|
...r,
|
|
352
|
-
cust:
|
|
353
|
-
picture:
|
|
354
|
-
iconBg:
|
|
355
|
-
profileUrl:
|
|
356
|
-
reward: r.reward || 'İşlem'
|
|
357
|
-
staffName: staffUser.username || 'Personel',
|
|
358
|
-
staffPicture: staffUser.picture || '',
|
|
359
|
-
date: new Date(r.ts).toISOString().slice(0, 10) // YYYY-MM-DD
|
|
342
|
+
cust: u.username || r.cust || 'Bilinmeyen',
|
|
343
|
+
picture: u.picture || '',
|
|
344
|
+
iconBg: u['icon:bgColor'] || '#4b5563',
|
|
345
|
+
profileUrl: u.userslug ? `${rp}/user/${u.userslug}` : '',
|
|
346
|
+
reward: r.reward || 'İşlem'
|
|
360
347
|
};
|
|
361
348
|
});
|
|
362
|
-
|
|
363
|
-
// FİLTRELEME
|
|
364
|
-
// 1. Tarih aralığı
|
|
365
|
-
if (startDate) {
|
|
366
|
-
const start = new Date(startDate).getTime();
|
|
367
|
-
enriched = enriched.filter(r => r.ts >= start);
|
|
368
|
-
}
|
|
369
|
-
if (endDate) {
|
|
370
|
-
const end = new Date(endDate).getTime() + 86400000; // gün sonu
|
|
371
|
-
enriched = enriched.filter(r => r.ts < end);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
// 2. Arama (kullanıcı adı)
|
|
375
|
-
if (search && search.trim()) {
|
|
376
|
-
const q = search.toLowerCase().trim();
|
|
377
|
-
enriched = enriched.filter(r =>
|
|
378
|
-
(r.cust && r.cust.toLowerCase().includes(q)) ||
|
|
379
|
-
(r.staffName && r.staffName.toLowerCase().includes(q))
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// 3. Ödül tipi
|
|
384
|
-
if (rewardType && rewardType !== 'all') {
|
|
385
|
-
enriched = enriched.filter(r => r.reward === rewardType);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
// İSTATİSTİKLER
|
|
389
|
-
const stats = {
|
|
390
|
-
totalTransactions: enriched.length,
|
|
391
|
-
totalPoints: enriched.reduce((sum, r) => sum + (parseFloat(r.amt) || 0), 0),
|
|
392
|
-
byReward: {},
|
|
393
|
-
byStaff: {},
|
|
394
|
-
byDate: {}
|
|
395
|
-
};
|
|
396
|
-
|
|
397
|
-
enriched.forEach(r => {
|
|
398
|
-
// Ödül bazında
|
|
399
|
-
stats.byReward[r.reward] = (stats.byReward[r.reward] || 0) + 1;
|
|
400
|
-
// Personel bazında
|
|
401
|
-
stats.byStaff[r.staffName] = (stats.byStaff[r.staffName] || 0) + 1;
|
|
402
|
-
// Gün bazında (son 7 gün için chart)
|
|
403
|
-
stats.byDate[r.date] = (stats.byDate[r.date] || 0) + 1;
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
// Benzersiz ödül tipleri (filter dropdown için)
|
|
407
|
-
const rewardTypes = [...new Set(rows.map(r => r.reward || 'İşlem'))];
|
|
408
|
-
|
|
409
|
-
// Export all için sayfalama yok
|
|
410
|
-
if (exportAll === 'true') {
|
|
411
|
-
return res.json({
|
|
412
|
-
data: enriched,
|
|
413
|
-
stats,
|
|
414
|
-
rewardTypes
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
// Normal görünüm (son 100 işlem)
|
|
419
|
-
return res.json({
|
|
420
|
-
data: enriched.slice(0, 100),
|
|
421
|
-
stats,
|
|
422
|
-
rewardTypes,
|
|
423
|
-
hasMore: enriched.length > 100
|
|
424
|
-
});
|
|
349
|
+
return res.json(enriched);
|
|
425
350
|
} catch (e) {
|
|
426
351
|
console.error('[Niki-Loyalty] Kasa history error:', e);
|
|
427
|
-
return res.status(500).json(
|
|
352
|
+
return res.status(500).json([]);
|
|
428
353
|
}
|
|
429
354
|
});
|
|
430
355
|
|