Merge branch 'refs/heads/abp' into digital-collectibles

This commit is contained in:
橙子
2024-10-17 23:03:49 +08:00
13 changed files with 143 additions and 26 deletions

View File

@@ -4,7 +4,9 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus;
using Yi.Framework.Bbs.Domain.Shared.Caches;
using Yi.Framework.Bbs.Domain.Shared.Etos;
namespace Yi.Framework.Bbs.Application.Extensions;
@@ -14,6 +16,29 @@ namespace Yi.Framework.Bbs.Application.Extensions;
/// 需考虑一致性问题,又不能上锁影响性能
/// </summary>
public class AccessLogMiddleware : IMiddleware, ITransientDependency
{
private static int _accessLogNumber = 0;
internal static void ResetAccessLogNumber()
{
_accessLogNumber = 0;
}
internal static int GetAccessLogNumber()
{
return _accessLogNumber;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
await next(context);
Interlocked.Increment(ref _accessLogNumber);
}
}
public class AccessLogResetEventHandler : ILocalEventHandler<AccessLogResetArgs>,
ITransientDependency
{
/// <summary>
/// 缓存前缀
@@ -39,13 +64,28 @@ public class AccessLogMiddleware : IMiddleware, ITransientDependency
return redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled);
}
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
//该事件由job定时10秒触发
public async Task HandleEventAsync(AccessLogResetArgs eventData)
{
await next(context);
if (EnableRedisCache)
{
await RedisClient.IncrByAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date}", 1);
//分布式锁
if (await RedisClient.SetNxAsync("AccessLogLock",true,TimeSpan.FromSeconds(5)))
{
//自增长数
var incrNumber= AccessLogMiddleware.GetAccessLogNumber();
//立即重置,开始计算,方式丢失
AccessLogMiddleware.ResetAccessLogNumber();
if (incrNumber>0)
{
await RedisClient.IncrByAsync(
$"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.ToString("yyyyMMdd")}", incrNumber);
}
}
}
}
}

View File

@@ -0,0 +1,38 @@
using FreeRedis;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Quartz;
using Volo.Abp.BackgroundWorkers.Quartz;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EventBus.Local;
using Yi.Framework.Bbs.Domain.Entities;
using Yi.Framework.Bbs.Domain.Shared.Caches;
using Yi.Framework.Bbs.Domain.Shared.Enums;
using Yi.Framework.Bbs.Domain.Shared.Etos;
using Yi.Framework.SqlSugarCore.Abstractions;
namespace Yi.Framework.Bbs.Application.Jobs;
public class AccessLogCacheJob : QuartzBackgroundWorkerBase
{
private readonly ILocalEventBus _localEventBus;
public AccessLogCacheJob(ILocalEventBus localEventBus)
{
_localEventBus = localEventBus;
JobDetail = JobBuilder.Create<AccessLogCacheJob>().WithIdentity(nameof(AccessLogCacheJob))
.Build();
//每10秒执行一次将本地缓存转入redis防止丢数据
Trigger = TriggerBuilder.Create().WithIdentity(nameof(AccessLogCacheJob))
.WithSimpleSchedule((schedule) => { schedule.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever();; })
.Build();
}
public override async Task Execute(IJobExecutionContext context)
{
await _localEventBus.PublishAsync(new AccessLogResetArgs());
}
}

View File

@@ -81,7 +81,7 @@ public class AccessLogStoreJob : QuartzBackgroundWorkerBase
}
//删除前一天的缓存
await RedisClient.DelAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1)}");
await RedisClient.DelAsync($"{CacheKeyPrefix}:{AccessLogCacheConst.Key}:{DateTime.Now.Date.AddDays(-1).ToString("yyyyMMdd")}");
}
}
}

View File

@@ -0,0 +1,6 @@
namespace Yi.Framework.Bbs.Domain.Shared.Etos;
public class AccessLogResetArgs
{
}

View File

@@ -20,7 +20,7 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Menu
public string? Remark { get; set; }
public string? Component { get; set; }
public string? Query { get; set; }
public string? RouterName { get; set; }
public int OrderNum { get; set; }
//public List<MenuEntity>? Children { get; set; }
}

View File

@@ -24,6 +24,8 @@ namespace Yi.Framework.Rbac.Application.Contracts.Dtos.Menu
public int OrderNum { get; set; }
public string? RouterName { get; set; }
//public List<MenuEntity>? Children { get; set; }
}
}

View File

@@ -20,12 +20,12 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog
public override async Task<PagedResultDto<LoginLogGetListOutputDto>> GetListAsync(LoginLogGetListInputVo input)
{
RefAsync<int> total = 0;
if (input.Sorting.IsNullOrWhiteSpace())
input.Sorting = $"{nameof(LoginLogAggregateRoot.CreationTime)} Desc";
//if (input.Sorting.IsNullOrWhiteSpace())
// input.Sorting = $"{nameof(LoginLogAggregateRoot.CreationTime)} Desc";
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.LoginIp), x => x.LoginIp.Contains(input.LoginIp!))
.WhereIF(!string.IsNullOrEmpty(input.LoginUser), x => x.LoginUser!.Contains(input.LoginUser!))
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.OrderBy(input.Sorting)
.OrderByDescending(it => it.CreationTime) //降序
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<LoginLogGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
}

View File

