feat: 新增请求访问统计功能

This commit is contained in:
橙子
2024-08-14 22:23:54 +08:00
parent b619204c5e
commit 9af98089f2
6 changed files with 135 additions and 92 deletions

View File

@@ -5,6 +5,7 @@ using Quartz;
using Volo.Abp.BackgroundWorkers.Quartz; using Volo.Abp.BackgroundWorkers.Quartz;
using Volo.Abp.Caching; using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Yi.Framework.Bbs.Domain.Entities; using Yi.Framework.Bbs.Domain.Entities;
using Yi.Framework.Bbs.Domain.Shared.Caches; using Yi.Framework.Bbs.Domain.Shared.Caches;
using Yi.Framework.Bbs.Domain.Shared.Enums; using Yi.Framework.Bbs.Domain.Shared.Enums;
@@ -46,10 +47,13 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase
_repository = repository; _repository = repository;
JobDetail = JobBuilder.Create<AccessLogStoreJob>().WithIdentity(nameof(AccessLogStoreJob)) JobDetail = JobBuilder.Create<AccessLogStoreJob>().WithIdentity(nameof(AccessLogStoreJob))
.Build(); .Build();
//每分钟执行一次 //每分钟执行一次
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob)) Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogStoreJob))
.WithCronSchedule("* * * * *") .WithCronSchedule("0 * * * * ?")
.Build(); .Build();
} }
public override async Task Execute(IJobExecutionContext context) public override async Task Execute(IJobExecutionContext context)
@@ -64,9 +68,20 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase
var entity = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogTypeEnum.Request) var entity = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogTypeEnum.Request)
.Where(x => x.CreationTime.Date == DateTime.Today) .Where(x => x.CreationTime.Date == DateTime.Today)
.FirstAsync(); .FirstAsync();
// _repository._Db.Storageable(list2).ExecuteCommandAsync();
if (entity is not null)
{
entity.Number = number+1;
await _repository.UpdateAsync(entity);
}
else
{
await _repository.InsertAsync((new AccessLogAggregateRoot() { Number = number,AccessLogType = AccessLogTypeEnum.Request}));
}
//删除前一天的缓存
await RedisClient.DelAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1)}");
} }
} }
} }

View File

