nodebb-plugin-niki-loyalty 1.0.10 → 1.0.11
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 +52 -36
- package/package.json +1 -1
package/library.js
CHANGED
|
@@ -12,18 +12,25 @@ const SETTINGS = {
|
|
|
12
12
|
coffeeCost: 250
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
// --- YARDIMCI:
|
|
16
|
-
async function
|
|
15
|
+
// --- YARDIMCI: KASA GÜNLÜĞÜNE EKLE ---
|
|
16
|
+
async function addKasaLog(staffUid, customerName, customerPicture) {
|
|
17
17
|
const logEntry = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
ts: Date.now(),
|
|
19
|
+
staff: staffUid, // İşlemi yapan personel ID'si
|
|
20
|
+
cust: customerName,
|
|
21
|
+
img: customerPicture,
|
|
22
|
+
amt: SETTINGS.coffeeCost
|
|
22
23
|
};
|
|
23
|
-
//
|
|
24
|
+
// Kasa geçmişine ekle (Sonuna ekler)
|
|
25
|
+
await db.listAppend('niki:kasa:history', logEntry);
|
|
26
|
+
// Son 100 işlemi tut, gerisini sil (Veritabanı temizliği)
|
|
27
|
+
await db.listTrim('niki:kasa:history', -100, -1);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// --- YARDIMCI: ÖĞRENCİ GÜNLÜĞÜNE EKLE ---
|
|
31
|
+
async function addUserLog(uid, type, amount, desc) {
|
|
32
|
+
const logEntry = { timestamp: Date.now(), type: type, amount: amount, desc: desc };
|
|
24
33
|
await db.listAppend(`niki:activity:${uid}`, logEntry);
|
|
25
|
-
|
|
26
|
-
// Son 50 işlemi tut, gerisini sil (Veritabanı şişmesin)
|
|
27
34
|
await db.listTrim(`niki:activity:${uid}`, -50, -1);
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -31,7 +38,7 @@ Plugin.init = async function (params) {
|
|
|
31
38
|
const router = params.router;
|
|
32
39
|
const middleware = params.middleware;
|
|
33
40
|
|
|
34
|
-
// 1. HEARTBEAT (Puan Kazanma
|
|
41
|
+
// 1. HEARTBEAT (Puan Kazanma)
|
|
35
42
|
router.post('/api/niki-loyalty/heartbeat', middleware.ensureLoggedIn, async (req, res) => {
|
|
36
43
|
const uid = req.uid;
|
|
37
44
|
const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
|
|
@@ -45,16 +52,12 @@ Plugin.init = async function (params) {
|
|
|
45
52
|
|
|
46
53
|
await user.incrementUserFieldBy(uid, 'niki_points', SETTINGS.pointsPerHeartbeat);
|
|
47
54
|
await db.incrObjectFieldBy(dailyKey, 'score', SETTINGS.pointsPerHeartbeat);
|
|
48
|
-
|
|
49
|
-
// LOG EKLEME (Her 5 puan için log şişirmemek adına, sadece veritabanına sessizce işleyelim)
|
|
50
|
-
// Ancak kullanıcı her saniye log görmesin diye buraya eklemiyoruz.
|
|
51
|
-
// İstersen "Ders Çalışma Oturumu" bittiğinde toplu ekleyebiliriz ama şimdilik basit tutalım.
|
|
52
|
-
|
|
55
|
+
|
|
53
56
|
const newBalance = await user.getUserField(uid, 'niki_points');
|
|
54
57
|
return res.json({ earned: true, points: SETTINGS.pointsPerHeartbeat, total: newBalance });
|
|
55
58
|
});
|
|
56
59
|
|
|
57
|
-
// 2. WALLET DATA
|
|
60
|
+
// 2. WALLET DATA (Öğrenci Cüzdanı)
|
|
58
61
|
router.get('/api/niki-loyalty/wallet-data', middleware.ensureLoggedIn, async (req, res) => {
|
|
59
62
|
const uid = req.uid;
|
|
60
63
|
const today = new Date().toISOString().slice(0, 10).replace(/-/g, '');
|
|
@@ -62,12 +65,9 @@ Plugin.init = async function (params) {
|
|
|
62
65
|
const [userData, dailyData, history] = await Promise.all([
|
|
63
66
|
user.getUserFields(uid, ['niki_points']),
|
|
64
67
|
db.getObject(`niki:daily:${uid}:${today}`),
|
|
65
|
-
db.getListRange(`niki:activity:${uid}`, 0, -1)
|
|
68
|
+
db.getListRange(`niki:activity:${uid}`, 0, -1)
|
|
66
69
|
]);
|
|
67
70
|
|
|
68
|
-
// Geçmişi ters çevir (En yeni en üstte)
|
|
69
|
-
const recentActivity = (history || []).reverse();
|
|
70
|
-
|
|
71
71
|
const currentPoints = parseInt(userData.niki_points) || 0;
|
|
72
72
|
const dailyScore = parseInt(dailyData ? dailyData.score : 0) || 0;
|
|
73
73
|
let dailyPercent = (dailyScore / SETTINGS.dailyCap) * 100;
|
|
@@ -78,7 +78,7 @@ Plugin.init = async function (params) {
|
|
|
78
78
|
dailyScore: dailyScore,
|
|
79
79
|
dailyCap: SETTINGS.dailyCap,
|
|
80
80
|
dailyPercent: dailyPercent,
|
|
81
|
-
history:
|
|
81
|
+
history: (history || []).reverse()
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
84
|
|
|
@@ -86,7 +86,6 @@ Plugin.init = async function (params) {
|
|
|
86
86
|
router.post('/api/niki-loyalty/generate-qr', middleware.ensureLoggedIn, async (req, res) => {
|
|
87
87
|
const uid = req.uid;
|
|
88
88
|
const points = parseInt(await user.getUserField(uid, 'niki_points')) || 0;
|
|
89
|
-
|
|
90
89
|
if (points < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Yetersiz Puan' });
|
|
91
90
|
|
|
92
91
|
const token = Math.random().toString(36).substring(2) + Date.now().toString(36);
|
|
@@ -96,40 +95,57 @@ Plugin.init = async function (params) {
|
|
|
96
95
|
return res.json({ success: true, token: token });
|
|
97
96
|
});
|
|
98
97
|
|
|
99
|
-
// 4. QR OKUTMA (
|
|
98
|
+
// 4. QR OKUTMA (KASA İŞLEMİ)
|
|
100
99
|
router.post('/api/niki-loyalty/scan-qr', middleware.ensureLoggedIn, async (req, res) => {
|
|
101
100
|
const { token } = req.body;
|
|
102
101
|
|
|
102
|
+
// Yetki Kontrolü
|
|
103
103
|
const isAdmin = await user.isAdministrator(req.uid);
|
|
104
104
|
const isMod = await user.isGlobalModerator(req.uid);
|
|
105
105
|
if (!isAdmin && !isMod) return res.status(403).json({ success: false, message: 'Yetkisiz' });
|
|
106
106
|
|
|
107
|
+
// Token Doğrula
|
|
107
108
|
const customerUid = await db.get(`niki:qr:${token}`);
|
|
108
|
-
if (!customerUid) return res.json({ success: false, message: 'Geçersiz Kod' });
|
|
109
|
+
if (!customerUid) return res.json({ success: false, message: 'Geçersiz/Süresi Dolmuş Kod' });
|
|
109
110
|
|
|
111
|
+
// Puan Kontrolü
|
|
110
112
|
const pts = parseInt(await user.getUserField(customerUid, 'niki_points')) || 0;
|
|
111
|
-
if (pts < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Bakiye
|
|
113
|
+
if (pts < SETTINGS.coffeeCost) return res.json({ success: false, message: 'Yetersiz Bakiye' });
|
|
112
114
|
|
|
113
|
-
//
|
|
115
|
+
// İŞLEMİ YAP
|
|
114
116
|
await user.decrementUserFieldBy(customerUid, 'niki_points', SETTINGS.coffeeCost);
|
|
115
117
|
await db.delete(`niki:qr:${token}`);
|
|
116
118
|
|
|
117
|
-
//
|
|
118
|
-
await addLog(customerUid, 'spend', SETTINGS.coffeeCost, 'Kahve Harcaması');
|
|
119
|
-
|
|
119
|
+
// LOGLARI GİR
|
|
120
120
|
const customerData = await user.getUserFields(customerUid, ['username', 'picture']);
|
|
121
|
+
|
|
122
|
+
// 1. Öğrencinin Geçmişine Ekle
|
|
123
|
+
await addUserLog(customerUid, 'spend', SETTINGS.coffeeCost, 'Kahve Harcaması');
|
|
124
|
+
|
|
125
|
+
// 2. Kasa Defterine Ekle (YENİ)
|
|
126
|
+
await addKasaLog(req.uid, customerData.username, customerData.picture);
|
|
127
|
+
|
|
121
128
|
return res.json({ success: true, customer: customerData, message: 'Onaylandı!' });
|
|
122
129
|
});
|
|
123
130
|
|
|
124
|
-
//
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
// 5. KASA GEÇMİŞİNİ GETİR (YENİ API)
|
|
132
|
+
router.get('/api/niki-loyalty/kasa-history', middleware.ensureLoggedIn, async (req, res) => {
|
|
133
|
+
const isAdmin = await user.isAdministrator(req.uid);
|
|
134
|
+
const isMod = await user.isGlobalModerator(req.uid);
|
|
135
|
+
if (!isAdmin && !isMod) return res.status(403).json([]);
|
|
136
|
+
|
|
137
|
+
// Tüm geçmişi çek
|
|
138
|
+
const history = await db.getListRange('niki:kasa:history', 0, -1);
|
|
139
|
+
|
|
140
|
+
// Ters çevir (En yeni en üstte)
|
|
141
|
+
res.json((history || []).reverse());
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// SAYFA ROUTE
|
|
130
145
|
routeHelpers.setupPageRoute(router, '/niki-kasa', middleware, [], async (req, res) => {
|
|
131
146
|
const isAdmin = await user.isAdministrator(req.uid);
|
|
132
|
-
|
|
147
|
+
const isMod = await user.isGlobalModerator(req.uid);
|
|
148
|
+
if (!isAdmin && !isMod) return res.render('403', {});
|
|
133
149
|
res.render('niki-kasa', { title: 'Niki Kasa' });
|
|
134
150
|
});
|
|
135
151
|
};
|