@@ -24,12 +24,12 @@ namespace Yi.Framework.Rbac.Application.Services.RecordLog
public override async Task<PagedResultDto<OperationLogGetListOutputDto>> GetListAsync(OperationLogGetListInputVo input)
{
RefAsync<int> total = 0;
if (input.Sorting.IsNullOrWhiteSpace())
input.Sorting = $"{nameof(OperationLogEntity.CreationTime)} Desc";
//if (input.Sorting.IsNullOrWhiteSpace())
// input.Sorting = $"{nameof(OperationLogEntity.CreationTime)} Desc";
var entities = await _repository._DbQueryable.WhereIF(!string.IsNullOrEmpty(input.OperUser), x => x.OperUser.Contains(input.OperUser!))
.WhereIF(input.OperType is not null, x => x.OperType == input.OperType)
.WhereIF(input.StartTime is not null && input.EndTime is not null, x => x.CreationTime >= input.StartTime && x.CreationTime <= input.EndTime)
.OrderBy(input.Sorting)
.OrderByDescending(it => it.CreationTime) //降序
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
return new PagedResultDto<OperationLogGetListOutputDto>(total, await MapToGetListOutputDtosAsync(entities));
}

View File

@@ -63,12 +63,12 @@ namespace Yi.Framework.Rbac.Domain.Entities
/// <summary>
/// 部门名称
///</summary>
public string DeptName { get; set; } = string.Empty;
public string DeptName { get; set; }
/// <summary>
/// 部门编码
///</summary>
[SugarColumn(ColumnName = "DeptCode")]
public string DeptCode { get; set; } = string.Empty;
public string DeptCode { get; set; }
/// <summary>
/// 负责人
///</summary>

View File

@@ -41,7 +41,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot shenzhenDept = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "SZ",
DeptName = "深圳总公司",
OrderNum = 100,
IsDeleted = false,
@@ -52,7 +52,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot jiangxiDept = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "JX",
DeptName = "江西总公司",
OrderNum = 100,
IsDeleted = false,
@@ -64,7 +64,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept1 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "YF",
DeptName = "研发部门",
OrderNum = 100,
IsDeleted = false,
@@ -74,7 +74,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept2 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "SC",
DeptName = "市场部门",
OrderNum = 100,
IsDeleted = false,
@@ -84,7 +84,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept3 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "CS",
DeptName = "测试部门",
OrderNum = 100,
IsDeleted = false,
@@ -94,7 +94,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept4 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "CW",
DeptName = "财务部门",
OrderNum = 100,
IsDeleted = false,
@@ -104,7 +104,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot szDept5 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "YW",
DeptName = "运维部门",
OrderNum = 100,
IsDeleted = false,
@@ -115,7 +115,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot jxDept1 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "SC",
DeptName = "市场部门",
OrderNum = 100,
IsDeleted = false,
@@ -126,7 +126,7 @@ namespace Yi.Framework.Rbac.SqlSugarCore.DataSeeds
DeptAggregateRoot jxDept2 = new DeptAggregateRoot(_guidGenerator.Create())
{
DeptCode = "CW2",
DeptName = "财务部门",
OrderNum = 100,
IsDeleted = false,

View File

@@ -91,13 +91,28 @@ defineExpose({ getRef });
<re-col
v-show="newFormInline.menuType !== 2"
:value="24"
:xs="24"
:sm="24"
:xs="12"
:sm="12"
>
<el-form-item label="菜单图标">
<IconSelect v-model="newFormInline.menuIcon" class="w-full" />
</el-form-item>
</re-col>
<re-col
v-show="newFormInline.menuType !== 2"
:value="24"
:xs="12"
:sm="12"
>
<el-form-item label="路由名称">
<el-input
v-model="newFormInline.routerName"
clearable
placeholder="请输入菜单名称"
class="w-full"
/>
</el-form-item>
</re-col>
<re-col :value="12" :xs="24" :sm="24">
<el-form-item label="菜单名称" prop="menuName">
<el-input

View File

@@ -89,7 +89,7 @@ export function useMenu() {
{
label: "显示",
prop: "isShow",
formatter: ({ isShow }) => (isShow ? "" : ""),
formatter: ({ isShow }) => (isShow ? "" : ""),
width: 100
},
{

View File

@@ -9,6 +9,14 @@
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="部门编号" prop="deptCode">
<el-input
v-model="queryParams.deptCode"
placeholder="请输入部门编号"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="状态" prop="state">
<el-select v-model="queryParams.state" placeholder="部门状态" clearable>
<el-option
@@ -55,6 +63,7 @@
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
>
<el-table-column prop="deptName" label="部门名称" width="260"></el-table-column>
<el-table-column prop="deptCode" label="部门编号" width="200"></el-table-column>
<el-table-column prop="orderNum" label="排序" width="200"></el-table-column>
<el-table-column prop="state" label="状态" width="100">
<template #default="scope">
@@ -112,6 +121,11 @@
<el-input v-model="form.deptName" placeholder="请输入部门名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="部门编号" prop="deptCode">
<el-input v-model="form.deptCode" placeholder="部门编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="显示排序" prop="orderNum">
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
@@ -173,11 +187,13 @@ const refreshTable = ref(true);
const data = reactive({
form: {},
queryParams: {
deptCode:undefined,
deptName: undefined,
state: undefined
},
rules: {
parentId: [{ required: true, message: "上级部门不能为空", trigger: "blur" }],
deptCode: [{ required: true, message: "部门编号不能为空", trigger: "blur" }],
deptName: [{ required: true, message: "部门名称不能为空", trigger: "blur" }],
orderNum: [{ required: true, message: "显示排序不能为空", trigger: "blur" }],
email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }],