mirror of
https://gitee.com/ccnetcore/Yi
synced 2026-04-24 02:16:36 +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)
|
||||||
[](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) | 简体中文
|
[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) (已上线,欢迎加入)
|
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>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
<SatelliteResourceLanguages>en;zh-CN</SatelliteResourceLanguages>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
<Version>1.0.0</Version>
|
<Version>1.0.0</Version>
|
||||||
<NoWarn>$(NoWarn);CS1591;CS8618;CS1998;CS8604;CS8620;CS8600;CS8602</NoWarn>
|
<NoWarn>$(NoWarn);CS1591;CS8618;CS1998;CS8604;CS8620;CS8600;CS8602</NoWarn>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// MIT 许可证
|
// MIT 许可证
|
||||||
//
|
//
|
||||||
// 版权 © 2020-present 百小僧, 百签科技(广东)有限公司 和所有贡献者
|
// 版权 © 2020-present 百小僧, 百签科技(广东)有限公司 和所有贡献者
|
||||||
//
|
//
|
||||||
@@ -17,25 +17,25 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using Volo.Abp.AspNetCore.Mvc;
|
using Volo.Abp.AspNetCore.Mvc;
|
||||||
using Volo.Abp.DependencyInjection;
|
using Volo.Abp.Validation;
|
||||||
using Yi.Framework.Core.Extensions;
|
using Yi.Framework.Core.Extensions;
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.UnifyResult.Fiters;
|
namespace Yi.Framework.AspNetCore.UnifyResult.Fiters;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 友好异常拦截器
|
/// 友好异常拦截器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
|
public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异常拦截
|
/// 异常拦截
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task OnExceptionAsync(ExceptionContext context)
|
public async Task OnExceptionAsync(ExceptionContext context)
|
||||||
{
|
{
|
||||||
|
|
||||||
// 排除 WebSocket 请求处理
|
// 排除 WebSocket 请求处理
|
||||||
if (context.HttpContext.IsWebSocketRequest()) return;
|
if (context.HttpContext.IsWebSocketRequest()) return;
|
||||||
|
|
||||||
@@ -44,20 +44,23 @@ public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
|
|||||||
|
|
||||||
// 解析异常信息
|
// 解析异常信息
|
||||||
var exceptionMetadata = GetExceptionMetadata(context);
|
var exceptionMetadata = GetExceptionMetadata(context);
|
||||||
|
var unifyResult = context.GetRequiredService<IUnifyResultProvider>();
|
||||||
IUnifyResultProvider unifyResult = context.GetRequiredService<IUnifyResultProvider>();
|
|
||||||
// 执行规范化异常处理
|
// 执行规范化异常处理
|
||||||
context.Result = unifyResult.OnException(context, exceptionMetadata);
|
context.Result = unifyResult.OnException(context, exceptionMetadata);
|
||||||
|
|
||||||
// 创建日志记录器
|
// 创建日志记录器
|
||||||
var logger = context.HttpContext.RequestServices.GetRequiredService<ILogger<FriendlyExceptionFilter>>();
|
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>
|
||||||
/// 获取异常元数据
|
/// 获取异常元数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
@@ -74,22 +77,25 @@ public sealed class FriendlyExceptionFilter : IAsyncExceptionFilter
|
|||||||
// 判断是否是 ExceptionContext 或者 ActionExecutedContext
|
// 判断是否是 ExceptionContext 或者 ActionExecutedContext
|
||||||
var exception = context is ExceptionContext exContext
|
var exception = context is ExceptionContext exContext
|
||||||
? exContext.Exception
|
? exContext.Exception
|
||||||
: (
|
: context is ActionExecutedContext edContext
|
||||||
context is ActionExecutedContext edContext
|
? edContext.Exception
|
||||||
? edContext.Exception
|
: default;
|
||||||
: default
|
|
||||||
);
|
if (exception is AbpValidationException validationException)
|
||||||
|
{
|
||||||
|
errors = validationException.ValidationErrors;
|
||||||
|
isValidationException = true;
|
||||||
|
}
|
||||||
|
|
||||||
// 判断是否是友好异常
|
// 判断是否是友好异常
|
||||||
if (exception is UserFriendlyException friendlyException)
|
if (exception is UserFriendlyException friendlyException)
|
||||||
{
|
{
|
||||||
int statusCode2 = 500;
|
var statusCode2 = 500;
|
||||||
int.TryParse(friendlyException.Code, out statusCode2);
|
int.TryParse(friendlyException.Code, out statusCode2);
|
||||||
isFriendlyException = true;
|
isFriendlyException = true;
|
||||||
errorCode = friendlyException.Code;
|
errorCode = friendlyException.Code;
|
||||||
originErrorCode = friendlyException.Code;
|
originErrorCode = friendlyException.Code;
|
||||||
statusCode = statusCode2==0?403:statusCode2;
|
statusCode = statusCode2 == 0 ? 403 : statusCode2;
|
||||||
isValidationException = false;
|
|
||||||
errors = friendlyException.Message;
|
errors = friendlyException.Message;
|
||||||
data = friendlyException.Data;
|
data = friendlyException.Data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
|
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
|
||||||
|
using Volo.Abp.AspNetCore.Mvc.Response;
|
||||||
using Yi.Framework.AspNetCore.UnifyResult.Fiters;
|
using Yi.Framework.AspNetCore.UnifyResult.Fiters;
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.UnifyResult;
|
namespace Yi.Framework.AspNetCore.UnifyResult;
|
||||||
@@ -20,9 +21,10 @@ public static class UnifyResultExtensions
|
|||||||
services.AddTransient<FriendlyExceptionFilter>();
|
services.AddTransient<FriendlyExceptionFilter>();
|
||||||
services.AddMvc(options =>
|
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<SucceededUnifyResultFilter>(99);
|
||||||
options.Filters.AddService<FriendlyExceptionFilter>(100);
|
options.Filters.AddService<FriendlyExceptionFilter>(100);
|
||||||
options.Filters.RemoveAll(x => (x as ServiceFilterAttribute)?.ServiceType == typeof(AbpExceptionFilter));
|
|
||||||
});
|
});
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Volo.Abp.Modularity;
|
using Volo.Abp.Modularity;
|
||||||
using Volo.Abp.ObjectMapping;
|
using Volo.Abp.ObjectMapping;
|
||||||
using Yi.Framework.Core;
|
using Yi.Framework.Core;
|
||||||
|
using Mapster;
|
||||||
|
|
||||||
namespace Yi.Framework.Mapster
|
namespace Yi.Framework.Mapster
|
||||||
{
|
{
|
||||||
@@ -22,7 +23,8 @@ namespace Yi.Framework.Mapster
|
|||||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
public override void ConfigureServices(ServiceConfigurationContext context)
|
||||||
{
|
{
|
||||||
var services = context.Services;
|
var services = context.Services;
|
||||||
|
// 扫描并注册所有映射配置
|
||||||
|
TypeAdapterConfig.GlobalSettings.Scan(AppDomain.CurrentDomain.GetAssemblies());
|
||||||
// 注册Mapster相关服务
|
// 注册Mapster相关服务
|
||||||
services.AddTransient<IAutoObjectMappingProvider, MapsterAutoObjectMappingProvider>();
|
services.AddTransient<IAutoObjectMappingProvider, MapsterAutoObjectMappingProvider>();
|
||||||
services.AddTransient<IObjectMapper, MapsterObjectMapper>();
|
services.AddTransient<IObjectMapper, MapsterObjectMapper>();
|
||||||
|
|||||||
@@ -58,5 +58,10 @@ namespace Yi.Framework.SqlSugarCore.Abstractions
|
|||||||
/// 是否启用SaaS多租户
|
/// 是否启用SaaS多租户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool EnabledSaasMultiTenancy { get; set; } = false;
|
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.Linq.Expressions;
|
using Microsoft.Extensions.Options;
|
||||||
using System.Text;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Nito.AsyncEx;
|
using Nito.AsyncEx;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.Auditing;
|
|
||||||
using Volo.Abp.Data;
|
using Volo.Abp.Data;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
using Volo.Abp.Domain.Entities;
|
using Volo.Abp.Domain.Entities;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Volo.Abp.Linq;
|
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()
|
public class SqlSugarRepository<TEntity> : ISqlSugarRepository<TEntity>, IRepository<TEntity> where TEntity : class, IEntity, new()
|
||||||
{
|
{
|
||||||
|
[Obsolete("使用GetDbContextAsync()")]
|
||||||
public ISqlSugarClient _Db => AsyncContext.Run(async () => await GetDbContextAsync());
|
public ISqlSugarClient _Db => AsyncContext.Run(async () => await GetDbContextAsync());
|
||||||
|
|
||||||
|
[Obsolete("使用AsQueryable()")]
|
||||||
public ISugarQueryable<TEntity> _DbQueryable => _Db.Queryable<TEntity>();
|
public ISugarQueryable<TEntity> _DbQueryable => _Db.Queryable<TEntity>();
|
||||||
|
|
||||||
private readonly ISugarDbContextProvider<ISqlSugarDbContext> _dbContextProvider;
|
private readonly ISugarDbContextProvider<ISqlSugarDbContext> _dbContextProvider;
|
||||||
|
|
||||||
|
public IAbpLazyServiceProvider LazyServiceProvider { get; set; }
|
||||||
|
|
||||||
|
protected DbConnOptions? Options => LazyServiceProvider?.LazyGetService<IOptions<DbConnOptions>>().Value;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步查询执行器
|
/// 异步查询执行器
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -264,6 +266,7 @@ namespace Yi.Framework.SqlSugarCore.Repositories
|
|||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
||||||
{
|
{
|
||||||
var entity = await GetByIdAsync(id);
|
var entity = await GetByIdAsync(id);
|
||||||
|
if (entity == null) return false;
|
||||||
//反射赋值
|
//反射赋值
|
||||||
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity);
|
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity);
|
||||||
return await UpdateAsync(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)
|
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)
|
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)
|
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)
|
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())
|
try
|
||||||
.Context.Updateable(updateObj).ExecuteCommandWithOptLockAsync(true);
|
{
|
||||||
return num>0;
|
int num = await (await GetDbSimpleClientAsync())
|
||||||
}
|
.Context.Updateable(updateObj).ExecuteCommandWithOptLockAsync(true);
|
||||||
catch (VersionExceptions ex)
|
return num > 0;
|
||||||
{
|
}
|
||||||
|
catch (VersionExceptions ex)
|
||||||
throw new AbpDbConcurrencyException($"{ex.Message}[更新失败:ConcurrencyStamp不是最新版本],entityInfo:{updateObj}", ex);
|
{
|
||||||
|
throw new AbpDbConcurrencyException(
|
||||||
|
$"{ex.Message}[更新失败:ConcurrencyStamp不是最新版本],entityInfo:{updateObj}", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj);
|
return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Mapster;
|
|||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using TencentCloud.Pds.V20210701.Models;
|
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
using Volo.Abp.Application.Dtos;
|
using Volo.Abp.Application.Dtos;
|
||||||
using Volo.Abp.EventBus.Local;
|
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.Domain.Entities.Events;
|
||||||
using Volo.Abp.EventBus;
|
using Volo.Abp.EventBus;
|
||||||
using Volo.Abp.EventBus.Local;
|
using Volo.Abp.EventBus.Local;
|
||||||
|
|||||||
@@ -6,8 +6,10 @@ using System.Threading.Tasks;
|
|||||||
using Mapster;
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
using Volo.Abp.Application.Services;
|
using Volo.Abp.Application.Services;
|
||||||
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Volo.Abp.Guids;
|
using Volo.Abp.Guids;
|
||||||
using Yi.Framework.Core.Enums;
|
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.Application.Contracts.IServices;
|
||||||
using Yi.Framework.Rbac.Domain.Entities;
|
using Yi.Framework.Rbac.Domain.Entities;
|
||||||
using Yi.Framework.Rbac.Domain.Managers;
|
using Yi.Framework.Rbac.Domain.Managers;
|
||||||
|
using Yi.Framework.Rbac.Domain.Shared.Caches;
|
||||||
|
|
||||||
namespace Yi.Framework.Rbac.Application.Services
|
namespace Yi.Framework.Rbac.Application.Services
|
||||||
{
|
{
|
||||||
@@ -23,11 +26,13 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
{
|
{
|
||||||
private readonly IRepository<FileAggregateRoot> _repository;
|
private readonly IRepository<FileAggregateRoot> _repository;
|
||||||
private readonly FileManager _fileManager;
|
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;
|
_repository = repository;
|
||||||
_fileManager = fileManager;
|
_fileManager = fileManager;
|
||||||
|
_memoryCache = memoryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -37,14 +42,22 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
[Route("file/{code}/{isThumbnail?}")]
|
[Route("file/{code}/{isThumbnail?}")]
|
||||||
public async Task<IActionResult> Get([FromRoute] Guid code, [FromRoute] bool? 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);
|
var path = file?.GetQueryFileSavePath(isThumbnail);
|
||||||
if (path is null || !File.Exists(path))
|
if (path is null || !File.Exists(path))
|
||||||
{
|
{
|
||||||
return new NotFoundResult();
|
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>
|
/// <summary>
|
||||||
@@ -57,12 +70,13 @@ namespace Yi.Framework.Rbac.Application.Services
|
|||||||
|
|
||||||
for (int i = 0; i < file.Count; i++)
|
for (int i = 0; i < file.Count; i++)
|
||||||
{
|
{
|
||||||
var entity= entities[i];
|
var entity = entities[i];
|
||||||
using (var steam = file[i].OpenReadStream())
|
using (var steam = file[i].OpenReadStream())
|
||||||
{
|
{
|
||||||
await _fileManager.SaveFileAsync(entity,steam);
|
await _fileManager.SaveFileAsync(entity, steam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return entities.Adapt<List<FileGetListOutputDto>>();
|
return entities.Adapt<List<FileGetListOutputDto>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Microsoft.VisualBasic;
|
using Microsoft.VisualBasic;
|
||||||
using TencentCloud.Mna.V20210119.Models;
|
|
||||||
using Volo.Abp.Application.Services;
|
using Volo.Abp.Application.Services;
|
||||||
using Volo.Abp.Caching;
|
using Volo.Abp.Caching;
|
||||||
using Volo.Abp.DependencyInjection;
|
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(!string.IsNullOrEmpty(input.DeptName), u => u.DeptName.Contains(input.DeptName!))
|
||||||
.WhereIF(input.State is not null, u => u.State == input.State)
|
.WhereIF(input.State is not null, u => u.State == input.State)
|
||||||
.OrderBy(u => u.OrderNum, OrderByType.Asc)
|
.OrderBy(u => u.OrderNum, OrderByType.Asc)
|
||||||
.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
|
.ToListAsync();
|
||||||
return new PagedResultDto<DeptGetListOutputDto>
|
return new PagedResultDto<DeptGetListOutputDto>
|
||||||
{
|
{
|
||||||
Items = await MapToGetListOutputDtosAsync(entities),
|
Items = await MapToGetListOutputDtosAsync(entities),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Volo.Abp.Application.Dtos;
|
using Volo.Abp.Application.Dtos;
|
||||||
using Yi.Framework.Ddd.Application;
|
using Yi.Framework.Ddd.Application;
|
||||||
@@ -54,5 +55,25 @@ namespace Yi.Framework.Rbac.Application.Services.System
|
|||||||
throw new UserFriendlyException(RoleConst.Exist);
|
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 Microsoft.AspNetCore.Mvc;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using TencentCloud.Tcr.V20190924.Models;
|
|
||||||
using Volo.Abp;
|
using Volo.Abp;
|
||||||
using Volo.Abp.Application.Dtos;
|
using Volo.Abp.Application.Dtos;
|
||||||
using Volo.Abp.Caching;
|
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 type = GetFileType();
|
||||||
|
|
||||||
var savePath = GetSaveFilePath();
|
var savePath = GetSaveFilePath();
|
||||||
var filePath = Path.Combine(savePath, this.FileName);
|
this.FilePath = savePath;
|
||||||
this.FilePath = filePath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,59 +1,59 @@
|
|||||||
using System;
|
// using System;
|
||||||
using System.Collections.Generic;
|
// using System.Collections.Generic;
|
||||||
using System.Linq;
|
// using System.Linq;
|
||||||
using System.Text;
|
// using System.Text;
|
||||||
using System.Threading.Tasks;
|
// using System.Threading.Tasks;
|
||||||
using TencentCloud.Common.Profile;
|
// using TencentCloud.Common.Profile;
|
||||||
using TencentCloud.Common;
|
// using TencentCloud.Common;
|
||||||
using TencentCloud.Sms.V20210111.Models;
|
// using TencentCloud.Sms.V20210111.Models;
|
||||||
using TencentCloud.Sms.V20210111;
|
// using TencentCloud.Sms.V20210111;
|
||||||
using Volo.Abp.Domain.Services;
|
// using Volo.Abp.Domain.Services;
|
||||||
using Microsoft.Extensions.Logging;
|
// using Microsoft.Extensions.Logging;
|
||||||
|
//
|
||||||
namespace Yi.Framework.Rbac.Domain.Managers
|
// namespace Yi.Framework.Rbac.Domain.Managers
|
||||||
{
|
// {
|
||||||
public class TencentCloudManager : DomainService
|
// public class TencentCloudManager : DomainService
|
||||||
{
|
// {
|
||||||
private ILogger<TencentCloudManager> _logger;
|
// private ILogger<TencentCloudManager> _logger;
|
||||||
public TencentCloudManager(ILogger<TencentCloudManager> logger)
|
// public TencentCloudManager(ILogger<TencentCloudManager> logger)
|
||||||
{
|
// {
|
||||||
_logger= logger;
|
// _logger= logger;
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
public async Task SendSmsAsync()
|
// public async Task SendSmsAsync()
|
||||||
{
|
// {
|
||||||
|
//
|
||||||
try
|
// try
|
||||||
{
|
// {
|
||||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
// // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
// // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
// // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||||
Credential cred = new Credential
|
// Credential cred = new Credential
|
||||||
{
|
// {
|
||||||
SecretId = "SecretId",
|
// SecretId = "SecretId",
|
||||||
SecretKey = "SecretKey"
|
// SecretKey = "SecretKey"
|
||||||
};
|
// };
|
||||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
// // 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||||
ClientProfile clientProfile = new ClientProfile();
|
// ClientProfile clientProfile = new ClientProfile();
|
||||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
// // 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||||
HttpProfile httpProfile = new HttpProfile();
|
// HttpProfile httpProfile = new HttpProfile();
|
||||||
httpProfile.Endpoint = ("sms.tencentcloudapi.com");
|
// httpProfile.Endpoint = ("sms.tencentcloudapi.com");
|
||||||
clientProfile.HttpProfile = httpProfile;
|
// clientProfile.HttpProfile = httpProfile;
|
||||||
|
//
|
||||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
// // 实例化要请求产品的client对象,clientProfile是可选的
|
||||||
SmsClient client = new SmsClient(cred, "", clientProfile);
|
// SmsClient client = new SmsClient(cred, "", clientProfile);
|
||||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
// // 实例化一个请求对象,每个接口都会对应一个request对象
|
||||||
SendSmsRequest req = new SendSmsRequest();
|
// SendSmsRequest req = new SendSmsRequest();
|
||||||
|
//
|
||||||
// 返回的resp是一个SendSmsResponse的实例,与请求对象对应
|
// // 返回的resp是一个SendSmsResponse的实例,与请求对象对应
|
||||||
SendSmsResponse resp = await client.SendSms(req);
|
// SendSmsResponse resp = await client.SendSms(req);
|
||||||
// 输出json格式的字符串回包
|
// // 输出json格式的字符串回包
|
||||||
_logger.LogInformation("腾讯云Sms返回:"+AbstractModel.ToJsonString(resp));
|
// _logger.LogInformation("腾讯云Sms返回:"+AbstractModel.ToJsonString(resp));
|
||||||
}
|
// }
|
||||||
catch (Exception e)
|
// catch (Exception e)
|
||||||
{
|
// {
|
||||||
_logger.LogError(e,e.ToString());
|
// _logger.LogError(e,e.ToString());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
<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" />
|
<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.Authentication.OAuth.QQ;
|
||||||
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
|
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
|
||||||
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
|
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Yi.Framework.AspNetCore.UnifyResult;
|
||||||
using Yi.Framework.BackgroundWorkers.Hangfire;
|
using Yi.Framework.BackgroundWorkers.Hangfire;
|
||||||
using Yi.Framework.Bbs.Application;
|
using Yi.Framework.Bbs.Application;
|
||||||
using Yi.Framework.Bbs.Application.Extensions;
|
using Yi.Framework.Bbs.Application.Extensions;
|
||||||
@@ -130,6 +131,7 @@ namespace Yi.Abp.Web
|
|||||||
});
|
});
|
||||||
|
|
||||||
//采用furion格式的规范化api,默认不开启,使用abp优雅的方式
|
//采用furion格式的规范化api,默认不开启,使用abp优雅的方式
|
||||||
|
//前置:需要将管道工作单元前加上app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
|
||||||
//你没看错。。。
|
//你没看错。。。
|
||||||
//service.AddFurionUnifyResultApi();
|
//service.AddFurionUnifyResultApi();
|
||||||
|
|
||||||
@@ -278,19 +280,19 @@ namespace Yi.Abp.Web
|
|||||||
};
|
};
|
||||||
options.Events = new JwtBearerEvents
|
options.Events = new JwtBearerEvents
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
OnMessageReceived = messageContext =>
|
||||||
{
|
{
|
||||||
//优先Query中获取,再去cookies中获取
|
//优先Query中获取,再去cookies中获取
|
||||||
var accessToken = context.Request.Query["access_token"];
|
var accessToken = messageContext.Request.Query["access_token"];
|
||||||
if (!string.IsNullOrEmpty(accessToken))
|
if (!string.IsNullOrEmpty(accessToken))
|
||||||
{
|
{
|
||||||
context.Token = accessToken;
|
messageContext.Token = accessToken;
|
||||||
}
|
}
|
||||||
else
|
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
|
options.Events = new JwtBearerEvents
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
OnMessageReceived = messageContext =>
|
||||||
{
|
{
|
||||||
var refresh_token = context.Request.Headers["refresh_token"];
|
var headerRefreshToken = messageContext.Request.Headers["refresh_token"];
|
||||||
if (!string.IsNullOrEmpty(refresh_token))
|
if (!string.IsNullOrEmpty(headerRefreshToken))
|
||||||
{
|
{
|
||||||
context.Token = refresh_token;
|
messageContext.Token = headerRefreshToken;
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
var refreshToken = context.Request.Query["refresh_token"];
|
var queryRefreshToken = messageContext.Request.Query["refresh_token"];
|
||||||
if (!string.IsNullOrEmpty(refreshToken))
|
if (!string.IsNullOrEmpty(queryRefreshToken))
|
||||||
{
|
{
|
||||||
context.Token = refreshToken;
|
messageContext.Token = queryRefreshToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
@@ -393,8 +395,7 @@ namespace Yi.Abp.Web
|
|||||||
app.UseDefaultFiles();
|
app.UseDefaultFiles();
|
||||||
app.UseDirectoryBrowser("/api/app/wwwroot");
|
app.UseDirectoryBrowser("/api/app/wwwroot");
|
||||||
|
|
||||||
|
//app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
|
||||||
// app.Properties.Add("_AbpExceptionHandlingMiddleware_Added",false);
|
|
||||||
//工作单元
|
//工作单元
|
||||||
app.UseUnitOfWork();
|
app.UseUnitOfWork();
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,8 @@
|
|||||||
"EnabledDbSeed": true,
|
"EnabledDbSeed": true,
|
||||||
"EnableUnderLine": false, // 启用驼峰转下划线
|
"EnableUnderLine": false, // 启用驼峰转下划线
|
||||||
//SAAS多租户
|
//SAAS多租户
|
||||||
"EnabledSaasMultiTenancy": true
|
"EnabledSaasMultiTenancy": true,
|
||||||
|
"EnabledConcurrencyException": false
|
||||||
//读写分离地址
|
//读写分离地址
|
||||||
//"ReadUrl": [
|
//"ReadUrl": [
|
||||||
// "DataSource=[xxxx]", //Sqlite
|
// "DataSource=[xxxx]", //Sqlite
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Shouldly;
|
using Shouldly;
|
||||||
using TencentCloud.Ame.V20190916.Models;
|
|
||||||
using TencentCloud.Tiw.V20190919.Models;
|
|
||||||
using Volo.Abp.Domain.Repositories;
|
using Volo.Abp.Domain.Repositories;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.User;
|
using Yi.Framework.Rbac.Application.Contracts.Dtos.User;
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export function usePost() {
|
|||||||
`确认要<strong>${
|
`确认要<strong>${
|
||||||
row.state === false ? "停用" : "启用"
|
row.state === false ? "停用" : "启用"
|
||||||
}</strong><strong style='color:var(--el-color-primary)'>${
|
}</strong><strong style='color:var(--el-color-primary)'>${
|
||||||
row.roleName
|
row.postName
|
||||||
}</strong>吗?`,
|
}</strong>吗?`,
|
||||||
"系统提示",
|
"系统提示",
|
||||||
{
|
{
|
||||||
@@ -132,7 +132,7 @@ export function usePost() {
|
|||||||
loading: false
|
loading: false
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
message(`已${row.state === false ? "停用" : "启用"}${row.roleName}`, {
|
message(`已${row.state === false ? "停用" : "启用"}${row.postName}`, {
|
||||||
type: "success"
|
type: "success"
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@@ -143,7 +143,7 @@ export function usePost() {
|
|||||||
|
|
||||||
async function handleDelete(row) {
|
async function handleDelete(row) {
|
||||||
await delPost([row.id]);
|
await delPost([row.id]);
|
||||||
message(`您删除了角色名称为${row.roleName}的这条数据`, { type: "success" });
|
message(`您删除了岗位名称为${row.postName}的这条数据`, { type: "success" });
|
||||||
onSearch();
|
onSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ export function delDept(deptId) {
|
|||||||
return request({
|
return request({
|
||||||
url: `/dept`,
|
url: `/dept`,
|
||||||
method: 'delete',
|
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