diff --git a/Yi.BBS.Vue3/src/apis/accessApi.js b/Yi.BBS.Vue3/src/apis/accessApi.js new file mode 100644 index 00000000..32354648 --- /dev/null +++ b/Yi.BBS.Vue3/src/apis/accessApi.js @@ -0,0 +1,17 @@ +import request from '@/utils/request' +// 触发访问 +export function access() { + return request({ + url: '/access-log', + method: 'post' + }) +} + + +// 获取本周数据 +export function getWeek() { + return request({ + url: '/access-log/week', + method: 'get' + }) +} \ No newline at end of file diff --git a/Yi.BBS.Vue3/src/components/echars/VisitsLineChart.vue b/Yi.BBS.Vue3/src/components/echars/VisitsLineChart.vue index c4b82539..9a766423 100644 --- a/Yi.BBS.Vue3/src/components/echars/VisitsLineChart.vue +++ b/Yi.BBS.Vue3/src/components/echars/VisitsLineChart.vue @@ -8,30 +8,34 @@ import { LineChart } from 'echarts/charts'; import { UniversalTransition } from 'echarts/features'; import { CanvasRenderer } from 'echarts/renderers'; import { ref ,onMounted} from 'vue'; - +import { getWeek } from '@/apis/accessApi.js' echarts.use([GridComponent, LineChart, CanvasRenderer, UniversalTransition]); const VisitsLineChart=ref(null); -onMounted(()=>{ +onMounted(async()=>{ var myChart = echarts.init(VisitsLineChart.value, null, { width: 320, height: 230 }); var option; +const response=await getWeek(); + +var numberData=response.data.map(x=>x.number); + option = { xAxis: { type: 'category', boundaryGap: false, - data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'] }, yAxis: { type: 'value' }, series: [ { - data: [82, 93, 90, 93, 129, 133, 132], + data: numberData, type: 'line', areaStyle: {} } diff --git a/Yi.BBS.Vue3/src/views/Index.vue b/Yi.BBS.Vue3/src/views/Index.vue index c8531e98..34179b7f 100644 --- a/Yi.BBS.Vue3/src/views/Index.vue +++ b/Yi.BBS.Vue3/src/views/Index.vue @@ -103,6 +103,7 @@ import AvatarInfo from '@/components/AvatarInfo.vue' import BottomInfo from '@/components/BottomInfo.vue' import VisitsLineChart from '@/components/echars/VisitsLineChart.vue' +import { access } from '@/apis/accessApi.js' import { getList } from '@/apis/plateApi.js' import { getList as bannerGetList } from '@/apis/bannerApi.js' import { getList as discussGetList } from '@/apis/discussApi.js' @@ -121,6 +122,7 @@ const query = reactive({ //初始化 onMounted(async () => { + await access(); plateList.value = (await getList()).data.items; discussList.value = (await discussGetList(query)).data.items; bannerList.value = (await bannerGetList()).data.items diff --git a/Yi.Furion.Net6/Yi.Furion.Application/Bbs/Services/IAccessLogService.cs b/Yi.Furion.Net6/Yi.Furion.Application/Bbs/Services/IAccessLogService.cs new file mode 100644 index 00000000..d845cf51 --- /dev/null +++ b/Yi.Furion.Net6/Yi.Furion.Application/Bbs/Services/IAccessLogService.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Yi.Furion.Application.Bbs.Services +{ + public interface IAccessLogService + { + } +} diff --git a/Yi.Furion.Net6/Yi.Furion.Application/Bbs/Services/Impl/AccessLogService.cs b/Yi.Furion.Net6/Yi.Furion.Application/Bbs/Services/Impl/AccessLogService.cs new file mode 100644 index 00000000..570c88b4 --- /dev/null +++ b/Yi.Furion.Net6/Yi.Furion.Application/Bbs/Services/Impl/AccessLogService.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Mapster; +using Yi.Framework.Infrastructure.Ddd.Repositories; +using Yi.Furion.Core.Bbs.Dtos.AccessLog; +using Yi.Furion.Core.Bbs.Entities; + +namespace Yi.Furion.Application.Bbs.Services.Impl +{ + public class AccessLogService : IAccessLogService,IDynamicApiController + { + private readonly IRepository _repository; + public AccessLogService(IRepository repository) { _repository = repository; } + + /// + /// 触发 + /// + /// + [HttpPost("")] + public async Task AccessAsync() + { + //可判断http重复,防止同一ip多次访问 + var last = await _repository._DbQueryable.OrderByDescending(x => x.CreationTime).FirstAsync(); + + if (last is null || last.CreationTime.Date != DateTime.Today) + { + await _repository.InsertAsync(new AccessLogEntity()); + } + else + { + await _repository._Db.Updateable().SetColumns(it => it.Number == it.Number + 1).Where(it => it.Id == last.Id).ExecuteCommandAsync(); + } + } + + /// + /// 获取当前周数据 + /// + /// + public async Task GetWeekAsync() + { + var lastSeven = await _repository._DbQueryable.OrderByDescending(x => x.CreationTime).ToPageListAsync(1, 7); + + return WeekTimeHandler(lastSeven.ToArray()); + } + + private AccessLogDto[] WeekTimeHandler(AccessLogEntity[] data) + { + data = data.Where(x => x.CreationTime.DayOfWeek == DateTime.Now.DayOfWeek).ToArray(); + Dictionary processedData = new Dictionary(); + + // 初始化字典,将每天的数据都设为0 + foreach (DayOfWeek dayOfWeek in Enum.GetValues(typeof(DayOfWeek))) + { + processedData.Add(dayOfWeek, new AccessLogDto()); + } + + // 处理原始数据 + foreach (var item in data) + { + DayOfWeek dayOfWeek = item.CreationTime.DayOfWeek; + // 如果当天有数据,则更新字典中的值为对应的Number + var sss= data.Adapt(); + processedData[dayOfWeek] = item.Adapt(); + + } + return processedData.Values.ToArray(); + } + } +} diff --git a/Yi.Furion.Net6/Yi.Furion.Application/Yi.Furion.Application.xml b/Yi.Furion.Net6/Yi.Furion.Application/Yi.Furion.Application.xml index 0fc6d1b4..0444753b 100644 --- a/Yi.Furion.Net6/Yi.Furion.Application/Yi.Furion.Application.xml +++ b/Yi.Furion.Net6/Yi.Furion.Application/Yi.Furion.Application.xml @@ -34,6 +34,18 @@ Label服务抽象 + + + 触发 + + + + + + 获取当前周数据 + + + 点赞功能 diff --git a/Yi.Furion.Net6/Yi.Furion.Core/Bbs/Dtos/AccessLog/AccessLogDto.cs b/Yi.Furion.Net6/Yi.Furion.Core/Bbs/Dtos/AccessLog/AccessLogDto.cs new file mode 100644 index 00000000..34580471 --- /dev/null +++ b/Yi.Furion.Net6/Yi.Furion.Core/Bbs/Dtos/AccessLog/AccessLogDto.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Yi.Framework.Infrastructure.Helper; + +namespace Yi.Furion.Core.Bbs.Dtos.AccessLog +{ + public class AccessLogDto + { + public long Id { get; set; } + public long Number { get; set; } + public DateTime? LastModificationTime { get; set; } + public DateTime CreationTime { get; set; } + } +} diff --git a/Yi.Furion.Net6/Yi.Furion.Core/Bbs/Entities/AccessLogEntity.cs b/Yi.Furion.Net6/Yi.Furion.Core/Bbs/Entities/AccessLogEntity.cs new file mode 100644 index 00000000..e261723a --- /dev/null +++ b/Yi.Furion.Net6/Yi.Furion.Core/Bbs/Entities/AccessLogEntity.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using SqlSugar; +using Yi.Framework.Infrastructure.Data.Auditing; +using Yi.Framework.Infrastructure.Ddd.Entities; +using Yi.Framework.Infrastructure.Helper; + +namespace Yi.Furion.Core.Bbs.Entities +{ + [SugarTable("AccessLog")] + public class AccessLogEntity : IEntity, IHasModificationTime, IHasCreationTime + { + [SugarColumn(IsPrimaryKey = true)] + public long Id { get; set; } = SnowflakeHelper.NextId; + public long Number { get; set; } + public DateTime? LastModificationTime { get; set; } + public DateTime CreationTime { get; set; } + } +} diff --git a/Yi.Furion.Net6/Yi.Furion.Core/Yi.Furion.Core.csproj b/Yi.Furion.Net6/Yi.Furion.Core/Yi.Furion.Core.csproj index 8dc398d3..36724827 100644 --- a/Yi.Furion.Net6/Yi.Furion.Core/Yi.Furion.Core.csproj +++ b/Yi.Furion.Net6/Yi.Furion.Core/Yi.Furion.Core.csproj @@ -28,10 +28,4 @@ - - - - - - diff --git a/Yi.Furion.Net6/Yi.Furion.Web.Entry/appsettings.json b/Yi.Furion.Net6/Yi.Furion.Web.Entry/appsettings.json index 5e45896a..da697e4d 100644 --- a/Yi.Furion.Net6/Yi.Furion.Web.Entry/appsettings.json +++ b/Yi.Furion.Net6/Yi.Furion.Web.Entry/appsettings.json @@ -21,7 +21,7 @@ "Url": "DataSource=yi-sqlsugar-dev.db", "DbType": "Sqlite", "EnabledReadWrite": false, - "EnabledCodeFirst": true, + "EnabledCodeFirst": false, "ReadUrl": [ "DataSource=[xxxx]", //Sqlite "server=[xxxx];port=3306;database=[xxxx];user id=[xxxx];password=[xxxx]", //Mysql @@ -29,7 +29,7 @@ ] }, - "EnabledDataSeed": true, + "EnabledDataSeed": false, "JWTSettings": { "ValidateIssuerSigningKey": true, // 是否验证密钥,bool 类型,默认true