diff --git a/Database.js b/Database.js index 1e2f6e7..ec21f81 100644 --- a/Database.js +++ b/Database.js @@ -5,125 +5,73 @@ class Database { this.pool = new pg.Pool({connectionString: connectionStr}); } - async registerQRTeam(name, owner) { + async checkAndRegisterUser(id, name) { let client = await this.pool.connect(); try { - await client.query('BEGIN'); - await client.query('INSERT INTO qr_team (team_name, owner_id) values ($1,$2)', [name, owner]); - await client.query('COMMIT'); + let result = await client.query("SELECT * FROM qr_users WHERE user_id = $1", [id]); + if (result.rowCount === 0) { + await client.query("INSERT INTO qr_users (user_id, name) VALUES ($1, $2)", [id, name]); + } } finally { client.release(); } } - /** - * - * @param code - * @returns {Promise} - */ - async getQRTask(code) { + async codeExists(code) { let client = await this.pool.connect(); - let task = null; try { - await client.query('BEGIN'); - let res = await client.query('SELECT * FROM qr_tasks WHERE code = $1', [code]); - await client.query('COMMIT'); - task = res.rows[0]; + let result = await client.query("SELECT * FROM qr_codes WHERE id = $1", [code]); + return result.rowCount === 1; } finally { client.release(); } - return task; } - async getTask(id) { - if(id === 0) return {short_name: "Начало"} + async useCode(code, user) { let client = await this.pool.connect(); - let task = null; try { - await client.query('BEGIN'); - let res = await client.query('SELECT * FROM qr_tasks WHERE id = $1', [id]); - await client.query('COMMIT'); - task = res.rows[0]; + let result = await client.query("SELECT * FROM qr_codes WHERE id = $1", [code]); + if (result.rowCount === 1) { + result = await client.query("SELECT * FROM qr_gots WHERE code_id = $1 AND user_id = $2", [code, user]); + if (result.rowCount === 0) { + await client.query("INSERT INTO qr_gots (code_id, user_id) VALUES ($1, $2)", [code, user]); + return true; + } else { + return false; + } + } else { + return false; + } + } finally { + client.release(); + } + } + + async getUserCodes(user) { + let client = await this.pool.connect(); + try { + let result = await client.query("SELECT * FROM qr_gots WHERE user_id = $1", [user]); + return result.rows.length; + } finally { + client.release(); + } + } + + async getTotalCodes() { + let client = await this.pool.connect(); + try { + let result = await client.query("SELECT * FROM qr_codes"); + return result.rowCount; } finally { client.release(); } - return task; } async getTop() { let client = await this.pool.connect(); - let teams = []; try { - await client.query('BEGIN'); - let res = await client.query('SELECT qr_team.*, COUNT(task) as count\n' + - 'FROM qr_team\n' + - ' join qr_completion as com on qr_team.id = com.group_id\n' + - 'group by id, team_name, owner_id\n' + - 'ORDER BY count DESC', []); - await client.query('COMMIT'); - teams = res.rows; - } finally { - client.release(); - } - return teams; - } - - /** - * - * @param team - * @param task - * @returns {Promise} - */ - async checkPreviousTasks(team, task) { - if(task === 1) return true; - let client = await this.pool.connect(); - let prevtasks = 0; - try { - await client.query('BEGIN'); - let res = await client.query('SELECT * FROM qr_view WHERE task = $1 AND group_id = $2', [task-1, team]); - prevtasks = res.rowCount; - await client.query('COMMIT'); - } finally { - client.release(); - } - return prevtasks > 0; - } - - async getTeam(user) { - let client = await this.pool.connect(); - let team = null; - try { - await client.query('BEGIN'); - let res = await client.query('SELECT * FROM qr_team WHERE owner_id = $1', [user]); - await client.query('COMMIT'); - team = res.rows[0]; - } finally { - client.release(); - } - return team; - } - - async addCompletion(team, task) { - let client = await this.pool.connect(); - try { - await client.query('BEGIN'); - //add completion if not exists - let res = await client.query('SELECT * FROM qr_completion WHERE group_id = $1 AND task = $2', [team, task]); - if(res.rowCount === 0) { - await client.query('INSERT INTO qr_completion (group_id, task) values ($1,$2)', [team, task]); - } - await client.query('COMMIT'); - } finally { - client.release(); - } - } - - async addView(team, task) { - let client = await this.pool.connect(); - try { - await client.query('BEGIN'); - await client.query('INSERT INTO qr_view (group_id, task) values ($1,$2)', [team, task]); - await client.query('COMMIT'); + let result = await client.query("SELECT qr_users.name as name, COUNT(qr_gots.user_id) AS count, qr_users.user_id as id FROM qr_gots INNER JOIN qr_users ON qr_gots.user_id = qr_users.user_id GROUP BY qr_users.user_id ORDER BY count DESC LIMIT 10"); + return result.rows; } finally { client.release(); } diff --git a/index.js b/index.js index bfefff2..dbb2311 100644 --- a/index.js +++ b/index.js @@ -13,79 +13,50 @@ bot.start(async (ctx) => { return; } - switch (code) { - case "shaman": { - ctx.session.state = "register"; - await ctx.reply("Введите название группы"); - break; - } - default: { - let team = await database.getTeam(ctx.from.id); - if (team == null) return; - let task = await database.getQRTask(code); - if (task == null) return; - if (!await database.checkPreviousTasks(team.id, task.id)) { - await ctx.reply("Вы не выполнили предыдущие задания или это одно из прошлых заданий"); - return; - } - await database.addView(team.id, task.id); - await database.addCompletion(team.id, task.id - 1); - let pTask = await database.getTask(task.id - 1); - await bot.telegram.sendMessage(-879242326, "Команда " + team.team_name + " получила задание " + task.short_name + "(" + task.id + ") и закончила задание " + pTask.short_name + "(" + (task.id - 1) + ")"); - if (code === "freead") { - await ctx.reply(task.id + ") \n" + task.task_text, Telegraf.Extra.markup((m) => m.inlineKeyboard([[m.callbackButton("Проверить выполнение", "check")]]))); - } else { - await ctx.reply(task.id + ") \n" + task.task_text); - } - } - } -}); + await database.checkAndRegisterUser(ctx.from.id, ctx.from.first_name); -bot.command("top", async (ctx) => { - if (ctx.chat.id !== -879242326) return; - let top = await database.getTop(); - let message = "Топ команд:\n"; - for (let i = 0; i < top.length; i++) { - message += (i + 1) + ". " + top[i].team_name + " - " + top[i].count + " заданий\n"; - } - await ctx.reply(message); -}); - -bot.action("check", async (ctx) => { bot.telegram.getChatMember("@ks54_op5", ctx.from.id).then(async (member) => { if(member.status === "left") { - await ctx.answerCbQuery("Вы не состоите в @ks54_op5"); + await ctx.reply("Вы не состоите в @ks54_op5"); return; } bot.telegram.getChatMember("@studsovet_ks54", ctx.from.id).then(async (mem) => { if (mem.status === "left") { - await ctx.answerCbQuery("Вы не состоите в @studsovet_ks54"); + await ctx.reply("Вы не состоите в @studsovet_ks54"); return; } - let team = await database.getTeam(ctx.from.id); - if (team == null) return; - await bot.telegram.sendMessage(-879242326, "Команда " + team.team_name + " завершила прохождение квеста!"); - await ctx.editMessageText("Поздравляем с прохождением QR квеста! Вы можете спускаться к Деду Морозу.") + let exists = await database.codeExists(code); + if (!exists) { + await ctx.reply("Код не найден, возможно вы криво отсканировали QR код или пытаете его подделать"); + return; + } + let used = await database.useCode(code, ctx.from.id); + if (used) { + let userCodes = await database.getUserCodes(ctx.from.id); + let totalCodes = await database.getTotalCodes(); + await ctx.reply("Код успешно использован, собрано " + userCodes + " из " + totalCodes + " кодов"); + await bot.telegram.sendMessage(-879242326, `${ctx.from.first_name} отсканировал код ${userCodes} из ${totalCodes}`, {parse_mode: "HTML"}); + } else { + await ctx.reply("Код уже использован"); + } }).catch(async (err) => { - await ctx.answerCbQuery("Вы не состоите в @studsovet_ks54"); + await ctx.reply("Вы не состоите в @studsovet_ks54"); }); }).catch(async (err) => { - await ctx.answerCbQuery("Вы не состоите в @ks54_op5"); + await ctx.reply("Вы не состоите в @ks54_op5"); }); }); -bot.on('text', async (ctx) => { - switch (ctx.session.state) { - case "register": { - let group = ctx.message.text; - await database.registerQRTeam(group, ctx.from.id); - await ctx.reply("Группа зарегистрирована.\nЛиса на девятом небе отдыхает, найдёшь ли ты её?"); - ctx.session.state = undefined; - await bot.telegram.sendMessage(-879242326, "Группа " + group + " зарегистрирована by " + ctx.from.first_name + "", {parse_mode: "HTML"}); - } +bot.command("top", async (ctx) => { + if (ctx.chat.id !== -879242326) return; + let top = await database.getTop(); + let message = "Топ игроков:\n"; + for (let i = 0; i < top.length; i++) { + message += `${(i + 1)}. ${top[i].name} - ${top[i].count} кодов\n`; } + await ctx.reply(message, {parse_mode: "HTML"}); }); bot.startPolling(); \ No newline at end of file