Compare commits

...

28 Commits
alipay ... abp

Author SHA1 Message Date
橙子
a50c45f7a3 !102 修正删除部门无效问题
Merge pull request !102 from Po/cherry-pick-1765609320
2025-12-14 04:37:59 +00:00
Po
2bc8837155 修正删除部门无效问题 2025-12-13 07:02:19 +00:00
ccnetcore
8a6e5abf48 fix: 修复token鉴权 2025-12-11 23:32:57 +08:00
ccnetcore
8b191330b8 Revert "fix: 仅从 Query 获取 access_token/refresh_token,简化 OnMessageReceived 逻辑"
This reverts commit 0d2f2cb826.
2025-12-11 23:31:29 +08:00
chenchun
0d2f2cb826 fix: 仅从 Query 获取 access_token/refresh_token,简化 OnMessageReceived 逻辑
- 修改文件:Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs
- 将 JwtBearerEvents.OnMessageReceived 的上下文参数名改为 messageContext,统一变量名。
- 简化 Token 获取逻辑:只从 request.Query 中读取 access_token 与 refresh_token,移除从 Cookies(Token)和请求头(refresh_token)读取的分支。
2025-12-11 17:41:38 +08:00
chenchun
571df74c43 chore: 在 common.props 添加 SatelliteResourceLanguages=en;zh-CN
在 Yi.Abp.Net8/common.props 中新增 SatelliteResourceLanguages 属性,指定生成卫星资源语言为 en 和 zh-CN,以便打包对应的本地化资源。
2025-12-10 15:53:18 +08:00
chenchun
cefde6848d perf: 去除35MB又臭又大的腾讯云sdk 2025-12-10 15:10:54 +08:00
ccnetcore
551597765c perf: 优化sqlsguar分页查询 2025-12-07 18:50:02 +08:00
chenchun
5eaffe2ec2 feat: 新增更新并发乐观锁配置与支持
- 在 DbConnOptions 新增 EnabledConcurrencyException(bool,默认 false) 配置项。
- 在 SqlSugarRepository 引入 IAbpLazyServiceProvider,通过 IOptions<DbConnOptions> 延迟获取配置。
- UpdateAsync 改为仅当 EnabledConcurrencyException 为 true 且实体实现 IHasConcurrencyStamp 时,使用 ExecuteCommandWithOptLockAsync 并捕获 VersionExceptions 抛出 AbpDbConcurrencyException;否则回退到原有的 UpdateAsync 实现。
- 清理/调整部分 using 引用,新增 Microsoft.Extensions.Options 与 Volo.Abp.DependencyInjection 引用。

注意:默认值为 false,需在配置中显式开启 EnabledConcurrencyException 才会启用乐观并发校验,开启后会改变之前对带版本实体自动使用乐观锁的行为。
2025-11-17 11:19:15 +08:00
chenchun
2ec7b5f4fd fix: 修复软删除时空引用异常
在 SqlSugarRepository.cs 中对 ISoftDelete 分支增加 GetByIdAsync 返回 null 的判断,避免在实体为 null 时继续反射赋值导致 NullReferenceException。若实体不存在,直接返回 false。
2025-11-13 16:49:44 +08:00
chenchun
4521212a90 feat: 新增文件缓存功能
- 在 Yi.Framework.Rbac.Application.Services.FileService 中注入 IMemoryCache,用于缓存文件元数据,减少对仓储的重复读取。
  - 在 Get 方法中通过 key "File:{code}" 缓存 FileCacheItem,设置绝对过期时间为 1 天。
  - 缓存项使用 Mapster 适配为 FileCacheItem,再适配回 FileAggregateRoot(保留现有逻辑判断和路径获取)。
- 新增缓存模型 Yi.Framework.Rbac.Domain.Shared.Caches.FileCacheItem(包含 Id、FileSize、FileName、FilePath、创建/修改信息等)。
- 增加并调整相关 using 引用(Microsoft.Extensions.Caching.Memory、Volo.Abp.Caching、Domain.Shared.Caches)。
- 同时修复了保存多文件时的缩进/空格格式(不影响功能)。
2025-11-06 11:29:21 +08:00
chenchun
94834f45c3 perf: 使用 FileStreamResult 流式返回文件,避免一次性读取到内存
改为 FileStream 并返回 FileStreamResult,减小内存占用并支持大型文件;修正变量名拼写并添加 null-forgiving 标记。
2025-11-06 11:13:50 +08:00
chenchun
22ac150acd fix: 修正 FileAggregateRoot.FilePath 的赋值,保存目录路径而非包含文件名的完整路径 2025-11-06 10:58:33 +08:00
ccnetcore
1cc5f2a14f refactor: 注释掉 Furion 统一结果 API 注册,保留 ABP 默认处理方式 2025-09-27 17:26:13 +08:00
橙子
d9997eeb28 !100 update Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/UnifyResult/Fiters/FriendlyExceptionFilter.cs.
Merge pull request !100 from Gary/N/A
2025-09-22 07:14:02 +00:00
Gary
06e77aa8fd update Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/UnifyResult/Fiters/FriendlyExceptionFilter.cs.
判断是否为模型验证错误,如果是,将errors传回,并打印日志

Signed-off-by: Gary <1511313969@qq.com>
2025-09-22 07:13:46 +00:00
橙子
e9e2228f6e !97 岗位状态修改
Merge pull request !97 from 嗳摸嫫/jun
2025-09-22 07:13:45 +00:00
橙子
d516a381d0 !98 update Yi.Abp.Net8/framework/Yi.Framework.Mapster/YiFrameworkMapsterModule.cs.
Merge pull request !98 from Gary/N/A
2025-09-22 07:13:26 +00:00
Gary
4e792ba976 update Yi.Abp.Net8/framework/Yi.Framework.Mapster/YiFrameworkMapsterModule.cs.
自动扫描所有继承IRegister 的Mapster 配置

Signed-off-by: Gary <1511313969@qq.com>
2025-09-22 02:58:59 +00:00
chenchun
f90d3871fa feat: 启用 Furion 统一返回结果并优化过滤器配置
- 在 `YiAbpWebModule` 中启用 `AddFurionUnifyResultApi` 以支持 Furion 风格的统一 API 返回格式
- 调整 `UnifyResultExtensions`,移除 `AbpExceptionFilter` 和 `AbpNoContentActionFilter`,确保统一结果过滤器优先执行
2025-09-16 11:48:36 +08:00
HW-July
6005b9329d 岗位状态修改 2025-08-25 17:12:18 +08:00
橙子
9d4b3e7d0c update README.md.
Signed-off-by: 橙子 <454313500@qq.com>
2025-07-05 07:50:10 +00:00
chenchun
72795382a1 style: 调整样式 2025-07-02 15:03:16 +08:00
橙子
35cdff2afa update README.md.
Signed-off-by: 橙子 <454313500@qq.com>
2025-07-02 06:04:18 +00:00
橙子
dcf547f513 style: 新增赞助
Signed-off-by: 橙子 <454313500@qq.com>
2025-07-02 06:03:28 +00:00
橙子
8660d45f36 update README.md.
Signed-off-by: 橙子 <454313500@qq.com>
2025-07-02 06:01:51 +00:00
橙子
63dd55e7a4 !95 修正分页导致部门结构显示异常。取消后台分页功能,同菜单结构无需分页。
Merge pull request !95 from Po/N/A
2025-07-02 03:49:56 +00:00
Po
40cd89f90c 修正分页导致部门结构显示异常。取消后台分页功能,同菜单结构无需分页。
Signed-off-by: Po <448443959@qq.com>
2025-07-02 02:50:06 +00:00
24 changed files with 227 additions and 139 deletions

View File

