From 33d0a96ef72facfc1b659c7d2620704810086d3f Mon Sep 17 00:00:00 2001 From: satori Date: Fri, 6 Dec 2024 11:56:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=8C=87=E6=A0=87=E5=88=B0?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++ main.js | 6 ++-- update.js | 104 ++++++++++++++++++++++++------------------------------ 3 files changed, 54 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index ee9ed13..8ffb6f6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ 创建指标 导出接口 + +喜欢20, 收藏35, 评论20, 浏览25 + ```bash # 安装依赖 npm install --registry=https://registry.npmmirror.com diff --git a/main.js b/main.js index 7cb3d73..6793929 100644 --- a/main.js +++ b/main.js @@ -38,7 +38,7 @@ const archive = async (message = '正在存档...') => { // 主函数 export default function () { if (fs.existsSync(`./data/${currentDate}.json`)) { - console.log(currentDate, '启动时加载数据...') + console.log(currentDate, '启动时加载当日数据...') const file = fs.readFileSync(`./data/${currentDate}.json`, 'utf8') if (file) { const data = JSON.parse(file) @@ -52,7 +52,9 @@ export default function () { setInterval(() => { archive('每10分钟自动存档...') - update('day_rank', Object.entries(Object.fromEntries(screenshots))) // 更新数据库中 day_rank 字段 + update('web_images', 'day_rank', Object.entries(Object.fromEntries(screenshots))), + update('web_article', 'day_rank', Object.entries(Object.fromEntries(articles))), + update('web_member_explorer', 'day_rank', Object.entries(Object.fromEntries(collections))) }, 600000) // 实时读取日志文件 diff --git a/update.js b/update.js index 863a64f..7ec8d0a 100644 --- a/update.js +++ b/update.js @@ -1,72 +1,62 @@ import fs from 'fs' import mysql from 'mysql2/promise' -export async function update(field, list) { +// 更新指标到数据库 +export async function update(table, rank, views) { + if (!['day_rank', 'week_rank', 'month_rank', 'year_rank', 'aeon_rank'].includes(rank)) { + throw new Error('字段类型错误') + } + const { mysql: config } = JSON.parse(fs.readFileSync('config.json', 'utf8')) const conn = await mysql.createConnection(config) console.log('创建临时表') - await conn.query(`CREATE TEMPORARY TABLE temp_updates (id INT PRIMARY KEY, ${mysql.escapeId(field)} INT UNSIGNED)`) + await conn.query(`CREATE TEMPORARY TABLE temp_updates (id INT PRIMARY KEY, views_count INT UNSIGNED)`) - console.log(`数据总量 ${list.length} 条, 每次 10000 条写入 ${Math.ceil(list.length / 10000)} 次`) - for (let i = 0; i < list.length; i += 10000) { + console.log(`数据总量 ${views.length} 条, 每次 10000 条写入 ${Math.ceil(views.length / 10000)} 次`) + for (let i = 0; i < views.length; i += 10000) { console.log(`第 ${i / 10000 + 1} 次写入`) - const values = list.slice(i, i + 10000) - await conn.query(`INSERT INTO temp_updates (id, ${field}) VALUES ?`, [values]) + const values = views.slice(i, i + 10000) + await conn.query(`INSERT INTO temp_updates (id, views_count) VALUES ?`, [values]) } + + + for (let name of ['comment', 'praise', 'collect']) { + console.log(`统计当天时间段内 ${name} 数到临时表`) + await conn.query(` + UPDATE temp_updates t + JOIN ( + SELECT + ${mame}_id AS article_id, + COUNT(*) AS ${name}_count + FROM + web_${name} + WHERE + DATE(create_time) = CURDATE() + GROUP BY + ${field}_id + ) stats + ON t.id = stats.article_id + SET t.${name}_count = stats.${name}_count; + `) + } + + console.log('统计当天时间段内排行榜到临时表') + await conn.query(` + UPDATE temp_updates + SET day_rank = + collect_count * 35 + + praise_count * 20 + + comment_count * 20 + + views_count * 25; + `) + + console.log('更新前清空当日记录') + await conn.query(`UPDATE ${table} SET ${rank} = 0`) + console.log('更新数据从临时表转入生产库') - await conn.query(`UPDATE web_images t JOIN temp_updates tu ON t.id = tu.id SET t.${field} = tu.${field}`) + await conn.query(`UPDATE ${table} t JOIN temp_updates tu ON t.id = tu.id SET t.${rank} = tu.${rank}`) await conn.end() console.log('更新完成') } - -export async function likes(day = 1) { - const { mysql: config } = JSON.parse(fs.readFileSync('config.json', 'utf8')) - const conn = await mysql.createConnection(config) - const [rows] = await conn.query(`SELECT * FROM web_praise WHERE create_time >= CURDATE() AND create_time < CURDATE() + INTERVAL ${day} DAY`) - await conn.end() - return rows -} - -export async function collects(day = 1) { - const { mysql: config } = JSON.parse(fs.readFileSync('config.json', 'utf8')) - const conn = await mysql.createConnection(config) - const [rows] = await conn.query(`SELECT * FROM web_collect WHERE create_time >= CURDATE() AND create_time < CURDATE() + INTERVAL ${day} DAY`) - await conn.end() - return rows -} - -export async function views(day = 1) { - const startDate = new Date(Date.now() - day * 24 * 60 * 60 * 1000) - const currentDate = new Date() - - const files = fs.readdirSync('./data').filter(name => /\d{4}-\d{2}-\d{2}\.json$/.test(name)).filter(name => { - const date = new Date(name.match(/\d{4}-\d{2}-\d{2}/)[0]) - return date >= startDate && date <= currentDate - }) - - const result = { articles: new Map(), games: new Map(), screenshots: new Map() } - - files.forEach(name => { - const data = JSON.parse(fs.readFileSync(`./data/${name}`, 'utf8')) - for (const type of ['articles', 'games', 'screenshots']) { - Object.entries(data[type] || {}).forEach(([key, value]) => { - result[type].set(key, (result[type].get(key) || 0) + value) - }) - } - }) - - return Object.fromEntries( - Object.entries(result).map(([key, map]) => [ - key, - [...map.entries()].sort((a, b) => b[1] - a[1]).map(([k]) => k) - ]) - ) -} - -// 计算总权重 -export function totalWeight(data) { - const total = Object.values(data).reduce((acc, cur) => acc + cur, 0) - return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, Math.round(value / total * 100)])) -}