136 lines
3.4 KiB
JavaScript
136 lines
3.4 KiB
JavaScript
import analysisDao from '../dao/analysis-dao';
|
|
import orm from '../entity/orm';
|
|
import email from '../entity/email';
|
|
import { desc, count, eq, and, ne, isNotNull } from 'drizzle-orm';
|
|
import { emailConst } from '../const/entity-const';
|
|
import kvConst from '../const/kv-const';
|
|
import dayjs from 'dayjs';
|
|
import { toUtc } from '../utils/date-uitil';
|
|
const analysisService = {
|
|
|
|
async echarts(c, params) {
|
|
if (!this.analysisCacheEnabled(c)) {
|
|
return await this.queryEcharts(c, params);
|
|
}
|
|
|
|
const cacheKey = this.echartsCacheKey(params);
|
|
const cache = await c.env.kv.get(cacheKey, { type: 'json' });
|
|
|
|
if (cache) {
|
|
return cache;
|
|
}
|
|
|
|
return await this.refreshEchartsCacheByKey(c, cacheKey);
|
|
},
|
|
|
|
async refreshEchartsCacheByKey(c, cacheKey) {
|
|
const params = this.echartsParamsByCacheKey(cacheKey);
|
|
const data = await this.queryEcharts(c, params);
|
|
await c.env.kv.put(cacheKey, JSON.stringify(data));
|
|
return data;
|
|
},
|
|
|
|
async refreshEchartsCache(c) {
|
|
if (!this.analysisCacheEnabled(c)) {
|
|
return;
|
|
}
|
|
|
|
const { keys } = await c.env.kv.list({ prefix: kvConst.ANALYSIS_ECHARTS });
|
|
|
|
await Promise.all(keys.map(key => this.refreshEchartsCacheByKey(c, key.name)));
|
|
},
|
|
|
|
async queryEcharts(c, params) {
|
|
|
|
const { timeZone } = params;
|
|
|
|
let utcDate = toUtc().startOf('day');
|
|
|
|
let localDate = utcDate.tz(timeZone);
|
|
|
|
utcDate = dayjs(utcDate.format('YYYY-MM-DD HH:mm:ss'))
|
|
|
|
localDate = dayjs(localDate.format('YYYY-MM-DD HH:mm:ss'))
|
|
|
|
//获取时差
|
|
const diffHours = localDate.diff(utcDate, 'hour',true);
|
|
|
|
|
|
const [
|
|
numberCount,
|
|
nameRatio,
|
|
userDayCountRaw,
|
|
receiveDayCountRaw,
|
|
sendDayCountRaw,
|
|
daySendTotalRaw
|
|
] = await Promise.all([
|
|
analysisDao.numberCount(c),
|
|
|
|
orm(c)
|
|
.select({ name: email.name, total: count() })
|
|
.from(email)
|
|
.where(and(eq(email.type, emailConst.type.RECEIVE), isNotNull(email.name),ne(email.name,'noreply'), ne(email.name,'')))
|
|
.groupBy(email.name)
|
|
.orderBy(desc(count()))
|
|
.limit(6),
|
|
|
|
|
|
analysisDao.userDayCount(c, diffHours),
|
|
analysisDao.receiveDayCount(c, diffHours),
|
|
analysisDao.sendDayCount(c, diffHours),
|
|
|
|
c.env.kv.get(kvConst.SEND_DAY_COUNT + dayjs().format('YYYY-MM-DD')),
|
|
]);
|
|
|
|
|
|
const userDayCount = this.filterEmptyDay(userDayCountRaw, timeZone);
|
|
const receiveDayCount = this.filterEmptyDay(receiveDayCountRaw, timeZone);
|
|
const sendDayCount = this.filterEmptyDay(sendDayCountRaw, timeZone);
|
|
|
|
const daySendTotal = daySendTotalRaw || 0;
|
|
|
|
return {
|
|
numberCount,
|
|
userDayCount,
|
|
receiveRatio: {
|
|
nameRatio
|
|
},
|
|
emailDayCount: {
|
|
receiveDayCount,
|
|
sendDayCount
|
|
},
|
|
daySendTotal: Number(daySendTotal)
|
|
};
|
|
},
|
|
|
|
filterEmptyDay(data, timeZone) {
|
|
const today = toUtc().tz(timeZone).subtract(1, 'day');
|
|
const previousDays = Array.from({ length: 15 }, (_, i) => {
|
|
return today.subtract(i, 'day').format('YYYY-MM-DD');
|
|
}).reverse();
|
|
|
|
return previousDays.map(day => {
|
|
const index = data.findIndex(item => item.date === day)
|
|
const total = index > - 1 ? data[index].total : 0
|
|
return {date: day,total}
|
|
})
|
|
|
|
},
|
|
|
|
echartsCacheKey(params = {}) {
|
|
return kvConst.ANALYSIS_ECHARTS + encodeURIComponent(params.timeZone || 'UTC');
|
|
},
|
|
|
|
echartsParamsByCacheKey(cacheKey) {
|
|
return {
|
|
timeZone: decodeURIComponent(cacheKey.replace(kvConst.ANALYSIS_ECHARTS, ''))
|
|
};
|
|
},
|
|
|
|
analysisCacheEnabled(c) {
|
|
return c.env.analysis_cache === true || c.env.analysis_cache === 'true';
|
|
}
|
|
}
|
|
|
|
export default analysisService
|