mirror of
https://gitee.com/ccnetcore/Yi
synced 2026-03-02 15:50:54 +08:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a50c45f7a3 | ||
|
|
2bc8837155 | ||
|
|
8a6e5abf48 | ||
|
|
8b191330b8 | ||
|
|
0d2f2cb826 | ||
|
|
571df74c43 | ||
|
|
cefde6848d | ||
|
|
551597765c | ||
|
|
5eaffe2ec2 | ||
|
|
2ec7b5f4fd | ||
|
|
4521212a90 | ||
|
|
94834f45c3 | ||
|
|
22ac150acd | ||
|
|
1cc5f2a14f | ||
|
|
d9997eeb28 | ||
|
|
06e77aa8fd | ||
|
|
e9e2228f6e | ||
|
|
d516a381d0 | ||
|
|
4e792ba976 | ||
|
|
f90d3871fa | ||
|
|
6005b9329d | ||
|
|
9d4b3e7d0c | ||
|
|
72795382a1 | ||
|
|
35cdff2afa | ||
|
|
dcf547f513 | ||
|
|
8660d45f36 | ||
|
|
63dd55e7a4 | ||
|
|
40cd89f90c |
10
README.md
10
README.md
@@ -7,6 +7,12 @@
|
||||
[](https://gitee.com/ccnetcore/Yi)
|
||||
[](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)
|
||||
|
||||
## 🍏 支持:
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -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" />
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -40,7 +40,8 @@
|
||||
"EnabledDbSeed": true,
|
||||
"EnableUnderLine": false, // 启用驼峰转下划线
|
||||
//SAAS多租户
|
||||
"EnabledSaasMultiTenancy": true
|
||||
"EnabledSaasMultiTenancy": true,
|
||||
"EnabledConcurrencyException": false
|
||||
//读写分离地址
|
||||
//"ReadUrl": [
|
||||
// "DataSource=[xxxx]", //Sqlite
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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
BIN
readme/edgeone.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Reference in New Issue
Block a user