@@ -55,9 +55,9 @@ namespace Yi.Framework.Bbs.Application.Services
/// </summary> /// </summary>
/// <param name="AccessLogType"></param> /// <param name="AccessLogType"></param>
/// <returns></returns> /// <returns></returns>
public async Task<List<AccessLogDto>> GetListAsync([FromQuery] AccessLogTypeEnum AccessLogType) public async Task<List<AccessLogDto>> GetListAsync([FromQuery] AccessLogTypeEnum accessLogType)
{ {
var entities = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogType) var entities = await _repository._DbQueryable.Where(x => x.AccessLogType == accessLogType)
.Where(x => x.CreationTime >= DateTime.Now.AddMonths(-3)) .Where(x => x.CreationTime >= DateTime.Now.AddMonths(-3))
.OrderBy(x => x.CreationTime).ToListAsync(); .OrderBy(x => x.CreationTime).ToListAsync();
var output = entities.Adapt<List<AccessLogDto>>(); var output = entities.Adapt<List<AccessLogDto>>();
@@ -73,11 +73,11 @@ namespace Yi.Framework.Bbs.Application.Services
public async Task AccessAsync() public async Task AccessAsync()
{ {
//可判断http重复防止同一ip多次访问 //可判断http重复防止同一ip多次访问
var last = await _repository._DbQueryable.OrderByDescending(x => x.CreationTime).FirstAsync(); var last = await _repository._DbQueryable.Where(x=>x.AccessLogType==AccessLogTypeEnum.HomeClick).OrderByDescending(x => x.CreationTime).FirstAsync();
if (last is null || last.CreationTime.Date != DateTime.Today) if (last is null || last.CreationTime.Date != DateTime.Today)
{ {
await _repository.InsertAsync(new AccessLogAggregateRoot()); await _repository.InsertAsync(new AccessLogAggregateRoot(){AccessLogType=AccessLogTypeEnum.HomeClick});
} }
else else
{ {
@@ -90,10 +90,10 @@ namespace Yi.Framework.Bbs.Application.Services
/// 获取当前周首页点击数据 /// 获取当前周首页点击数据
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public async Task<AccessLogDto[]> GetWeekAsync() public async Task<AccessLogDto[]> GetWeekAsync([FromQuery] AccessLogTypeEnum accessLogType)
{ {
var lastSeven = await _repository._DbQueryable var lastSeven = await _repository._DbQueryable
.Where(x => x.AccessLogType == AccessLogTypeEnum.HomeClick) .Where(x => x.AccessLogType == accessLogType)
.OrderByDescending(x => x.CreationTime).ToPageListAsync(1, 7); .OrderByDescending(x => x.CreationTime).ToPageListAsync(1, 7);
return WeekTimeHandler(lastSeven.ToArray()); return WeekTimeHandler(lastSeven.ToArray());

View File

@@ -288,8 +288,8 @@ namespace Yi.Abp.Web
//swagger //swagger
app.UseYiSwagger(); app.UseYiSwagger();
//流量访问统计,不启用 //流量访问统计,需redis支持否则不生效
//app.UseAccessLog(); app.UseAccessLog();
//请求处理 //请求处理
app.UseYiApiHandlinge(); app.UseYiApiHandlinge();

View File

@@ -9,16 +9,18 @@ export function access() {
} }
// 获取本周数据 // 获取本周数据
export function getWeek() { export function getWeek(data) {
return request({ return request({
url: "/access-log/week", url: "/access-log/week",
method: "get", method: "get",
params :data
}); });
} }
// 获取全部数据 // 获取全部数据
export function getAccessList() { export function getAccessList(data) {
return request({ return request({
url: "/access-log", url: "/access-log",
method: "get", method: "get",
params :data
}); });
} }

View File

@@ -37,7 +37,14 @@ const onClickText=()=>{
.el-divider { .el-divider {
margin: 0.2rem 0; margin: 0.2rem 0;
} }
.VisitsLineChart /deep/ .el-card__body{
padding: 0 20px;
}
.box-card-info {
width: 100%;
height: v-bind(height);
padding-bottom: 10px;
}
.card-header { .card-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@@ -52,9 +59,4 @@ const onClickText=()=>{
margin: 1rem 0; margin: 1rem 0;
} }
.box-card {
width: 100%;
height: v-bind(height);
padding-bottom: 10px;
}
</style> </style>

View File

@@ -3,7 +3,8 @@
<el-row :gutter="20" class="top-div"> <el-row :gutter="20" class="top-div">
<el-col :span="17"> <el-col :span="17">
<div class="chat-hub"> <div class="chat-hub">
<p @click="onClickToChatHub">点击前往-最新上线<span>聊天室 </span>现已支持<span>Ai助手</span>希望能帮助大家</p> <p @click="onClickToChatHub">点击前往-最新上线<span>聊天室 </span>现已支持<span>Ai助手</span>希望能帮助大家
</p>
</div> </div>
<div class="scrollbar"> <div class="scrollbar">
<ScrollbarInfo/> <ScrollbarInfo/>
@@ -97,23 +98,26 @@
<el-col :span="24"> <el-col :span="24">
<InfoCard header="访问统计" class="VisitsLineChart" text="全站历史统计" @onClickText="onClickAccessLog"> <InfoCard header="访问统计" class="VisitsLineChart" text="全站历史统计" @onClickText="onClickAccessLog">
<template #content> <template #content>
<p class="switch-span" @click="onClickWeekSwitch">切换</p>
<VisitsLineChart :option="statisOptions" class="statisChart"/> <VisitsLineChart :option="statisOptions" class="statisChart"/>
</template> </template>
</InfoCard> </InfoCard>
<el-dialog v-model="accessLogDialogVisible" title="全站历史统计" width="1200px" center> <el-dialog v-model="accessLogDialogVisible" title="全站历史统计" width="1200px" center>
<el-tabs v-model="accessLogTab"> <el-tabs v-model="accessLogTab">
<el-tab-pane label="访问统计近3月" name="AccessLogChart" style="display: flex;justify-content: center;"> <el-tab-pane label="访问统计近3月" name="AccessLogChart"
style="display: flex;justify-content: center;">
<AccessLogChart :option="accessLogOptins" style="height: 600px;width: 1200px;"/> <AccessLogChart :option="accessLogOptins" style="height: 600px;width: 1200px;"/>
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="注册统计近3月" name="RegisterChart" style="display: flex;justify-content: center;"> <el-tab-pane label="注册统计近3月" name="RegisterChart"
style="display: flex;justify-content: center;">
<AccessLogChart :option="registerLogOptins" style="height: 600px;width: 1200px;"/> <AccessLogChart :option="registerLogOptins" style="height: 600px;width: 1200px;"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-dialog> </el-dialog>
</el-col> </el-col>
@@ -129,7 +133,8 @@
<el-col :span="24"> <el-col :span="24">
<template v-if="isPointFinished"> <template v-if="isPointFinished">
<InfoCard :items="pointList" header="财富排行榜" text="查看我的位置" height="400" @onClickText="onClickMoneyTop"> <InfoCard :items="pointList" header="财富排行榜" text="查看我的位置" height="400"
@onClickText="onClickMoneyTop">
<template #item="temp"> <template #item="temp">
<PointsRanking :pointsData="temp"/> <PointsRanking :pointsData="temp"/>
</template> </template>
@@ -256,6 +261,7 @@ const query = reactive({
isTop: true, isTop: true,
}); });
const weekQuery = reactive({accessLogType: "Request"});
//初始化 //初始化
onMounted(async () => { onMounted(async () => {
access(); access();
@@ -266,7 +272,7 @@ onMounted(async () => {
isDiscussFinished.value = discussConfig.isFinish; isDiscussFinished.value = discussConfig.isFinish;
const {data: bannerData} = await bannerGetList(); const {data: bannerData} = await bannerGetList();
bannerList.value = bannerData.items; bannerList.value = bannerData.items;
const { data: weekData } = await getWeek(); const {data: weekData} = await getWeek(weekQuery);
weekList.value = weekData; weekList.value = weekData;
const {data: pointData, config: pointConfig} = await getRankingPoints(); const {data: pointData, config: pointConfig} = await getRankingPoints();
pointList.value = pointData.items; pointList.value = pointData.items;
@@ -372,7 +378,7 @@ watch(
async (value) => { async (value) => {
switch (value) { switch (value) {
case "AccessLogChart": case "AccessLogChart":
const { data } = await getAccessList(); const {data} = await getAccessList(weekQuery);
accessAllList.value = data; accessAllList.value = data;
break; break;
@@ -383,7 +389,6 @@ watch(
break; break;
} }
} }
) )
const onClickAccessLog = async () => { const onClickAccessLog = async () => {
accessLogDialogVisible.value = true; accessLogDialogVisible.value = true;
@@ -391,6 +396,17 @@ const onClickAccessLog = async () => {
} }
//切换统计开关
const onClickWeekSwitch = async () => {
if (weekQuery.accessLogType === "HomeClick") {
weekQuery.accessLogType= "Request";
} else if (weekQuery.accessLogType === "Request") {
weekQuery.accessLogType = "HomeClick";
}
const {data: weekData} = await getWeek(weekQuery);
weekList.value = weekData;
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.home-box { .home-box {
@@ -539,6 +555,13 @@ const onClickAccessLog = async () => {
padding: 0.5rem; padding: 0.5rem;
} }
.VisitsLineChart p{
display: flex;
justify-content: flex-end;
color: #409eff;
cursor: pointer;
margin-top: 8px;
}
.statisChart { .statisChart {
width: 100%; width: 100%;
height: 300px; height: 300px;
@@ -550,6 +573,7 @@ const onClickAccessLog = async () => {
} }
} }
//走马灯,聊天室链接 //走马灯,聊天室链接
.chat-hub { .chat-hub {
background-color: #E6A23C; background-color: #E6A23C;