@@ -7,6 +7,12 @@
[![fork](https://gitee.com/ccnetcore/yi/badge/fork.svg?theme=dark)](https://gitee.com/ccnetcore/Yi)
[![license](https://img.shields.io/badge/license-MIT-yellow)](https://gitee.com/ccnetcore/Yi)
本项目 CDN 加速及安全防护由 Tencent EdgeOne 赞助
[亚洲最佳CDN、边缘和安全解决方案 - Tencent EdgeOne](https://edgeone.ai/zh?from=github)
<img src="readme/edgeone.png"/>
[English](README-en.md) | 简体中文
****
## 🍍 简介:
@@ -60,9 +66,9 @@ bbs前端`docker run -d --name yi.bbs -p 18001:18001 -v /home/Yi/Yi.Bbs.Vue3/
Yi社区官网网址Bbs社区正式[ccnetcore.com](https://ccnetcore.com) (已上线,欢迎加入)
Rbac后台演示地址https://ccnetcore.com:1000 用户cc、密码123456
Rbac后台演示地址https://data.ccnetcore.com:1000 用户cc、密码123456
Pure后台演示地址https://ccnetcore.com:1001 用户cc、密码123456
Pure后台演示地址https://data.ccnetcore.com:1001 用户cc、密码123456
## 🍏 支持:

View File

@@ -12,6 +12,7 @@
</PropertyGroup>
<PropertyGroup>
<SatelliteResourceLanguages>en;zh-CN</SatelliteResourceLanguages>
<LangVersion>latest</LangVersion>
<Version>1.0.0</Version>
<NoWarn>$(NoWarn);CS1591;CS8618;CS1998;CS8604;CS8620;CS8600;CS8602</NoWarn>

View File

@@ -1,4 +1,4 @@
// MIT 许可证
// MIT 许可证
//
// 版权 © 2020-present 百小僧, 百签科技(广东)有限公司 和所有贡献者
//
@@ -17,25 +17,25 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Validation;
using Yi.Framework.Core.Extensions;
namespace Yi.Framework.AspNetCore.UnifyResult.Fiters;
/// <summary>
/// 友好异常拦截器
/// 友好异常拦截器
/// </summary>
public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
{
/// <summary>
/// 异常拦截
/// 异常拦截
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task OnExceptionAsync(ExceptionContext context)
{
// 排除 WebSocket 请求处理
if (context.HttpContext.IsWebSocketRequest()) return;
@@ -44,20 +44,23 @@ public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
// 解析异常信息
var exceptionMetadata = GetExceptionMetadata(context);
IUnifyResultProvider unifyResult = context.GetRequiredService<IUnifyResultProvider>();
var unifyResult = context.GetRequiredService<IUnifyResultProvider>();
// 执行规范化异常处理
context.Result = unifyResult.OnException(context, exceptionMetadata);
// 创建日志记录器
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<FriendlyExceptionFilter>>();
var errorMsg = "";
if (exceptionMetadata.Errors != null) errorMsg = "\n" + JsonConvert.SerializeObject(exceptionMetadata.Errors);
// 记录拦截日常
logger.LogError(context.Exception, context.Exception.Message);
logger.LogError(context.Exception, context.Exception.Message + errorMsg);
}
/// <summary>
/// 获取异常元数据
/// 获取异常元数据
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
@@ -74,22 +77,25 @@ public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
// 判断是否是 ExceptionContext 或者 ActionExecutedContext
var exception = context is ExceptionContext exContext
? exContext.Exception
: (
context is ActionExecutedContext edContext
? edContext.Exception
: default
);
: context is ActionExecutedContext edContext
? edContext.Exception
: default;
if (exception is AbpValidationException validationException)
{
errors = validationException.ValidationErrors;
isValidationException = true;
}
// 判断是否是友好异常
if (exception is UserFriendlyException friendlyException)
{
int statusCode2 = 500;
var statusCode2 = 500;
int.TryParse(friendlyException.Code, out statusCode2);
isFriendlyException = true;
errorCode = friendlyException.Code;
originErrorCode = friendlyException.Code;
statusCode = statusCode2==0?403:statusCode2;
isValidationException = false;
statusCode = statusCode2 == 0 ? 403 : statusCode2;
errors = friendlyException.Message;
data = friendlyException.Data;
}

View File

@@ -2,6 +2,7 @@
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.SwaggerGen;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.Mvc.Response;
using Yi.Framework.AspNetCore.UnifyResult.Fiters;
namespace Yi.Framework.AspNetCore.UnifyResult;
@@ -20,9 +21,10 @@ public static class UnifyResultExtensions
services.AddTransient<FriendlyExceptionFilter>();
services.AddMvc(options =>
{
options.Filters.RemoveAll(x => (x as ServiceFilterAttribute)?.ServiceType == typeof(AbpExceptionFilter));
options.Filters.RemoveAll(x => (x as ServiceFilterAttribute)?.ServiceType == typeof(AbpNoContentActionFilter));
options.Filters.AddService<SucceededUnifyResultFilter>(99);
options.Filters.AddService<FriendlyExceptionFilter>(100);
options.Filters.RemoveAll(x => (x as ServiceFilterAttribute)?.ServiceType == typeof(AbpExceptionFilter));
});
return services;
}

View File

@@ -1,7 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectMapping;
using Yi.Framework.Core;
using Mapster;
namespace Yi.Framework.Mapster
{
@@ -22,7 +23,8 @@ namespace Yi.Framework.Mapster
public override void ConfigureServices(ServiceConfigurationContext context)
{
var services = context.Services;
// 扫描并注册所有映射配置
TypeAdapterConfig.GlobalSettings.Scan(AppDomain.CurrentDomain.GetAssemblies());
// 注册Mapster相关服务
services.AddTransient<IAutoObjectMappingProvider, MapsterAutoObjectMappingProvider>();
services.AddTransient<IObjectMapper, MapsterObjectMapper>();

View File

@@ -58,5 +58,10 @@ namespace Yi.Framework.SqlSugarCore.Abstractions
/// 是否启用SaaS多租户
/// </summary>
public bool EnabledSaasMultiTenancy { get; set; } = false;
/// <summary>
/// 是否开启更新并发乐观锁
/// </summary>
public bool EnabledConcurrencyException { get;set; } = false;
}
}

View File

@@ -1,12 +1,9 @@
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Microsoft.Extensions.Logging;
using System.Linq.Expressions;
using Microsoft.Extensions.Options;
using Nito.AsyncEx;
using SqlSugar;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
@@ -17,12 +14,17 @@ namespace Yi.Framework.SqlSugarCore.Repositories
{
public class SqlSugarRepository<TEntity> : ISqlSugarRepository<TEntity>, IRepository<TEntity> where TEntity : class, IEntity, new()
{
[Obsolete("使用GetDbContextAsync()")]
public ISqlSugarClient _Db => AsyncContext.Run(async () => await GetDbContextAsync());
[Obsolete("使用AsQueryable()")]
public ISugarQueryable<TEntity> _DbQueryable => _Db.Queryable<TEntity>();
private readonly ISugarDbContextProvider<ISqlSugarDbContext> _dbContextProvider;
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
protected DbConnOptions? Options => LazyServiceProvider?.LazyGetService<IOptions<DbConnOptions>>().Value;
/// <summary>
/// 异步查询执行器
/// </summary>
@@ -264,6 +266,7 @@ namespace Yi.Framework.SqlSugarCore.Repositories
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
{
var entity = await GetByIdAsync(id);
if (entity == null) return false;
//反射赋值
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity);
return await UpdateAsync(entity);
@@ -319,12 +322,12 @@ namespace Yi.Framework.SqlSugarCore.Repositories
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize)
{
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, new PageModel() { PageIndex = pageNum, PageSize = pageSize });
return await (await AsQueryable()).Where(whereExpression).ToPageListAsync(pageNum, pageSize);
}
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize, Expression<Func<TEntity, object>>? orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
{
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, new PageModel { PageIndex = pageNum, PageSize = pageSize }, orderByExpression, orderByType);
return await (await AsQueryable()).Where(whereExpression) .OrderBy( orderByExpression,orderByType).ToPageListAsync(pageNum, pageSize);
}
public virtual async Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> whereExpression)
@@ -379,20 +382,24 @@ namespace Yi.Framework.SqlSugarCore.Repositories
public virtual async Task<bool> UpdateAsync(TEntity updateObj)
{
if (typeof(TEntity).IsAssignableTo<IHasConcurrencyStamp>())//带版本号乐观锁更新
if (Options is not null && Options.EnabledConcurrencyException)
{
try
if (typeof(TEntity).IsAssignableTo<IHasConcurrencyStamp>()) //带版本号乐观锁更新
{
int num = await (await GetDbSimpleClientAsync())
.Context.Updateable(updateObj).ExecuteCommandWithOptLockAsync(true);
return num>0;
}
catch (VersionExceptions ex)
{
throw new AbpDbConcurrencyException($"{ex.Message}[更新失败ConcurrencyStamp不是最新版本],entityInfo{updateObj}", ex);
try
{
int num = await (await GetDbSimpleClientAsync())
.Context.Updateable(updateObj).ExecuteCommandWithOptLockAsync(true);
return num > 0;
}
catch (VersionExceptions ex)
{
throw new AbpDbConcurrencyException(
$"{ex.Message}[更新失败ConcurrencyStamp不是最新版本],entityInfo{updateObj}", ex);
}
}
}
return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj);
}

View File

@@ -3,7 +3,6 @@ using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using TencentCloud.Pds.V20210701.Models;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.EventBus.Local;

View File

@@ -1,5 +1,4 @@
using TencentCloud.Tbm.V20180129.Models;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities.Events;
using Volo.Abp.EventBus;
using Volo.Abp.EventBus.Local;

View File

@@ -6,8 +6,10 @@ using System.Threading.Tasks;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Volo.Abp;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
using Yi.Framework.Core.Enums;
@@ -16,6 +18,7 @@ using Yi.Framework.Rbac.Application.Contracts.Dtos.FileManager;
using Yi.Framework.Rbac.Application.Contracts.IServices;
using Yi.Framework.Rbac.Domain.Entities;
using Yi.Framework.Rbac.Domain.Managers;
using Yi.Framework.Rbac.Domain.Shared.Caches;
namespace Yi.Framework.Rbac.Application.Services
{
@@ -23,11 +26,13 @@ namespace Yi.Framework.Rbac.Application.Services
{
private readonly IRepository<FileAggregateRoot> _repository;
private readonly FileManager _fileManager;
private readonly IMemoryCache _memoryCache;
public FileService(IRepository<FileAggregateRoot> repository, FileManager fileManager)
public FileService(IRepository<FileAggregateRoot> repository, FileManager fileManager, IMemoryCache memoryCache)
{
_repository = repository;
_fileManager = fileManager;
_memoryCache = memoryCache;
}
/// <summary>
@@ -37,14 +42,22 @@ namespace Yi.Framework.Rbac.Application.Services
[Route("file/{code}/{isThumbnail?}")]
public async Task<IActionResult> Get([FromRoute] Guid code, [FromRoute] bool? isThumbnail)
{
var file = await _repository.GetAsync(x => x.Id == code);
var fileCache = await _memoryCache.GetOrCreateAsync($"File:{code}", async (options) =>
{
options.AbsoluteExpiration = DateTime.Now.AddDays(1);
var file = await _repository.GetAsync(x => x.Id == code);
if (file == null!) return null;
return file.Adapt<FileCacheItem>();
});
var file = fileCache?.Adapt<FileAggregateRoot>();
var path = file?.GetQueryFileSavePath(isThumbnail);
if (path is null || !File.Exists(path))
{
return new NotFoundResult();
}
var steam = await File.ReadAllBytesAsync(path);
return new FileContentResult(steam, file.GetMimeMapping());
var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
return new FileStreamResult(stream, file!.GetMimeMapping());
}
/// <summary>
@@ -57,12 +70,13 @@ namespace Yi.Framework.Rbac.Application.Services
for (int i = 0; i < file.Count; i++)
{
var entity= entities[i];
using (var steam = file[i].OpenReadStream())
{
await _fileManager.SaveFileAsync(entity,steam);
}
var entity = entities[i];
using (var steam = file[i].OpenReadStream())
{
await _fileManager.SaveFileAsync(entity, steam);
}
}
return entities.Adapt<List<FileGetListOutputDto>>();
}
}

View File

@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using Microsoft.VisualBasic;
using TencentCloud.Mna.V20210119.Models;
using Volo.Abp.Application.Services;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;

View File

@@ -51,7 +51,7 @@ namespace Yi.Framework.Rbac.Application.Services.System
.WhereIF(!string.IsNullOrEmpty(input.DeptName), u => u.DeptName.Contains(input.DeptName!))
.WhereIF(input.State is not null, u => u.State == input.State)
.OrderBy(u => u.OrderNum, OrderByType.Asc)
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
.ToListAsync();
return new PagedResultDto<DeptGetListOutputDto>
{
Items = await MapToGetListOutputDtosAsync(entities),

View File

@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Yi.Framework.Ddd.Application;
@@ -54,5 +55,25 @@ namespace Yi.Framework.Rbac.Application.Services.System
throw new UserFriendlyException(RoleConst.Exist);
}
}
/// <summary>
/// 更新状态
/// </summary>
/// <param name="id"></param>
/// <param name="state"></param>
/// <returns></returns>
[Route("post/{id}/{state}")]
public async Task<PostGetOutputDto> UpdateStateAsync([FromRoute] Guid id, [FromRoute] bool state)
{
var entity = await _repository.GetByIdAsync(id);
if (entity is null)
{
throw new ApplicationException("岗位未存在");
}
entity.State = state;
await _repository.UpdateAsync(entity);
return await MapToGetOutputDtoAsync(entity);
}
}
}

View File

@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using TencentCloud.Tcr.V20190924.Models;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Caching;

View File

@@ -0,0 +1,29 @@
namespace Yi.Framework.Rbac.Domain.Shared.Caches;
public class FileCacheItem
{
public Guid Id { get; set; }
/// <summary>
/// 文件大小
///</summary>
public decimal FileSize { get; set; }
/// <summary>
/// 文件名
///</summary>
public string FileName { get; set; }
/// <summary>
/// 文件路径
///</summary>
public string FilePath { get; set; }
public DateTime CreationTime { get; set; }
public Guid? CreatorId { get; set; }
public Guid? LastModifierId { get; set; }
public DateTime? LastModificationTime { get; set; }
}

View File

@@ -34,8 +34,7 @@ namespace Yi.Framework.Rbac.Domain.Entities
var type = GetFileType();
var savePath = GetSaveFilePath();
var filePath = Path.Combine(savePath, this.FileName);
this.FilePath = filePath;
this.FilePath = savePath;
}
/// <summary>

View File

@@ -1,59 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TencentCloud.Common.Profile;
using TencentCloud.Common;
using TencentCloud.Sms.V20210111.Models;
using TencentCloud.Sms.V20210111;
using Volo.Abp.Domain.Services;
using Microsoft.Extensions.Logging;
namespace Yi.Framework.Rbac.Domain.Managers
{
public class TencentCloudManager : DomainService
{
private ILogger<TencentCloudManager> _logger;
public TencentCloudManager(ILogger<TencentCloudManager> logger)
{
_logger= logger;
}
public async Task SendSmsAsync()
{
try
{
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
Credential cred = new Credential
{
SecretId = "SecretId",
SecretKey = "SecretKey"
};
// 实例化一个client选项可选的没有特殊需求可以跳过
ClientProfile clientProfile = new ClientProfile();
// 实例化一个http选项可选的没有特殊需求可以跳过
HttpProfile httpProfile = new HttpProfile();
httpProfile.Endpoint = ("sms.tencentcloudapi.com");
clientProfile.HttpProfile = httpProfile;
// 实例化要请求产品的client对象,clientProfile是可选的
SmsClient client = new SmsClient(cred, "", clientProfile);
// 实例化一个请求对象,每个接口都会对应一个request对象
SendSmsRequest req = new SendSmsRequest();
// 返回的resp是一个SendSmsResponse的实例与请求对象对应
SendSmsResponse resp = await client.SendSms(req);
// 输出json格式的字符串回包
_logger.LogInformation("腾讯云Sms返回"+AbstractModel.ToJsonString(resp));
}
catch (Exception e)
{
_logger.LogError(e,e.ToString());
}
}
}
}
// using System;
// using System.Collections.Generic;
// using System.Linq;
// using System.Text;
// using System.Threading.Tasks;
// using TencentCloud.Common.Profile;
// using TencentCloud.Common;
// using TencentCloud.Sms.V20210111.Models;
// using TencentCloud.Sms.V20210111;
// using Volo.Abp.Domain.Services;
// using Microsoft.Extensions.Logging;
//
// namespace Yi.Framework.Rbac.Domain.Managers
// {
// public class TencentCloudManager : DomainService
// {
// private ILogger<TencentCloudManager> _logger;
// public TencentCloudManager(ILogger<TencentCloudManager> logger)
// {
// _logger= logger;
// }
//
// public async Task SendSmsAsync()
// {
//
// try
// {
// // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey此处还需注意密钥对的保密
// // 代码泄露可能会导致 SecretId 和 SecretKey 泄露并威胁账号下所有资源的安全性。以下代码示例仅供参考建议采用更安全的方式来使用密钥请参见https://cloud.tencent.com/document/product/1278/85305
// // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
// Credential cred = new Credential
// {
// SecretId = "SecretId",
// SecretKey = "SecretKey"
// };
// // 实例化一个client选项可选的没有特殊需求可以跳过
// ClientProfile clientProfile = new ClientProfile();
// // 实例化一个http选项可选的没有特殊需求可以跳过
// HttpProfile httpProfile = new HttpProfile();
// httpProfile.Endpoint = ("sms.tencentcloudapi.com");
// clientProfile.HttpProfile = httpProfile;
//
// // 实例化要请求产品的client对象,clientProfile是可选的
// SmsClient client = new SmsClient(cred, "", clientProfile);
// // 实例化一个请求对象,每个接口都会对应一个request对象
// SendSmsRequest req = new SendSmsRequest();
//
// // 返回的resp是一个SendSmsResponse的实例与请求对象对应
// SendSmsResponse resp = await client.SendSms(req);
// // 输出json格式的字符串回包
// _logger.LogInformation("腾讯云Sms返回"+AbstractModel.ToJsonString(resp));
// }
// catch (Exception e)
// {
// _logger.LogError(e,e.ToString());
// }
// }
// }
// }

View File

@@ -8,7 +8,7 @@
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="TencentCloudSDK" Version="3.0.966" />
<!-- <PackageReference Include="TencentCloudSDK" Version="3.0.966" />-->
<PackageReference Include="UAParser" Version="3.1.47" />

View File

@@ -39,6 +39,7 @@ using Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
using Yi.Framework.AspNetCore.UnifyResult;
using Yi.Framework.BackgroundWorkers.Hangfire;
using Yi.Framework.Bbs.Application;
using Yi.Framework.Bbs.Application.Extensions;
@@ -130,6 +131,7 @@ namespace Yi.Abp.Web
});
//采用furion格式的规范化api默认不开启使用abp优雅的方式
//前置需要将管道工作单元前加上app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
//你没看错。。。
//service.AddFurionUnifyResultApi();
@@ -278,19 +280,19 @@ namespace Yi.Abp.Web
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
OnMessageReceived = messageContext =>
{
//优先Query中获取再去cookies中获取
var accessToken = context.Request.Query["access_token"];
var accessToken = messageContext.Request.Query["access_token"];
if (!string.IsNullOrEmpty(accessToken))
{
context.Token = accessToken;
messageContext.Token = accessToken;
}
else
{
if (context.Request.Cookies.TryGetValue("Token", out var cookiesToken))
if (messageContext.Request.Cookies.TryGetValue("Token", out var cookiesToken))
{
context.Token = cookiesToken;
messageContext.Token = cookiesToken;
}
}
@@ -311,19 +313,19 @@ namespace Yi.Abp.Web
};
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
OnMessageReceived = messageContext =>
{
var refresh_token = context.Request.Headers["refresh_token"];
if (!string.IsNullOrEmpty(refresh_token))
var headerRefreshToken = messageContext.Request.Headers["refresh_token"];
if (!string.IsNullOrEmpty(headerRefreshToken))
{
context.Token = refresh_token;
messageContext.Token = headerRefreshToken;
return Task.CompletedTask;
}
var refreshToken = context.Request.Query["refresh_token"];
if (!string.IsNullOrEmpty(refreshToken))
var queryRefreshToken = messageContext.Request.Query["refresh_token"];
if (!string.IsNullOrEmpty(queryRefreshToken))
{
context.Token = refreshToken;
messageContext.Token = queryRefreshToken;
}
return Task.CompletedTask;
@@ -393,8 +395,7 @@ namespace Yi.Abp.Web
app.UseDefaultFiles();
app.UseDirectoryBrowser("/api/app/wwwroot");
// app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
//app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
//工作单元
app.UseUnitOfWork();

View File

@@ -40,7 +40,8 @@
"EnabledDbSeed": true,
"EnableUnderLine": false, // 启用驼峰转下划线
//SAAS多租户
"EnabledSaasMultiTenancy": true
"EnabledSaasMultiTenancy": true,
"EnabledConcurrencyException": false
//读写分离地址
//"ReadUrl": [
// "DataSource=[xxxx]", //Sqlite

View File

@@ -1,7 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using TencentCloud.Ame.V20190916.Models;
using TencentCloud.Tiw.V20190919.Models;
using Volo.Abp.Domain.Repositories;
using Xunit;
using Yi.Framework.Rbac.Application.Contracts.Dtos.User;

View File

@@ -103,7 +103,7 @@ export function usePost() {
`确认要<strong>${
row.state === false ? "停用" : "启用"
}</strong><strong style='color:var(--el-color-primary)'>${
row.roleName
row.postName
}</strong>吗?`,
"系统提示",
{
@@ -132,7 +132,7 @@ export function usePost() {
loading: false
}
);
message(`${row.state === false ? "停用" : "启用"}${row.roleName}`, {
message(`${row.state === false ? "停用" : "启用"}${row.postName}`, {
type: "success"
});
})
@@ -143,7 +143,7 @@ export function usePost() {
async function handleDelete(row) {
await delPost([row.id]);
message(`您删除了角色名称为${row.roleName}的这条数据`, { type: "success" });
message(`您删除了岗位名称为${row.postName}的这条数据`, { type: "success" });
onSearch();
}

View File

@@ -50,7 +50,7 @@ export function delDept(deptId) {
return request({
url: `/dept`,
method: 'delete',
params:{id:deptId}
params:{ids:deptId}
})
}

BIN
readme/edgeone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB