Compare commits
32 Commits
49bd703039
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| c88d106a55 | |||
| 42485cc97e | |||
| bb1c7ec16d | |||
| 7280705baf | |||
| 39e1f58665 | |||
| b2c8345798 | |||
| 6d56fe8638 | |||
| afd0b1125d | |||
| b8e35a9760 | |||
| f4beb32725 | |||
| cdf683bd62 | |||
| 80b3219244 | |||
| 09f402377e | |||
| 5f127098cf | |||
| a9b6a2c7fd | |||
| e62c113c93 | |||
| eb2e0e5d2a | |||
| 5d22686cf8 | |||
| 31cf0d0daa | |||
| 76924ac0a5 | |||
| 7042f3d11e | |||
| 368d23399a | |||
| 05dc0aac1b | |||
| c4feb57867 | |||
| a51818759c | |||
| 497b3ab9ed | |||
| 409ff2f44a | |||
| ac8d89454b | |||
| 586fb257bd | |||
| 8372b221ee | |||
| c97825b54f | |||
| f8c408878e |
113
main.js
113
main.js
@@ -8,6 +8,7 @@ class 计数 {
|
|||||||
周 = new Map()
|
周 = new Map()
|
||||||
月 = new Map()
|
月 = new Map()
|
||||||
年 = new Map()
|
年 = new Map()
|
||||||
|
总 = new Map()
|
||||||
}
|
}
|
||||||
|
|
||||||
class 类型 {
|
class 类型 {
|
||||||
@@ -25,6 +26,27 @@ const 截图 = new 类型()
|
|||||||
const 收藏 = new 类型()
|
const 收藏 = new 类型()
|
||||||
const 综合 = new 类型()
|
const 综合 = new 类型()
|
||||||
|
|
||||||
|
// 获取浏览数
|
||||||
|
export function get_views(name, ids = []) {
|
||||||
|
const all = { 文章, 作品, 游戏, 截图, 收藏, 综合 }
|
||||||
|
const counts = all[name].浏览数.总
|
||||||
|
return ids.map(id => ({ id: parseInt(id, 10), count: counts.get(id) || 0 }))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当日热门搜索词
|
||||||
|
export function get_search(n = 10) {
|
||||||
|
const 全部 = new Map()
|
||||||
|
const all = { 文章, 作品, 游戏, 截图, 收藏, 综合 }
|
||||||
|
for (const key in all) {
|
||||||
|
all[key].搜索词.日.forEach((value, key) => {
|
||||||
|
console.log(key, value)
|
||||||
|
全部.set(key, (全部.get(key) || 0) + value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return [...全部.entries()].sort((a, b) => b[1] - a[1]).slice(0, n).map(([text, count]) => {
|
||||||
|
return { text, count }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const 日期格式 = new Intl.DateTimeFormat('zh-CN', {
|
const 日期格式 = new Intl.DateTimeFormat('zh-CN', {
|
||||||
year: 'numeric',
|
year: 'numeric',
|
||||||
@@ -36,7 +58,8 @@ const 日期格式 = new Intl.DateTimeFormat('zh-CN', {
|
|||||||
// 匹配文章和截图的正则表达式
|
// 匹配文章和截图的正则表达式
|
||||||
const imagesRegex = /\/web\/v1\/images\/detail\/v2\?imagesId=(\d+)¤tUserId=(\d+)/
|
const imagesRegex = /\/web\/v1\/images\/detail\/v2\?imagesId=(\d+)¤tUserId=(\d+)/
|
||||||
const articleRegex = /\/web\/v1\/article\/get\?id=(\d+)&userId=(\d+)/
|
const articleRegex = /\/web\/v1\/article\/get\?id=(\d+)&userId=(\d+)/
|
||||||
const collectionRegex = /\/web\/v1\/member\/explorer\/article\/get\?id=(\d+)/
|
const collectionArticleRegex = /\/web\/v1\/member\/explorer\/article\/get\?id=(\d+)/
|
||||||
|
const collectionImagesRegex = /\/web\/v1\/member\/explorer\/get\?id=(\d+)/
|
||||||
|
|
||||||
|
|
||||||
var 当前日期 = 日期格式.format(new Date()).replace(/\//g, '-')
|
var 当前日期 = 日期格式.format(new Date()).replace(/\//g, '-')
|
||||||
@@ -60,7 +83,19 @@ const 存档 = async (message = '正在存档...') => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default function () {
|
export function main() {
|
||||||
|
console.log(当前日期, '启动时加载全部数据...')
|
||||||
|
fs.readdirSync('./data').filter(file => file.endsWith('.json')).map(name => {
|
||||||
|
console.log('filename:', name)
|
||||||
|
const file = fs.readFileSync(`./data/${name}`, 'utf8')
|
||||||
|
if (file) {
|
||||||
|
const data = JSON.parse(file)
|
||||||
|
Object.entries(data.文章).forEach(([key, value]) => 文章.浏览数.总.set(key, value))
|
||||||
|
Object.entries(data.截图).forEach(([key, value]) => 截图.浏览数.总.set(key, value))
|
||||||
|
Object.entries(data.收藏).forEach(([key, value]) => 收藏.浏览数.总.set(key, value))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
console.log(当前日期, '启动时加载当日数据...')
|
console.log(当前日期, '启动时加载当日数据...')
|
||||||
if (fs.existsSync(`./data/${当前日期}.json`)) {
|
if (fs.existsSync(`./data/${当前日期}.json`)) {
|
||||||
const file = fs.readFileSync(`./data/${当前日期}.json`, 'utf8')
|
const file = fs.readFileSync(`./data/${当前日期}.json`, 'utf8')
|
||||||
@@ -76,14 +111,23 @@ export default function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 定时执行任务,确保上一次执行完毕后才开始下一轮
|
||||||
|
async function startScheduledTask() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
存档('每10分钟自动存档...')
|
||||||
|
await update('web_images', 'day_rank', Object.entries(Object.fromEntries(截图.浏览数.日)))
|
||||||
|
await update('web_article', 'day_rank', Object.entries(Object.fromEntries(文章.浏览数.日)))
|
||||||
|
await update_explorer('web_member_explorer', 'day_rank', Object.entries(Object.fromEntries(收藏.浏览数.日)))
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 10 * 60 * 1000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setInterval(async () => {
|
// 启动定时任务
|
||||||
存档('每10分钟自动存档...')
|
startScheduledTask()
|
||||||
await update('web_images', 'day_rank', Object.entries(Object.fromEntries(截图.浏览数.日)))
|
|
||||||
await update('web_article', 'day_rank', Object.entries(Object.fromEntries(文章.浏览数.日)))
|
|
||||||
await update_explorer('web_member_explorer', 'day_rank', Object.entries(Object.fromEntries(收藏.浏览数.日)))
|
|
||||||
}, 10000)
|
|
||||||
|
|
||||||
|
|
||||||
console.log(当前日期, '开始收集日志...')
|
console.log(当前日期, '开始收集日志...')
|
||||||
const tail = new Tail('/opt/log/caddy/access.log')
|
const tail = new Tail('/opt/log/caddy/access.log')
|
||||||
@@ -111,7 +155,11 @@ export default function () {
|
|||||||
if (item.request.uri.startsWith('/web/v1/article/get')) {
|
if (item.request.uri.startsWith('/web/v1/article/get')) {
|
||||||
const [uri, id] = item.request.uri.match(articleRegex) ?? []
|
const [uri, id] = item.request.uri.match(articleRegex) ?? []
|
||||||
if (uri && id) {
|
if (uri && id) {
|
||||||
文章.浏览数.日.set(id, 文章.浏览数.日.has(id) ? 文章.浏览数.日.get(id) + 1 : 1)
|
文章.浏览数.日.set(id, (文章.浏览数.日.get(id) || 0) + 1)
|
||||||
|
文章.浏览数.周.set(id, (文章.浏览数.周.get(id) || 0) + 1)
|
||||||
|
文章.浏览数.月.set(id, (文章.浏览数.月.get(id) || 0) + 1)
|
||||||
|
文章.浏览数.年.set(id, (文章.浏览数.年.get(id) || 0) + 1)
|
||||||
|
文章.浏览数.总.set(id, (文章.浏览数.总.get(id) || 0) + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,16 +167,53 @@ export default function () {
|
|||||||
if (item.request.uri.startsWith('/web/v1/images/detail/v2')) {
|
if (item.request.uri.startsWith('/web/v1/images/detail/v2')) {
|
||||||
const [uri, id] = item.request.uri.match(imagesRegex) ?? []
|
const [uri, id] = item.request.uri.match(imagesRegex) ?? []
|
||||||
if (uri && id) {
|
if (uri && id) {
|
||||||
截图.浏览数.日.set(id, 截图.浏览数.日.has(id) ? 截图.浏览数.日.get(id) + 1 : 1)
|
截图.浏览数.日.set(id, (截图.浏览数.日.get(id) || 0) + 1)
|
||||||
|
截图.浏览数.周.set(id, (截图.浏览数.周.get(id) || 0) + 1)
|
||||||
|
截图.浏览数.月.set(id, (截图.浏览数.月.get(id) || 0) + 1)
|
||||||
|
截图.浏览数.年.set(id, (截图.浏览数.年.get(id) || 0) + 1)
|
||||||
|
截图.浏览数.总.set(id, (截图.浏览数.总.get(id) || 0) + 1)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理收藏日志
|
// 处理收藏图集日志
|
||||||
if (item.request.uri.startsWith('/web/v1/member/explorer/article/get')) {
|
if (item.request.uri.startsWith('/web/v1/member/explorer/article/get')) {
|
||||||
const [uri, id] = item.request.uri.match(collectionRegex) ?? []
|
const [uri, id] = item.request.uri.match(collectionArticleRegex) ?? []
|
||||||
if (uri && id) {
|
if (uri && id) {
|
||||||
收藏.浏览数.日.set(id, 收藏.浏览数.日.has(id) ? 收藏.浏览数.日.get(id) + 1 : 1)
|
收藏.浏览数.日.set(id, (收藏.浏览数.日.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.周.set(id, (收藏.浏览数.周.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.月.set(id, (收藏.浏览数.月.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.年.set(id, (收藏.浏览数.年.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.总.set(id, (收藏.浏览数.总.get(id) || 0) + 1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理收藏图片日志
|
||||||
|
if (item.request.uri.startsWith('/web/v1/member/explorer/get')) {
|
||||||
|
const [uri, id] = item.request.uri.match(collectionImagesRegex) ?? []
|
||||||
|
if (uri && id) {
|
||||||
|
收藏.浏览数.日.set(id, (收藏.浏览数.日.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.周.set(id, (收藏.浏览数.周.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.月.set(id, (收藏.浏览数.月.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.年.set(id, (收藏.浏览数.年.get(id) || 0) + 1)
|
||||||
|
收藏.浏览数.总.set(id, (收藏.浏览数.总.get(id) || 0) + 1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理搜索日志
|
||||||
|
if (item.request.uri.startsWith('/api?query=')) {
|
||||||
|
const url = decodeURI(item.request.uri)
|
||||||
|
const regex = /text:"([^"]*)"/g
|
||||||
|
const match = regex.exec(url)
|
||||||
|
if (match) {
|
||||||
|
let key = match[1]
|
||||||
|
截图.搜索词.日.set(key, (截图.搜索词.日.get(key) || 0) + 1)
|
||||||
|
截图.搜索词.周.set(key, (截图.搜索词.周.get(key) || 0) + 1)
|
||||||
|
截图.搜索词.月.set(key, (截图.搜索词.月.get(key) || 0) + 1)
|
||||||
|
截图.搜索词.年.set(key, (截图.搜索词.年.get(key) || 0) + 1)
|
||||||
|
截图.搜索词.总.set(key, (截图.搜索词.总.get(key) || 0) + 1)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
11
server.js
11
server.js
@@ -1,10 +1,19 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import main from './main.js'
|
import { main, get_search, get_views } from './main.js'
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
|
|
||||||
app.use(express.json())
|
app.use(express.json())
|
||||||
|
|
||||||
|
app.get('/api/get_views/:name', (req, res) => {
|
||||||
|
res.json(get_views(req.params.name, req.query.ids.split(",")))
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('/api/get_search/hot', (req, res) => {
|
||||||
|
res.json(get_search(req.query.pagesize || 10))
|
||||||
|
})
|
||||||
|
|
||||||
app.get('/api', (req, res) => {
|
app.get('/api', (req, res) => {
|
||||||
const { start, end } = req.query
|
const { start, end } = req.query
|
||||||
console.log(req.query)
|
console.log(req.query)
|
||||||
|
|||||||
35
update.js
35
update.js
@@ -48,7 +48,7 @@ export async function update_explorer(table, rank, views) {
|
|||||||
console.log('统计当天时间段内排行榜到临时表')
|
console.log('统计当天时间段内排行榜到临时表')
|
||||||
await conn.query("UPDATE temp_updates SET rank = fans_count * 35 + views_count * 25")
|
await conn.query("UPDATE temp_updates SET rank = fans_count * 35 + views_count * 25")
|
||||||
|
|
||||||
console.log('更新数据从临时表转入生产库')
|
console.log('更新数据从临时表转入生产库', table)
|
||||||
await conn.query(`UPDATE ${table} t LEFT JOIN temp_updates tu ON t.id = tu.id SET t.${rank} = IFNULL(tu.rank, 0)`)
|
await conn.query(`UPDATE ${table} t LEFT JOIN temp_updates tu ON t.id = tu.id SET t.${rank} = IFNULL(tu.rank, 0)`)
|
||||||
await conn.end()
|
await conn.end()
|
||||||
console.log('更新完成')
|
console.log('更新完成')
|
||||||
@@ -82,35 +82,44 @@ export async function update(table, rank, views) {
|
|||||||
|
|
||||||
// 0=文章/游戏/作品 1=短视频 2=图片
|
// 0=文章/游戏/作品 1=短视频 2=图片
|
||||||
const TYPE = {
|
const TYPE = {
|
||||||
'web_images': 'type=2',
|
'web_images': 'type=2',
|
||||||
'web_article': 'type=0',
|
'web_article': 'type=0',
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义查询时间范围
|
// 定义查询时间范围
|
||||||
const WHERE = {
|
const WHERE = {
|
||||||
'day_rank': `create_time >= CURDATE() AND ${TYPE[table]}`,
|
'day_rank': `create_time >= CURDATE() AND ${TYPE[table]}`,
|
||||||
'week_rank': `create_time >= CURDATE() - INTERVAL 7 DAY AND ${TYPE[table]}`,
|
'week_rank': `create_time >= CURDATE() - INTERVAL 7 DAY AND ${TYPE[table]}`,
|
||||||
'month_rank': `create_time >= CURDATE() - INTERVAL 1 MONTH AND ${TYPE[table]}`,
|
'month_rank': `create_time >= CURDATE() - INTERVAL 1 MONTH AND ${TYPE[table]}`,
|
||||||
'year_rank': `create_time >= CURDATE() - INTERVAL 1 YEAR AND ${TYPE[table]}`,
|
'year_rank': `create_time >= CURDATE() - INTERVAL 1 YEAR AND ${TYPE[table]}`,
|
||||||
'aeon_rank': `${TYPE[table]}`
|
'aeon_rank': `${TYPE[table]}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const JOIN = {
|
const JOIN = {
|
||||||
'comment': `SELECT comment_id AS id, COUNT(*) AS comment_count FROM web_comment WHERE ${WHERE[rank]} GROUP BY id`,
|
'comment': `SELECT comment_id AS id, IFNULL(COUNT(*), 0) AS comment_count FROM web_comment WHERE ${WHERE[rank]} GROUP BY comment_id`,
|
||||||
'praise': `SELECT praise_id AS id, COUNT(*) AS praise_count FROM web_praise WHERE ${WHERE[rank]} GROUP BY id`,
|
'praise': `SELECT praise_id AS id, IFNULL(COUNT(*), 0) AS praise_count FROM web_praise WHERE ${WHERE[rank]} GROUP BY praise_id`,
|
||||||
'collect': `SELECT collect_id AS id, COUNT(*) AS collect_count FROM web_collect WHERE ${WHERE[rank]} GROUP BY id`
|
'collect': `SELECT collect_id AS id, IFNULL(COUNT(*), 0) AS collect_count FROM web_collect WHERE ${WHERE[rank]} GROUP BY collect_id`
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let name of ['comment', 'praise', 'collect']) {
|
for (let name of ['comment', 'praise', 'collect']) {
|
||||||
console.log(`统计 ${rank} 时间段内 ${name} 数到临时表`)
|
console.log(`统计 ${rank} 时间段内 ${name} 数到临时表`)
|
||||||
await conn.query(`UPDATE temp_updates t JOIN(${JOIN[name]}) stats ON t.id = stats.id SET t.${name}_count = stats.${name}_count`)
|
const updateResult = await conn.query(`UPDATE temp_updates t JOIN(${JOIN[name]}) stats ON t.id = stats.id SET t.${name}_count = stats.${name}_count`)
|
||||||
|
console.log(`${name} 更新结果:`, updateResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('统计当天时间段内排行榜到临时表')
|
console.log('统计当天时间段内排行榜到临时表')
|
||||||
await conn.query("UPDATE temp_updates SET rank = collect_count * 35 + praise_count * 20 + comment_count * 20 + views_count * 25")
|
const rankUpdateResult = await conn.query("UPDATE temp_updates SET rank = IFNULL(collect_count, 0) * 35 + IFNULL(praise_count, 0) * 20 + IFNULL(comment_count, 0) * 20 + IFNULL(views_count, 0) * 25")
|
||||||
|
console.log('排行榜更新结果:', rankUpdateResult)
|
||||||
|
|
||||||
|
// 打印临时表前 10 条数据
|
||||||
|
console.log('打印临时表前 10 条数据')
|
||||||
|
const [tempData] = await conn.query("SELECT * FROM temp_updates LIMIT 10")
|
||||||
|
console.log('临时表数据:', tempData)
|
||||||
|
|
||||||
|
console.log('更新数据从临时表转入生产库', table)
|
||||||
|
const finalUpdateResult = await conn.query(`UPDATE ${table} t LEFT JOIN temp_updates tu ON t.id = tu.id SET t.${rank} = IFNULL(tu.rank, 0)`)
|
||||||
|
console.log('生产库更新结果:', finalUpdateResult)
|
||||||
|
|
||||||
console.log('更新数据从临时表转入生产库')
|
|
||||||
await conn.query(`UPDATE ${table} t LEFT JOIN temp_updates tu ON t.id = tu.id SET t.${rank} = IFNULL(tu.rank, 0)`)
|
|
||||||
await conn.end()
|
await conn.end()
|
||||||
console.log('更新完成')
|
console.log('更新完成')
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user