Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
714acc0749 | ||
|
|
1d32f4709b | ||
|
|
b96a4adb9f | ||
|
|
0e08a7d102 | ||
|
|
54e5b46dbf | ||
|
|
f266c9a718 | ||
|
|
b02cf986d3 | ||
|
|
44ef55be00 | ||
|
|
70371e92b3 | ||
|
|
803d862513 | ||
|
|
4a093470d5 | ||
|
|
b01765360d | ||
|
|
02ffc18a61 | ||
|
|
0fb410159a | ||
|
|
d2afa84c37 | ||
|
|
672fb84871 | ||
|
|
1e7a9c7abb | ||
|
|
b83c005f28 | ||
|
|
b9a3cfe377 | ||
|
|
be515339fe | ||
|
|
c65952202a | ||
|
|
ab98cf30c1 | ||
|
|
4d914ead0e | ||
|
|
b67c59710b | ||
|
|
24c9ceefde | ||
|
|
e713bcd9b7 | ||
|
|
400aa876df | ||
|
|
07b4b95732 | ||
|
|
94fa69e8ef | ||
|
|
46c9563f33 | ||
|
|
52240ab6a8 | ||
|
|
ea3fa0e0d6 | ||
|
|
6bf4885f85 | ||
|
|
839e400ed1 | ||
|
|
55733f07e8 | ||
|
|
6533020ebc | ||
|
|
710966e098 | ||
|
|
9495589b28 | ||
|
|
e8cbf35abb | ||
|
|
dc38e97296 | ||
|
|
ba693d1e78 | ||
|
|
e8ab6d47eb | ||
|
|
240a607875 | ||
|
|
09c45c4ba4 | ||
|
|
0257fb294a | ||
|
|
1ca05495d8 | ||
|
|
d1108700e0 | ||
|
|
ff4e857128 | ||
|
|
31cf1a82f1 | ||
|
|
0531c2b330 |
@@ -1,12 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Infrastructure.Model;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
using System;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Security.Principal;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
|
|
||||||
namespace Infrastructure
|
namespace Infrastructure
|
||||||
{
|
{
|
||||||
|
|||||||
+14
-3
@@ -1,13 +1,20 @@
|
|||||||
using Infrastructure.Extensions;
|
using Infrastructure.Extensions;
|
||||||
|
using Infrastructure.Model;
|
||||||
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Web;
|
using System.Web;
|
||||||
using Io = System.IO;
|
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers
|
namespace Infrastructure.Controllers
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// web层通用数据处理
|
||||||
|
/// </summary>
|
||||||
public class BaseController : ControllerBase
|
public class BaseController : ControllerBase
|
||||||
{
|
{
|
||||||
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
|
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
|
||||||
@@ -61,7 +68,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
{
|
{
|
||||||
throw new CustomException(fileName + "文件不存在");
|
throw new CustomException(fileName + "文件不存在");
|
||||||
}
|
}
|
||||||
var stream = Io.File.OpenRead(path); //创建文件流
|
var stream = System.IO.File.OpenRead(path); //创建文件流
|
||||||
|
|
||||||
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
|
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
|
||||||
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
|
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
|
||||||
@@ -92,6 +99,10 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
|
|
||||||
return new ApiResult((int)resultCode, msg, data);
|
return new ApiResult((int)resultCode, msg, data);
|
||||||
}
|
}
|
||||||
|
protected ApiResult Success()
|
||||||
|
{
|
||||||
|
return GetApiResult(ResultCode.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace Infrastructure
|
namespace Infrastructure.Converter
|
||||||
{
|
{
|
||||||
public class JsonConverterUtil
|
public class JsonConverterUtil
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Infrastructure.Converter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Json任何类型读取到字符串属性
|
||||||
|
/// 因为 System.Text.Json 必须严格遵守类型一致,当非字符串读取到字符属性时报错:
|
||||||
|
/// The JSON value could not be converted to System.String.
|
||||||
|
/// </summary>
|
||||||
|
public class StringConverter : System.Text.Json.Serialization.JsonConverter<string>
|
||||||
|
{
|
||||||
|
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType == JsonTokenType.String)
|
||||||
|
{
|
||||||
|
return reader.GetString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//非字符类型,返回原生内容
|
||||||
|
return GetRawPropertyValue(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
writer.WriteStringValue(value);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 非字符类型,返回原生内容
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="jsonReader"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static string GetRawPropertyValue(Utf8JsonReader jsonReader)
|
||||||
|
{
|
||||||
|
ReadOnlySpan<byte> utf8Bytes = jsonReader.HasValueSequence ?
|
||||||
|
jsonReader.ValueSequence.ToArray() :
|
||||||
|
jsonReader.ValueSpan;
|
||||||
|
return Encoding.UTF8.GetString(utf8Bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,8 +5,18 @@ namespace Infrastructure
|
|||||||
public class CustomException : Exception
|
public class CustomException : Exception
|
||||||
{
|
{
|
||||||
public int Code { get; set; }
|
public int Code { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 前端提示语
|
||||||
|
/// </summary>
|
||||||
public string Msg { get; set; }
|
public string Msg { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 记录到日志的详细内容
|
||||||
|
/// </summary>
|
||||||
public string LogMsg { get; set; }
|
public string LogMsg { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 是否通知
|
||||||
|
/// </summary>
|
||||||
|
public bool Notice { get; set; } = true;
|
||||||
|
|
||||||
public CustomException(string msg) : base(msg)
|
public CustomException(string msg) : base(msg)
|
||||||
{
|
{
|
||||||
@@ -17,9 +27,10 @@ namespace Infrastructure
|
|||||||
Msg = msg;
|
Msg = msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomException(ResultCode resultCode, string msg) : base(msg)
|
public CustomException(ResultCode resultCode, string msg, bool notice = true) : base(msg)
|
||||||
{
|
{
|
||||||
Code = (int)resultCode;
|
Code = (int)resultCode;
|
||||||
|
Notice = notice;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -54,5 +54,10 @@
|
|||||||
/// 清空数据
|
/// 清空数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
CLEAN = 9,
|
CLEAN = 9,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载
|
||||||
|
/// </summary>
|
||||||
|
DOWNLOAD = 10,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace Infrastructure
|
|||||||
|
|
||||||
#region 获取unix时间戳
|
#region 获取unix时间戳
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取unix时间戳
|
/// 获取unix时间戳(毫秒)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dt"></param>
|
/// <param name="dt"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
namespace ZR.Common
|
namespace Infrastructure.Helper
|
||||||
{
|
{
|
||||||
public class JnHelper
|
public class JnHelper
|
||||||
{
|
{
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
|
||||||
<Compile Remove="Model\PagedInfo.cs" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="AspectCore.Abstractions" Version="2.4.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="7.0.4" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
using Infrastructure;
|
using Infrastructure.Extensions;
|
||||||
using Infrastructure.Extensions;
|
using Infrastructure.Model;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IdentityModel.Tokens.Jwt;
|
using System.IdentityModel.Tokens.Jwt;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Model.System.Dto;
|
|
||||||
using ZR.Service.System;
|
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Framework
|
namespace Infrastructure
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 2020-11-20
|
/// 2023-8-29已从WebApi移至此
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JwtUtil
|
public class JwtUtil
|
||||||
{
|
{
|
||||||
@@ -21,7 +22,7 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="httpContext"></param>
|
/// <param name="httpContext"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static LoginUser GetLoginUser(HttpContext httpContext)
|
public static TokenModel GetLoginUser(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
string token = httpContext.GetToken();
|
string token = httpContext.GetToken();
|
||||||
|
|
||||||
@@ -36,10 +37,12 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
/// 生成token
|
/// 生成token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="claims"></param>
|
/// <param name="claims"></param>
|
||||||
/// <param name="jwtSettings"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string GenerateJwtToken(List<Claim> claims, JwtSettings jwtSettings)
|
public static string GenerateJwtToken(List<Claim> claims)
|
||||||
{
|
{
|
||||||
|
JwtSettings jwtSettings = new();
|
||||||
|
AppSettings.Bind("JwtSettings", jwtSettings);
|
||||||
|
|
||||||
var authTime = DateTime.Now;
|
var authTime = DateTime.Now;
|
||||||
var expiresAt = authTime.AddMinutes(jwtSettings.Expire);
|
var expiresAt = authTime.AddMinutes(jwtSettings.Expire);
|
||||||
var tokenHandler = new JwtSecurityTokenHandler();
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
@@ -55,7 +58,7 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
IssuedAt = authTime,//token生成时间
|
IssuedAt = authTime,//token生成时间
|
||||||
Expires = expiresAt,
|
Expires = expiresAt,
|
||||||
//NotBefore = authTime,
|
//NotBefore = authTime,
|
||||||
TokenType = "Bearer",
|
TokenType = jwtSettings.TokenType,
|
||||||
//对称秘钥,签名证书
|
//对称秘钥,签名证书
|
||||||
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
|
||||||
};
|
};
|
||||||
@@ -96,7 +99,7 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="token">令牌</param>
|
/// <param name="token">令牌</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IEnumerable<Claim>? ParseToken(string token)
|
public static JwtSecurityToken? ParseToken(string token)
|
||||||
{
|
{
|
||||||
var tokenHandler = new JwtSecurityTokenHandler();
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
var validateParameter = ValidParameters();
|
var validateParameter = ValidParameters();
|
||||||
@@ -105,8 +108,7 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
{
|
{
|
||||||
tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken);
|
tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken);
|
||||||
|
|
||||||
var jwtToken = tokenHandler.ReadJwtToken(token);
|
return tokenHandler.ReadJwtToken(token);
|
||||||
return jwtToken.Claims;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -119,25 +121,21 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// jwt token校验
|
/// jwt token校验
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="jwtToken"></param>
|
/// <param name="jwtSecurityToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static LoginUser? ValidateJwtToken(IEnumerable<Claim> jwtToken)
|
public static TokenModel? ValidateJwtToken(JwtSecurityToken jwtSecurityToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LoginUser loginUser = null;
|
if (jwtSecurityToken == null) return null;
|
||||||
|
IEnumerable<Claim> claims = jwtSecurityToken?.Claims;
|
||||||
|
TokenModel loginUser = null;
|
||||||
|
|
||||||
var userData = jwtToken.FirstOrDefault(x => x.Type == ClaimTypes.UserData)?.Value;
|
var userData = claims.FirstOrDefault(x => x.Type == ClaimTypes.UserData)?.Value;
|
||||||
if (userData != null)
|
if (userData != null)
|
||||||
{
|
{
|
||||||
loginUser = JsonConvert.DeserializeObject<LoginUser>(userData);
|
loginUser = JsonConvert.DeserializeObject<TokenModel>(userData);
|
||||||
var permissions = CacheService.GetUserPerms(GlobalConstant.UserPermKEY + loginUser?.UserId);
|
loginUser.ExpireTime = jwtSecurityToken.ValidTo;
|
||||||
if (loginUser?.UserName == GlobalConstant.AdminRole)
|
|
||||||
{
|
|
||||||
permissions = new List<string>() { GlobalConstant.AdminPerm };
|
|
||||||
}
|
|
||||||
if (permissions == null) return null;
|
|
||||||
loginUser.Permissions = permissions;
|
|
||||||
}
|
}
|
||||||
return loginUser;
|
return loginUser;
|
||||||
}
|
}
|
||||||
@@ -153,7 +151,7 @@ namespace ZR.Admin.WebApi.Framework
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="user"></param>
|
/// <param name="user"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static List<Claim> AddClaims(LoginUser user)
|
public static List<Claim> AddClaims(TokenModel user)
|
||||||
{
|
{
|
||||||
var claims = new List<Claim>()
|
var claims = new List<Claim>()
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Infrastructure
|
||||||
|
{
|
||||||
|
public class Log
|
||||||
|
{
|
||||||
|
public static void WriteLine(ConsoleColor color = ConsoleColor.Black, string msg = "")
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = color;
|
||||||
|
Console.WriteLine($"{DateTime.Now} {msg}");
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +1,26 @@
|
|||||||
using Infrastructure.Constant;
|
using Infrastructure.Constant;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Infrastructure.Model
|
namespace Infrastructure.Model
|
||||||
{
|
{
|
||||||
public class ApiResult
|
public class ApiResult : Dictionary<string, object>
|
||||||
{
|
{
|
||||||
public int Code { get; set; }
|
/** 状态码 */
|
||||||
public string Msg { get; set; }
|
public static readonly string CODE_TAG = "code";
|
||||||
|
|
||||||
|
/** 返回内容 */
|
||||||
|
public static readonly string MSG_TAG = "msg";
|
||||||
|
|
||||||
|
/** 数据对象 */
|
||||||
|
public static readonly string DATA_TAG = "data";
|
||||||
|
//public int Code { get; set; }
|
||||||
|
//public string Msg { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 如果data值为null,则忽略序列化将不会返回data字段
|
/// 如果data值为null,则忽略序列化将不会返回data字段
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||||
public object Data { get; set; }
|
//public object Data { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 初始化一个新创建的APIResult对象,使其表示一个空消息
|
/// 初始化一个新创建的APIResult对象,使其表示一个空消息
|
||||||
@@ -27,8 +36,8 @@ namespace Infrastructure.Model
|
|||||||
/// <param name="msg"></param>
|
/// <param name="msg"></param>
|
||||||
public ApiResult(int code, string msg)
|
public ApiResult(int code, string msg)
|
||||||
{
|
{
|
||||||
Code = code;
|
Add(CODE_TAG, code);
|
||||||
Msg = msg;
|
Add(MSG_TAG, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -36,33 +45,28 @@ namespace Infrastructure.Model
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="code"></param>
|
/// <param name="code"></param>
|
||||||
/// <param name="msg"></param>
|
/// <param name="msg"></param>
|
||||||
|
/// <param name="data"></param>
|
||||||
public ApiResult(int code, string msg, object data)
|
public ApiResult(int code, string msg, object data)
|
||||||
{
|
{
|
||||||
Code = code;
|
Add(CODE_TAG, code);
|
||||||
Msg = msg;
|
Add(MSG_TAG, msg);
|
||||||
if (data != null)
|
if (data != null)
|
||||||
{
|
{
|
||||||
Data = data;
|
Add(DATA_TAG, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 返回成功消息
|
||||||
|
/// </summary>
|
||||||
|
/// < returns > 成功消息 </ returns >
|
||||||
|
public static ApiResult Success() { return new ApiResult(HttpStatus.SUCCESS, "success"); }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回成功消息
|
/// 返回成功消息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <param name="data"></param>
|
||||||
public ApiResult Success()
|
/// <returns> 成功消息 </returns >
|
||||||
{
|
public static ApiResult Success(object data) { return new ApiResult(HttpStatus.SUCCESS, "success", data); }
|
||||||
Code = (int)ResultCode.SUCCESS;
|
|
||||||
Msg = "success";
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
///// <summary>
|
|
||||||
///// 返回成功消息
|
|
||||||
///// </summary>
|
|
||||||
///// <param name = "data" > 数据对象 </ param >
|
|
||||||
///// < returns > 成功消息 </ returns >
|
|
||||||
//public static ApiResult Success(object data) { return new ApiResult(HttpStatus.SUCCESS, "success", data); }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 返回成功消息
|
/// 返回成功消息
|
||||||
@@ -79,21 +83,9 @@ namespace Infrastructure.Model
|
|||||||
/// <returns>成功消息</returns>
|
/// <returns>成功消息</returns>
|
||||||
public static ApiResult Success(string msg, object data) { return new ApiResult(HttpStatus.SUCCESS, msg, data); }
|
public static ApiResult Success(string msg, object data) { return new ApiResult(HttpStatus.SUCCESS, msg, data); }
|
||||||
|
|
||||||
/// <summary>
|
public static ApiResult Error(ResultCode code, string msg = "")
|
||||||
/// 访问被拒
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public ApiResult On401()
|
|
||||||
{
|
{
|
||||||
Code = (int)ResultCode.DENY;
|
return Error((int)code, msg);
|
||||||
Msg = "access denyed";
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public ApiResult Error(ResultCode resultCode, string msg = "")
|
|
||||||
{
|
|
||||||
Code = (int)resultCode;
|
|
||||||
Msg = msg;
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -111,9 +103,26 @@ namespace Infrastructure.Model
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static ApiResult Error(string msg) { return new ApiResult((int)ResultCode.CUSTOM_ERROR, msg); }
|
public static ApiResult Error(string msg) { return new ApiResult((int)ResultCode.CUSTOM_ERROR, msg); }
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为成功消息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsSuccess()
|
||||||
{
|
{
|
||||||
return $"msg={Msg},data={Data}";
|
return HttpStatus.SUCCESS == (int)this[CODE_TAG];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 方便链式调用
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public ApiResult Put(string key, object value)
|
||||||
|
{
|
||||||
|
Add(key, value);
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace Infrastructure
|
namespace Infrastructure.Model
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取配置文件POCO实体类
|
/// 获取配置文件POCO实体类
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OptionsSetting
|
public class OptionsSetting
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否单点登录
|
||||||
|
/// </summary>
|
||||||
|
public bool SingleLogin { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否演示模式
|
/// 是否演示模式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool DemoMode { get; set; }
|
public bool DemoMode { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化db
|
||||||
|
/// </summary>
|
||||||
|
public bool InitDb { get; set; }
|
||||||
public MailOptions MailOptions { get; set; }
|
public MailOptions MailOptions { get; set; }
|
||||||
public Upload Upload { get; set; }
|
public Upload Upload { get; set; }
|
||||||
public ALIYUN_OSS ALIYUN_OSS { get; set; }
|
public ALIYUN_OSS ALIYUN_OSS { get; set; }
|
||||||
@@ -78,6 +84,14 @@ namespace Infrastructure
|
|||||||
/// token时间(分)
|
/// token时间(分)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Expire { get; set; } = 1440;
|
public int Expire { get; set; } = 1440;
|
||||||
|
/// <summary>
|
||||||
|
/// 刷新token时长
|
||||||
|
/// </summary>
|
||||||
|
public int RefreshTokenTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// token类型
|
||||||
|
/// </summary>
|
||||||
|
public string TokenType { get; set; } = "Bearer";
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Gen
|
public class Gen
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Infrastructure.Model
|
||||||
|
{
|
||||||
|
public class TokenModel
|
||||||
|
{
|
||||||
|
public long UserId { get; set; }
|
||||||
|
public long DeptId { get; set; }
|
||||||
|
public string UserName { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 角色集合
|
||||||
|
/// </summary>
|
||||||
|
public List<string> RoleIds { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 角色集合(数据权限过滤使用)
|
||||||
|
/// </summary>
|
||||||
|
public List<Roles> Roles { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// Jwt过期时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime ExpireTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 权限集合
|
||||||
|
/// </summary>
|
||||||
|
//public List<string> Permissions { get; set; } = new List<string>();
|
||||||
|
public TokenModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public TokenModel(TokenModel info, List<Roles> roles)
|
||||||
|
{
|
||||||
|
UserId = info.UserId;
|
||||||
|
UserName = info.UserName;
|
||||||
|
DeptId = info.DeptId;
|
||||||
|
Roles = roles;
|
||||||
|
RoleIds = roles.Select(f => f.RoleKey).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Roles
|
||||||
|
{
|
||||||
|
public long RoleId { get; set; }
|
||||||
|
public string RoleKey { get; set; }
|
||||||
|
public int DataScope { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-3
@@ -1,8 +1,10 @@
|
|||||||
using Infrastructure;
|
using Infrastructure.Attribute;
|
||||||
using Infrastructure.Attribute;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Extensions
|
namespace Infrastructure
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// App服务注册
|
/// App服务注册
|
||||||
+8
-1
@@ -1,5 +1,12 @@
|
|||||||
namespace ZR.Admin.WebApi.Extensions
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Infrastructure
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 跨域扩展
|
||||||
|
/// </summary>
|
||||||
public static class CorsExtension
|
public static class CorsExtension
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
+6
-3
@@ -1,14 +1,17 @@
|
|||||||
|
|
||||||
|
using Infrastructure.Extensions;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Extensions
|
namespace Infrastructure
|
||||||
{
|
{
|
||||||
public static class EntityExtension
|
public static class EntityExtension
|
||||||
{
|
{
|
||||||
public static TSource ToCreate<TSource>(this TSource source, HttpContext? context = null)
|
public static TSource ToCreate<TSource>(this TSource source, HttpContext? context = null)
|
||||||
{
|
{
|
||||||
var types = source?.GetType();
|
var types = source?.GetType();
|
||||||
if (types == null) return source;
|
if (types == null || context == null) return source;
|
||||||
BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance;
|
BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance;
|
||||||
|
|
||||||
types.GetProperty("CreateTime", flag)?.SetValue(source, DateTime.Now, null);
|
types.GetProperty("CreateTime", flag)?.SetValue(source, DateTime.Now, null);
|
||||||
@@ -23,7 +26,7 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
public static TSource ToUpdate<TSource>(this TSource source, HttpContext? context = null)
|
public static TSource ToUpdate<TSource>(this TSource source, HttpContext? context = null)
|
||||||
{
|
{
|
||||||
var types = source?.GetType();
|
var types = source?.GetType();
|
||||||
if (types == null) return source;
|
if (types == null || context == null) return source;
|
||||||
BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance;
|
BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance;
|
||||||
|
|
||||||
types.GetProperty("UpdateTime", flag)?.SetValue(source, DateTime.Now, null);
|
types.GetProperty("UpdateTime", flag)?.SetValue(source, DateTime.Now, null);
|
||||||
+41
-31
@@ -1,12 +1,15 @@
|
|||||||
using Infrastructure;
|
using IPTools.Core;
|
||||||
using Infrastructure.Extensions;
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using UAParser;
|
using UAParser;
|
||||||
using ZR.Model.System;
|
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Extensions
|
namespace Infrastructure.Extensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// HttpContext扩展类
|
/// HttpContext扩展类
|
||||||
@@ -50,7 +53,7 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
if (result.Contains("::1"))
|
if (result.Contains("::1"))
|
||||||
result = "127.0.0.1";
|
result = "127.0.0.1";
|
||||||
|
|
||||||
result = result.Replace("::ffff:", "127.0.0.1");
|
result = result.Replace("::ffff:", "");
|
||||||
result = result.Split(':')?.FirstOrDefault() ?? "127.0.0.1";
|
result = result.Split(':')?.FirstOrDefault() ?? "127.0.0.1";
|
||||||
result = IsIP(result) ? result : "127.0.0.1";
|
result = IsIP(result) ? result : "127.0.0.1";
|
||||||
return result;
|
return result;
|
||||||
@@ -82,7 +85,7 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string? GetName(this HttpContext context)
|
public static string GetName(this HttpContext context)
|
||||||
{
|
{
|
||||||
var uid = context.User?.Identity?.Name;
|
var uid = context.User?.Identity?.Name;
|
||||||
|
|
||||||
@@ -105,7 +108,7 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IEnumerable<ClaimsIdentity>? GetClaims(this HttpContext context)
|
public static IEnumerable<ClaimsIdentity> GetClaims(this HttpContext context)
|
||||||
{
|
{
|
||||||
return context.User?.Identities;
|
return context.User?.Identities;
|
||||||
}
|
}
|
||||||
@@ -131,26 +134,12 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
return context.Request.Headers["Authorization"];
|
return context.Request.Headers["Authorization"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取浏览器信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static ClientInfo GetClientInfo(this HttpContext context)
|
|
||||||
{
|
|
||||||
var str = context.GetUserAgent();
|
|
||||||
var uaParser = Parser.GetDefault();
|
|
||||||
ClientInfo c = uaParser.Parse(str);
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取请求Url
|
/// 获取请求Url
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string? GetRequestUrl(this HttpContext context)
|
public static string GetRequestUrl(this HttpContext context)
|
||||||
{
|
{
|
||||||
return context != null ? context.Request.Path.Value : "";
|
return context != null ? context.Request.Path.Value : "";
|
||||||
}
|
}
|
||||||
@@ -194,30 +183,51 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取浏览器信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static ClientInfo GetClientInfo(this HttpContext context)
|
||||||
|
{
|
||||||
|
var str = context.GetUserAgent();
|
||||||
|
var uaParser = Parser.GetDefault();
|
||||||
|
ClientInfo c = uaParser.Parse(str);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据IP获取地理位置
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GetIpInfo(string IP)
|
||||||
|
{
|
||||||
|
var ipInfo = IpTool.Search(IP);
|
||||||
|
return ipInfo?.Province + "-" + ipInfo?.City + "-" + ipInfo?.NetworkOperator;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 设置请求参数
|
/// 设置请求参数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="operLog"></param>
|
/// <param name="reqMethod"></param>
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
public static void GetRequestValue(this HttpContext context, SysOperLog operLog)
|
public static string GetRequestValue(this HttpContext context, string reqMethod)
|
||||||
{
|
{
|
||||||
string reqMethod = operLog.RequestMethod;
|
string param = string.Empty;
|
||||||
string param= string.Empty;
|
|
||||||
|
|
||||||
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod) || HttpMethods.IsDelete(reqMethod))
|
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod) || HttpMethods.IsDelete(reqMethod))
|
||||||
{
|
{
|
||||||
param = context.GetBody();
|
param = context.GetBody();
|
||||||
param = PwdRep().Replace(param, "***");
|
string regex = "(?<=\"password\":\")[^\",]*";
|
||||||
|
param = Regex.Replace(param, regex, "***");
|
||||||
}
|
}
|
||||||
if (param.IsEmpty())
|
if (param.IsEmpty())
|
||||||
{
|
{
|
||||||
param = context.GetQueryString();
|
param = context.GetQueryString();
|
||||||
}
|
}
|
||||||
operLog.OperParam = param;
|
return param;
|
||||||
}
|
}
|
||||||
|
|
||||||
[GeneratedRegex("(?<=\"password\":\")[^\",]*")]
|
|
||||||
private static partial Regex PwdRep();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+4
-1
@@ -1,6 +1,9 @@
|
|||||||
using AspNetCoreRateLimit;
|
using AspNetCoreRateLimit;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Extensions
|
namespace ZR.Infrastructure.WebExtensions
|
||||||
{
|
{
|
||||||
public static class IPRateExtension
|
public static class IPRateExtension
|
||||||
{
|
{
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Infrastructure;
|
||||||
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.IdentityModel.Tokens;
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace ZR.Infrastructure.WebExtensions
|
||||||
|
{
|
||||||
|
public static class JwtExtension
|
||||||
|
{
|
||||||
|
public static void AddJwt(this IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
}).AddCookie()
|
||||||
|
.AddJwtBearer(o =>
|
||||||
|
{
|
||||||
|
o.TokenValidationParameters = JwtUtil.ValidParameters();
|
||||||
|
o.Events = new JwtBearerEvents
|
||||||
|
{
|
||||||
|
OnAuthenticationFailed = context =>
|
||||||
|
{
|
||||||
|
// 如果过期,把过期信息添加到头部
|
||||||
|
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
|
||||||
|
{
|
||||||
|
Console.WriteLine("jwt过期了");
|
||||||
|
context.Response.Headers.Add("Token-Expired", "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
-5
@@ -1,7 +1,9 @@
|
|||||||
using JinianNet.JNTemplate;
|
using Infrastructure.Helper;
|
||||||
using ZR.Common;
|
using JinianNet.JNTemplate;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Extensions
|
namespace Infrastructure
|
||||||
{
|
{
|
||||||
public static class LogoExtension
|
public static class LogoExtension
|
||||||
{
|
{
|
||||||
@@ -10,13 +12,14 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
Console.ForegroundColor = ConsoleColor.Blue;
|
Console.ForegroundColor = ConsoleColor.Blue;
|
||||||
var contentTpl = JnHelper.ReadTemplate("", "logo.txt");
|
var contentTpl = JnHelper.ReadTemplate("", "logo.txt");
|
||||||
var content = contentTpl?.Render();
|
var content = contentTpl?.Render();
|
||||||
|
var context = App.HttpContext;
|
||||||
Console.WriteLine(content);
|
Console.WriteLine(content);
|
||||||
Console.ForegroundColor = ConsoleColor.Blue;
|
Console.ForegroundColor = ConsoleColor.Blue;
|
||||||
Console.WriteLine("🎉源码地址: https://gitee.com/izory/ZrAdminNetCore");
|
Console.WriteLine("🎉源码地址: https://gitee.com/izory/ZrAdminNetCore");
|
||||||
Console.WriteLine("📖官方文档:http://www.izhaorui.cn/doc");
|
Console.WriteLine("📖官方文档:http://www.izhaorui.cn/doc");
|
||||||
Console.WriteLine("🤑打赏作者:http://www.izhaorui.cn/doc/support.html");
|
Console.WriteLine("💰打赏作者:http://www.izhaorui.cn/doc/support.html");
|
||||||
Console.WriteLine("📱移动端体验:http://www.izhaorui.cn/h5");
|
Console.WriteLine("📱移动端体验:http://www.izhaorui.cn/h5");
|
||||||
|
Console.WriteLine($"Swagger地址:[后端启动地址]/swagger/index.html");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<NoWarn>8632</NoWarn>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AspectCore.Abstractions" Version="2.4.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||||
|
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" />
|
||||||
|
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" />
|
||||||
|
<PackageReference Include="MiniExcel" Version="1.31.2" />
|
||||||
|
<PackageReference Include="CSRedisCore" Version="3.8.670" />
|
||||||
|
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
+4
-7
@@ -22,10 +22,6 @@
|
|||||||
-Based on. NET5/. A common rights management platform (RBAC model) implemented by NET7. Integrate the latest technology for efficient and rapid development, front-end and back-end separation mode, out of the box.
|
-Based on. NET5/. A common rights management platform (RBAC model) implemented by NET7. Integrate the latest technology for efficient and rapid development, front-end and back-end separation mode, out of the box.
|
||||||
- Less code, simple to learn, easy to understand, powerful, easy to extend, lightweight, make web development faster, simpler and more efficient (say goodbye to 996), solve 70% of repetitive work, focus on your business, easy development from now on!
|
- Less code, simple to learn, easy to understand, powerful, easy to extend, lightweight, make web development faster, simpler and more efficient (say goodbye to 996), solve 70% of repetitive work, focus on your business, easy development from now on!
|
||||||
- 提供了技术栈(Ant Design Vue)版[Ant Design Vue](https://gitee.com/billzh/mc-dull.git)
|
- 提供了技术栈(Ant Design Vue)版[Ant Design Vue](https://gitee.com/billzh/mc-dull.git)
|
||||||
- 七牛云通用云产品优惠券:[点我进入](https://s.qiniu.com/FzEfay)。
|
|
||||||
- 腾讯云秒杀场:[☛☛ 点我进入 ☚☚](https://curl.qcloud.com/4yEoRquq)。
|
|
||||||
- 腾讯云优惠券:[☛☛ 点我领取 ☚☚](https://curl.qcloud.com/5J4nag8D)。
|
|
||||||
- 阿里云特惠专区:[☛☛ 点我进入 ☚☚](https://www.aliyun.com/minisite/goods?userCode=uotn5vt1&share_source=copy_link)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
If it helps you, you can click "Star" in the upper right corner to collect it, so that the author has the motivation to continue to go on for free, thank you! ~
|
If it helps you, you can click "Star" in the upper right corner to collect it, so that the author has the motivation to continue to go on for free, thank you! ~
|
||||||
@@ -52,7 +48,7 @@ Since it is a personal project, the funds are limited, and the experience server
|
|||||||
|
|
||||||
| repository | Github | Gitee |
|
| repository | Github | Gitee |
|
||||||
| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
|
| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||||
| Net7 | [Clone/Download](https://github.com/izhaorui/Zr.Admin.NET) | [Clone/Download](https://gitee.com/izory/ZrAdminNetCore/tree/net7.0/) |
|
| Net7 | [Clone/Download](https://github.com/izhaorui/Zr.Admin.NET) | [Clone/Download](https://gitee.com/izory/ZrAdminNetCore) |
|
||||||
| Vue3(Hot) | [Clone/Download](https://github.com/izhaorui/ZR.Admin.Vue3) | [Clone/Download](https://gitee.com/izory/ZRAdmin-vue) |
|
| Vue3(Hot) | [Clone/Download](https://github.com/izhaorui/ZR.Admin.Vue3) | [Clone/Download](https://gitee.com/izory/ZRAdmin-vue) |
|
||||||
|
|
||||||
## 🍁 Front-end technology
|
## 🍁 Front-end technology
|
||||||
@@ -61,7 +57,7 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
|
|||||||
|
|
||||||
## 🍀 Back-end technology
|
## 🍀 Back-end technology
|
||||||
|
|
||||||
- Core Framework: . Net5.0/. Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis
|
- Core Framework: . Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis
|
||||||
- Scheduled tasks: Quartz.Net component that supports the execution of assemblies or HTTP network requests
|
- Scheduled tasks: Quartz.Net component that supports the execution of assemblies or HTTP network requests
|
||||||
- Security support: filters (data permission filtering), SQL injection, request forgery
|
- Security support: filters (data permission filtering), SQL injection, request forgery
|
||||||
- Log management: NLog, login log, operation log, scheduled task log
|
- Log management: NLog, login log, operation log, scheduled task log
|
||||||
@@ -99,7 +95,8 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
|
|||||||
## 🍻 Project structure
|
## 🍻 Project structure
|
||||||
|
|
||||||
```
|
```
|
||||||
├─ZR.Service ->[服务层类库]:提供WebApi接口调用;
|
├─ZR.Service ->[你的业务服务层类库]:提供WebApi接口调用;
|
||||||
|
├─ZR.ServiceCore ->[系统服务层类库]:提供WebApi接口调用;
|
||||||
├─ZR.Repository ->[仓库层类库]:方便提供有执行存储过程的操作;
|
├─ZR.Repository ->[仓库层类库]:方便提供有执行存储过程的操作;
|
||||||
├─ZR.Model ->[实体层类库]:提供项目中的数据库表、数据传输对象;
|
├─ZR.Model ->[实体层类库]:提供项目中的数据库表、数据传输对象;
|
||||||
├─ZR.Admin.WebApi ->[webapi接口]:为Vue版或其他三方系统提供接口服务。
|
├─ZR.Admin.WebApi ->[webapi接口]:为Vue版或其他三方系统提供接口服务。
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a>
|
<a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a>
|
||||||
<a href='https://gitee.com/izory/ZrAdminNetCore/members'><img src='https://gitee.com/izory/ZrAdminNetCore/badge/fork.svg?theme=dark' alt='fork'></img></a>
|
<a href='https://gitee.com/izory/ZrAdminNetCore/members'><img src='https://gitee.com/izory/ZrAdminNetCore/badge/fork.svg?theme=dark' alt='fork'></img></a>
|
||||||
<a href="https://gitee.com/izory/ZrAdminNetCore/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
<a href="https://gitee.com/izory/ZrAdminNetCore/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||||
<a href="http://www.izhaorui.cn/doc/changelog.html"><img src="https://img.shields.io/badge/更新日志-20230713-yellow"/></a>
|
<a href="http://www.izhaorui.cn/doc/changelog.html"><img src="https://img.shields.io/badge/更新日志-20230811-yellow"/></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
- 阿里云特惠专区:[☛☛ 点我进入 ☚☚](https://www.aliyun.com/minisite/goods?userCode=uotn5vt1&share_source=copy_link)
|
- 阿里云特惠专区:[☛☛ 点我进入 ☚☚](https://www.aliyun.com/minisite/goods?userCode=uotn5vt1&share_source=copy_link)
|
||||||
|
|
||||||
```
|
```
|
||||||
如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,这样作者才有继续免费下去的动力,谢谢!~
|
如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,谢谢!~
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🍿 在线体验
|
## 🍿 在线体验
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
- Vue3.x 版本体验:[http://www.izhaorui.cn/vue3](http://www.izhaorui.cn/vue3)
|
- Vue3.x 版本体验:[http://www.izhaorui.cn/vue3](http://www.izhaorui.cn/vue3)
|
||||||
- Vue2.x 版本体验:[http://www.izhaorui.cn/admin](http://www.izhaorui.cn/admin)
|
- Vue2.x 版本体验:[http://www.izhaorui.cn/admin](http://www.izhaorui.cn/admin)
|
||||||
- Uniapp 版本体验:[http://www.izhaorui.cn/h5](http://www.izhaorui.cn/h5)
|
- Uniapp 版本体验:[http://www.izhaorui.cn/h5](http://www.izhaorui.cn/h5)
|
||||||
- 账号密码:admin/123456
|
- 账号密码:admin/123456,普通用户 user/123456
|
||||||
|
|
||||||
| H5 | 微信小程序 |
|
| H5 | 微信小程序 |
|
||||||
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
| 仓库 | Github | Gitee |
|
| 仓库 | Github | Gitee |
|
||||||
| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
|
| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||||
| Net7 | [克隆/下载](https://github.com/izhaorui/Zr.Admin.NET) | [克隆/下载](https://gitee.com/izory/ZrAdminNetCore/tree/net7.0/) |
|
| Net7 | [克隆/下载](https://github.com/izhaorui/Zr.Admin.NET) | [克隆/下载](https://gitee.com/izory/ZrAdminNetCore) |
|
||||||
| Vue3(推荐使用) | [克隆/下载](https://github.com/izhaorui/ZR.Admin.Vue3) | [克隆/下载](https://gitee.com/izory/ZRAdmin-vue) |
|
| Vue3(推荐使用) | [克隆/下载](https://github.com/izhaorui/ZR.Admin.Vue3) | [克隆/下载](https://gitee.com/izory/ZRAdmin-vue) |
|
||||||
|
|
||||||
## 🍁 前端技术
|
## 🍁 前端技术
|
||||||
@@ -72,6 +72,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
|||||||
- 分库分表:使用 orm sqlsugar 可以很轻松的实现分库分库性能优越
|
- 分库分表:使用 orm sqlsugar 可以很轻松的实现分库分库性能优越
|
||||||
- 多 租 户:支持多租户功能
|
- 多 租 户:支持多租户功能
|
||||||
- 缓存数据:内置内存缓存和 Redis
|
- 缓存数据:内置内存缓存和 Redis
|
||||||
|
- signalR:使用signalr管理用户在线状态
|
||||||
|
|
||||||
## 🍖 内置功能
|
## 🍖 内置功能
|
||||||
|
|
||||||
@@ -88,18 +89,24 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
|||||||
11. 在线构建器:拖动表单元素生成相应的 VUE 代码(仅支持 vue2)。
|
11. 在线构建器:拖动表单元素生成相应的 VUE 代码(仅支持 vue2)。
|
||||||
12. 任务系统:基于 Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。
|
12. 任务系统:基于 Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。
|
||||||
13. 文章管理:可以写文章记录。
|
13. 文章管理:可以写文章记录。
|
||||||
14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、.sql 等)支持下载,自定义配置前端展示控件、让开发更快捷高效(史上最强)。
|
14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、.sql、uniapp 等)支持下载,自定义配置前端展示控件、让开发更快捷高效(史上最强)。
|
||||||
15. 参数管理:对系统动态配置常用参数。
|
15. 参数管理:对系统动态配置常用参数。
|
||||||
16. 发送邮件:可以对多个用户进行发送邮件。
|
16. 发送邮件:可以对多个用户进行发送邮件。
|
||||||
17. 文件管理:可以进行上传文件管理,目前支持上传到本地、阿里云。
|
17. 文件管理:可以进行上传文件管理,目前支持上传到本地、阿里云。
|
||||||
18. 通知管理:系统通知公告信息发布维护,使用 signalr 实现对用户实时通知。
|
18. 通知管理:系统通知公告信息发布维护,使用 signalr 实现对用户实时通知。
|
||||||
19. 账号注册:可以注册账号登录系统。
|
19. 账号注册:可以注册账号登录系统。
|
||||||
20. 多语言管理:支持静态、后端动态配置国际化。目前只支持中、英、繁体(仅支持 vue3)
|
20. 多语言管理:支持静态、后端动态配置国际化。目前只支持中、英、繁体(仅支持 vue3)
|
||||||
|
21. 在线用户:可以查看正在登录使用的用户,可以对其踢出、通知操作
|
||||||
|
22. db 审计日志:数据库审计功能
|
||||||
|
23. 三方登录:提供三方登录实现逻辑
|
||||||
|
|
||||||
## 🍻 项目结构
|
## 🍻 项目结构
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
```
|
```
|
||||||
├─ZR.Service ->[服务层类库]:提供WebApi接口调用;
|
├─ZR.Service ->[你的业务服务层类库]:提供WebApi接口调用;
|
||||||
|
├─ZR.ServiceCore ->[系统服务层类库]:提供WebApi接口调用;
|
||||||
├─ZR.Repository ->[仓库层类库]:方便提供有执行存储过程的操作;
|
├─ZR.Repository ->[仓库层类库]:方便提供有执行存储过程的操作;
|
||||||
├─ZR.Model ->[实体层类库]:提供项目中的数据库表、数据传输对象;
|
├─ZR.Model ->[实体层类库]:提供项目中的数据库表、数据传输对象;
|
||||||
├─ZR.Admin.WebApi ->[webapi接口]:为Vue版或其他三方系统提供接口服务。
|
├─ZR.Admin.WebApi ->[webapi接口]:为Vue版或其他三方系统提供接口服务。
|
||||||
@@ -195,6 +202,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
|||||||
- 👉SqlSugar:[SqlSugar](https://gitee.com/dotnetchina/SqlSugar)
|
- 👉SqlSugar:[SqlSugar](https://gitee.com/dotnetchina/SqlSugar)
|
||||||
- 👉vue-element-admin:[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
|
- 👉vue-element-admin:[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
|
||||||
- 👉Meiam.System:[Meiam.System](https://github.com/91270/Meiam.System)
|
- 👉Meiam.System:[Meiam.System](https://github.com/91270/Meiam.System)
|
||||||
|
- 👉Furion:[Furion](https://gitee.com/dotnetchina/Furion)
|
||||||
|
|
||||||
## 🎀 捐赠
|
## 🎀 捐赠
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using Infrastructure.Extensions;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
|
using ZR.Service.IService;
|
||||||
using ZR.Service.System;
|
using ZR.Service.System;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
|
||||||
@@ -14,6 +13,8 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// 公共模块
|
/// 公共模块
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("[controller]/[action]")]
|
[Route("[controller]/[action]")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
|
//[Produces("application/json")]
|
||||||
public class CommonController : BaseController
|
public class CommonController : BaseController
|
||||||
{
|
{
|
||||||
private OptionsSetting OptionsSetting;
|
private OptionsSetting OptionsSetting;
|
||||||
@@ -21,18 +22,22 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
|
|
||||||
private IWebHostEnvironment WebHostEnvironment;
|
private IWebHostEnvironment WebHostEnvironment;
|
||||||
private ISysFileService SysFileService;
|
private ISysFileService SysFileService;
|
||||||
|
private IHelloService HelloService;
|
||||||
|
|
||||||
public CommonController(
|
public CommonController(
|
||||||
IOptions<OptionsSetting> options,
|
IOptions<OptionsSetting> options,
|
||||||
IWebHostEnvironment webHostEnvironment,
|
IWebHostEnvironment webHostEnvironment,
|
||||||
ISysFileService fileService)
|
ISysFileService fileService,
|
||||||
|
IHelloService helloService)
|
||||||
{
|
{
|
||||||
WebHostEnvironment = webHostEnvironment;
|
WebHostEnvironment = webHostEnvironment;
|
||||||
SysFileService = fileService;
|
SysFileService = fileService;
|
||||||
OptionsSetting = options.Value;
|
OptionsSetting = options.Value;
|
||||||
|
HelloService = helloService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// hello
|
/// home
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Route("/")]
|
[Route("/")]
|
||||||
@@ -43,6 +48,18 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
"如果觉得项目有用,打赏作者喝杯咖啡作为奖励\n☛☛http://www.izhaorui.cn/doc/support.html\n");
|
"如果觉得项目有用,打赏作者喝杯咖啡作为奖励\n☛☛http://www.izhaorui.cn/doc/support.html\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// hello
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Route("/hello")]
|
||||||
|
[HttpGet]
|
||||||
|
public IActionResult Hello(string name)
|
||||||
|
{
|
||||||
|
return Ok(HelloService.SayHello(name));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 企业消息测试
|
/// 企业消息测试
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// 文章目录Controller
|
/// 文章目录Controller
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Route("article/ArticleCategory")]
|
[Route("article/ArticleCategory")]
|
||||||
|
[ApiExplorerSettings(GroupName = "article")]
|
||||||
public class ArticleCategoryController : BaseController
|
public class ArticleCategoryController : BaseController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("article")]
|
[Route("article")]
|
||||||
|
[ApiExplorerSettings(GroupName = "article")]
|
||||||
public class ArticleController : BaseController
|
public class ArticleController : BaseController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -32,7 +33,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
[ActionPermissionFilter(Permission = "system:article:list")]
|
[ActionPermissionFilter(RolePermi = "admin")]
|
||||||
public IActionResult Query([FromQuery] ArticleQueryDto parm)
|
public IActionResult Query([FromQuery] ArticleQueryDto parm)
|
||||||
{
|
{
|
||||||
var response = _ArticleService.GetList(parm);
|
var response = _ArticleService.GetList(parm);
|
||||||
@@ -87,7 +88,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
var model = response.Adapt<ArticleDto>();
|
var model = response.Adapt<ArticleDto>();
|
||||||
if (model.IsPublic == 0 && userId != model.UserId)
|
if (model.IsPublic == 0 && userId != model.UserId)
|
||||||
{
|
{
|
||||||
return ToResponse(Infrastructure.ResultCode.CUSTOM_ERROR, "访问失败");
|
return ToResponse(ResultCode.CUSTOM_ERROR, "访问失败");
|
||||||
}
|
}
|
||||||
if (model != null)
|
if (model != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
using Infrastructure;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Infrastructure.Attribute;
|
|
||||||
using Infrastructure.Enums;
|
|
||||||
using Infrastructure.Extensions;
|
|
||||||
using Mapster;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
using ZR.Admin.WebApi.Extensions;
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.CodeGenerator;
|
using ZR.CodeGenerator;
|
||||||
using ZR.CodeGenerator.Model;
|
using ZR.CodeGenerator.Model;
|
||||||
using ZR.CodeGenerator.Service;
|
using ZR.CodeGenerator.Service;
|
||||||
using ZR.Common;
|
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
using ZR.Model.System.Generate;
|
using ZR.Model.System.Generate;
|
||||||
@@ -23,6 +17,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("tool/gen")]
|
[Route("tool/gen")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class CodeGeneratorController : BaseController
|
public class CodeGeneratorController : BaseController
|
||||||
{
|
{
|
||||||
private readonly CodeGeneraterService _CodeGeneraterService = new CodeGeneraterService();
|
private readonly CodeGeneraterService _CodeGeneraterService = new CodeGeneraterService();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/CommonLang")]
|
[Route("system/CommonLang")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class CommonLangController : BaseController
|
public class CommonLangController : BaseController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/config")]
|
[Route("system/config")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysConfigController : BaseController
|
public class SysConfigController : BaseController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
@@ -13,6 +12,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/dept")]
|
[Route("system/dept")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysDeptController : BaseController
|
public class SysDeptController : BaseController
|
||||||
{
|
{
|
||||||
public ISysDeptService DeptService;
|
public ISysDeptService DeptService;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
@@ -13,6 +12,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/dict/data")]
|
[Route("system/dict/data")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysDictDataController : BaseController
|
public class SysDictDataController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysDictDataService SysDictDataService;
|
private readonly ISysDictDataService SysDictDataService;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/dict/type")]
|
[Route("system/dict/type")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysDictTypeController : BaseController
|
public class SysDictTypeController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysDictService SysDictService;
|
private readonly ISysDictService SysDictService;
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Infrastructure.Attribute;
|
|
||||||
using Infrastructure.Enums;
|
|
||||||
using Infrastructure.Model;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Common;
|
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Service.System.IService;
|
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
|
using ZR.Service.System.IService;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers
|
namespace ZR.Admin.WebApi.Controllers
|
||||||
{
|
{
|
||||||
@@ -16,6 +12,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("tool/file")]
|
[Route("tool/file")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysFileController : BaseController
|
public class SysFileController : BaseController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -37,15 +34,13 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
[ActionPermissionFilter(Permission = "tool:file:list")]
|
[ActionPermissionFilter(Permission = "tool:file:list")]
|
||||||
public IActionResult QuerySysFile([FromQuery] SysFileQueryDto parm)
|
public IActionResult QuerySysFile([FromQuery] SysFileQueryDto parm)
|
||||||
{
|
{
|
||||||
//开始拼装查询条件
|
|
||||||
var predicate = Expressionable.Create<SysFile>();
|
var predicate = Expressionable.Create<SysFile>();
|
||||||
//搜索条件查询语法参考Sqlsugar
|
|
||||||
predicate = predicate.AndIF(parm.BeginCreate_time != null, it => it.Create_time >= parm.BeginCreate_time);
|
predicate = predicate.AndIF(parm.BeginCreate_time != null, it => it.Create_time >= parm.BeginCreate_time);
|
||||||
predicate = predicate.AndIF(parm.EndCreate_time != null, it => it.Create_time <= parm.EndCreate_time);
|
predicate = predicate.AndIF(parm.EndCreate_time != null, it => it.Create_time <= parm.EndCreate_time);
|
||||||
predicate = predicate.AndIF(parm.StoreType != null, m => m.StoreType == parm.StoreType);
|
predicate = predicate.AndIF(parm.StoreType != null, m => m.StoreType == parm.StoreType);
|
||||||
predicate = predicate.AndIF(parm.FileId != null, m => m.Id == parm.FileId);
|
predicate = predicate.AndIF(parm.FileId != null, m => m.Id == parm.FileId);
|
||||||
|
|
||||||
//搜索条件查询语法参考Sqlsugar
|
|
||||||
var response = _SysFileService.GetPages(predicate.ToExpression(), parm, x => x.Id, OrderByType.Desc);
|
var response = _SysFileService.GetPages(predicate.ToExpression(), parm, x => x.Id, OrderByType.Desc);
|
||||||
return SUCCESS(response);
|
return SUCCESS(response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
using IPTools.Core;
|
using Lazy.Captcha.Core;
|
||||||
using Lazy.Captcha.Core;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using UAParser;
|
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Admin.WebApi.Framework;
|
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
using ZR.Service.System;
|
using ZR.Service.System;
|
||||||
@@ -16,9 +12,10 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录
|
/// 登录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysLoginController : BaseController
|
public class SysLoginController : BaseController
|
||||||
{
|
{
|
||||||
static readonly NLog.Logger logger = NLog.LogManager.GetLogger("LoginController");
|
//static readonly NLog.Logger logger = NLog.LogManager.GetLogger("LoginController");
|
||||||
private readonly IHttpContextAccessor httpContextAccessor;
|
private readonly IHttpContextAccessor httpContextAccessor;
|
||||||
private readonly ISysUserService sysUserService;
|
private readonly ISysUserService sysUserService;
|
||||||
private readonly ISysMenuService sysMenuService;
|
private readonly ISysMenuService sysMenuService;
|
||||||
@@ -27,7 +24,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
private readonly ICaptcha SecurityCodeHelper;
|
private readonly ICaptcha SecurityCodeHelper;
|
||||||
private readonly ISysConfigService sysConfigService;
|
private readonly ISysConfigService sysConfigService;
|
||||||
private readonly ISysRoleService roleService;
|
private readonly ISysRoleService roleService;
|
||||||
private readonly OptionsSetting jwtSettings;
|
private readonly OptionsSetting optionSettings;
|
||||||
|
|
||||||
public SysLoginController(
|
public SysLoginController(
|
||||||
IHttpContextAccessor contextAccessor,
|
IHttpContextAccessor contextAccessor,
|
||||||
@@ -38,7 +35,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
ISysConfigService configService,
|
ISysConfigService configService,
|
||||||
ISysRoleService sysRoleService,
|
ISysRoleService sysRoleService,
|
||||||
ICaptcha captcha,
|
ICaptcha captcha,
|
||||||
IOptions<OptionsSetting> jwtSettings)
|
IOptions<OptionsSetting> optionSettings)
|
||||||
{
|
{
|
||||||
httpContextAccessor = contextAccessor;
|
httpContextAccessor = contextAccessor;
|
||||||
SecurityCodeHelper = captcha;
|
SecurityCodeHelper = captcha;
|
||||||
@@ -48,7 +45,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
this.sysConfigService = configService;
|
this.sysConfigService = configService;
|
||||||
roleService = sysRoleService;
|
roleService = sysRoleService;
|
||||||
this.jwtSettings = jwtSettings.Value;
|
this.optionSettings = optionSettings.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -70,15 +67,17 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
|
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
var user = sysLoginService.Login(loginBody, RecordLogInfo(httpContextAccessor.HttpContext));
|
sysLoginService.CheckLockUser(loginBody.Username);
|
||||||
|
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
|
||||||
|
var user = sysLoginService.Login(loginBody, new SysLogininfor() { LoginLocation = location });
|
||||||
|
|
||||||
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
|
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
|
||||||
//权限集合 eg *:*:*,system:user:list
|
//权限集合 eg *:*:*,system:user:list
|
||||||
List<string> permissions = permissionService.GetMenuPermission(user);
|
List<string> permissions = permissionService.GetMenuPermission(user);
|
||||||
|
|
||||||
LoginUser loginUser = new(user, roles, permissions);
|
TokenModel loginUser = new(user.Adapt<TokenModel>(), roles.Adapt<List<Roles>>());
|
||||||
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
|
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
|
||||||
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), jwtSettings.JwtSettings));
|
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -118,6 +117,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
//权限集合 eg *:*:*,system:user:list
|
//权限集合 eg *:*:*,system:user:list
|
||||||
List<string> permissions = permissionService.GetMenuPermission(user);
|
List<string> permissions = permissionService.GetMenuPermission(user);
|
||||||
user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)];
|
user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)];
|
||||||
|
|
||||||
return SUCCESS(new { user, roles, permissions });
|
return SUCCESS(new { user, roles, permissions });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,28 +152,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
return SUCCESS(obj);
|
return SUCCESS(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 记录用户登陆信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public SysLogininfor RecordLogInfo(HttpContext context)
|
|
||||||
{
|
|
||||||
var ipAddr = context.GetClientUserIp();
|
|
||||||
var ip_info = IpTool.Search(ipAddr);
|
|
||||||
ClientInfo clientInfo = context.GetClientInfo();
|
|
||||||
SysLogininfor sysLogininfor = new()
|
|
||||||
{
|
|
||||||
Browser = clientInfo.ToString(),
|
|
||||||
Os = clientInfo.OS.ToString(),
|
|
||||||
Ipaddr = ipAddr,
|
|
||||||
UserName = context.GetName(),
|
|
||||||
LoginLocation = ip_info?.Province + "-" + ip_info?.City
|
|
||||||
};
|
|
||||||
|
|
||||||
return sysLogininfor;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 注册
|
/// 注册
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -181,7 +159,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("/register")]
|
[HttpPost("/register")]
|
||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
[Log(Title = "注册", BusinessType = Infrastructure.Enums.BusinessType.INSERT)]
|
[Log(Title = "注册", BusinessType = BusinessType.INSERT)]
|
||||||
public IActionResult Register([FromBody] RegisterDto dto)
|
public IActionResult Register([FromBody] RegisterDto dto)
|
||||||
{
|
{
|
||||||
SysConfig config = sysConfigService.GetSysConfigByKey("sys.account.register");
|
SysConfig config = sysConfigService.GetSysConfigByKey("sys.account.register");
|
||||||
@@ -202,5 +180,86 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
}
|
}
|
||||||
return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员");
|
return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region 二维码登录
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 生成二维码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="uuid"></param>
|
||||||
|
/// <param name="deviceId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("/GenerateQrcode")]
|
||||||
|
public IActionResult GenerateQrcode(string uuid, string deviceId)
|
||||||
|
{
|
||||||
|
var state = Guid.NewGuid().ToString();
|
||||||
|
var dict = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "state", state }
|
||||||
|
};
|
||||||
|
CacheService.SetScanLogin(uuid, dict);
|
||||||
|
return SUCCESS(new
|
||||||
|
{
|
||||||
|
status = 1,
|
||||||
|
state,
|
||||||
|
uuid,
|
||||||
|
codeContent = new { uuid, deviceId }// "https://qm.qq.com/cgi-bin/qm/qr?k=kgt4HsckdljU0VM-0kxND6d_igmfuPlL&authKey=r55YUbruiKQ5iwC/folG7KLCmZ++Y4rQVgNlvLbUniUMkbk24Y9+zNuOmOnjAjRc&noverify=0"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 轮询判断扫码状态
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("/VerifyScan")]
|
||||||
|
[AllowAnonymous]
|
||||||
|
public IActionResult VerifyScan([FromBody] ScanDto dto)
|
||||||
|
{
|
||||||
|
int status = -1;
|
||||||
|
object token = string.Empty;
|
||||||
|
if (CacheService.GetScanLogin(dto.Uuid) is Dictionary<string, object> str)
|
||||||
|
{
|
||||||
|
status = 0;
|
||||||
|
str.TryGetValue("token", out token);
|
||||||
|
if (str.ContainsKey("status") && (string)str.GetValueOrDefault("status") == "success")
|
||||||
|
{
|
||||||
|
status = 2;//扫码成功
|
||||||
|
CacheService.RemoveScanLogin(dto.Uuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SUCCESS(new { status, token });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 移动端扫码登录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("/ScanLogin")]
|
||||||
|
[Log(Title = "扫码登录")]
|
||||||
|
[Verify]
|
||||||
|
public IActionResult ScanLogin([FromBody] ScanDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null) { return ToResponse(ResultCode.CUSTOM_ERROR, "扫码失败"); }
|
||||||
|
var name = App.HttpContext.GetName();
|
||||||
|
|
||||||
|
sysLoginService.CheckLockUser(name);
|
||||||
|
|
||||||
|
TokenModel tokenModel = JwtUtil.GetLoginUser(HttpContext);
|
||||||
|
if (CacheService.GetScanLogin(dto.Uuid) is not null)
|
||||||
|
{
|
||||||
|
Dictionary<string, object> dict = new() { };
|
||||||
|
dict.Add("status", "success");
|
||||||
|
dict.Add("token", JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(tokenModel)));
|
||||||
|
CacheService.SetScanLogin(dto.Uuid, dict);
|
||||||
|
|
||||||
|
return SUCCESS(1);
|
||||||
|
}
|
||||||
|
return ToResponse(ResultCode.FAIL, "二维码已失效");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
@@ -12,6 +11,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("/system/menu")]
|
[Route("/system/menu")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysMenuController : BaseController
|
public class SysMenuController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysRoleService sysRoleService;
|
private readonly ISysRoleService sysRoleService;
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
using Infrastructure.Constant;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Admin.WebApi.Hubs;
|
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
using ZR.ServiceCore.Signalr;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers.System
|
namespace ZR.Admin.WebApi.Controllers.System
|
||||||
{
|
{
|
||||||
@@ -17,6 +15,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/notice")]
|
[Route("system/notice")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysNoticeController : BaseController
|
public class SysNoticeController : BaseController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using Infrastructure.Extensions;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
@@ -14,6 +12,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/post")]
|
[Route("system/post")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysPostController : BaseController
|
public class SysPostController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysPostService PostService;
|
private readonly ISysPostService PostService;
|
||||||
@@ -122,7 +121,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// 岗位导出
|
/// 岗位导出
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title= "岗位导出")]
|
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "岗位导出")]
|
||||||
[HttpGet("export")]
|
[HttpGet("export")]
|
||||||
[ActionPermissionFilter(Permission = "system:post:export")]
|
[ActionPermissionFilter(Permission = "system:post:export")]
|
||||||
public IActionResult Export()
|
public IActionResult Export()
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
@@ -12,6 +11,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/user/profile")]
|
[Route("system/user/profile")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysProfileController : BaseController
|
public class SysProfileController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysUserService UserService;
|
private readonly ISysUserService UserService;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
@@ -13,6 +12,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/role")]
|
[Route("system/role")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysRoleController : BaseController
|
public class SysRoleController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysRoleService sysRoleService;
|
private readonly ISysRoleService sysRoleService;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
@@ -15,6 +14,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/user")]
|
[Route("system/user")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysUserController : BaseController
|
public class SysUserController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysUserService UserService;
|
private readonly ISysUserService UserService;
|
||||||
@@ -93,9 +93,10 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.Create_by = HttpContext.GetName();
|
user.Create_by = HttpContext.GetName();
|
||||||
|
user.Create_time = DateTime.Now;
|
||||||
user.Password = NETCore.Encrypt.EncryptProvider.Md5(user.Password);
|
user.Password = NETCore.Encrypt.EncryptProvider.Md5(user.Password);
|
||||||
|
|
||||||
return ToResponse(UserService.InsertUser(user));
|
return SUCCESS(UserService.InsertUser(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -143,7 +144,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
public IActionResult Remove(int userid = 0)
|
public IActionResult Remove(int userid = 0)
|
||||||
{
|
{
|
||||||
if (userid <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
|
if (userid <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
|
||||||
if (userid == 1) return ToResponse(Infrastructure.ResultCode.FAIL, "不能删除管理员账号");
|
if (userid == 1) return ToResponse(ResultCode.FAIL, "不能删除管理员账号");
|
||||||
int result = UserService.DeleteUser(userid);
|
int result = UserService.DeleteUser(userid);
|
||||||
|
|
||||||
return ToResponse(result);
|
return ToResponse(result);
|
||||||
@@ -156,7 +157,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
[HttpPut("resetPwd")]
|
[HttpPut("resetPwd")]
|
||||||
[Log(Title = "重置密码", BusinessType = BusinessType.UPDATE)]
|
[Log(Title = "重置密码", BusinessType = BusinessType.UPDATE)]
|
||||||
[ActionPermissionFilter(Permission = "system:user:resetPwd")]
|
[ActionPermissionFilter(Permission = "system:user:resetPwd")]
|
||||||
public IActionResult ResetPwd([FromBody] SysUser sysUser)
|
public IActionResult ResetPwd([FromBody] SysUserDto sysUser)
|
||||||
{
|
{
|
||||||
//密码md5
|
//密码md5
|
||||||
sysUser.Password = NETCore.Encrypt.EncryptProvider.Md5(sysUser.Password);
|
sysUser.Password = NETCore.Encrypt.EncryptProvider.Md5(sysUser.Password);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/userRole")]
|
[Route("system/userRole")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysUserRoleController : BaseController
|
public class SysUserRoleController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysUserRoleService SysUserRoleService;
|
private readonly ISysUserRoleService SysUserRoleService;
|
||||||
@@ -43,7 +44,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("create")]
|
[HttpPost("create")]
|
||||||
[ActionPermissionFilter(Permission = "system:roleusers:add")]
|
[ActionPermissionFilter(Permission = "system:roleusers:add")]
|
||||||
[Log(Title = "添加角色用户", BusinessType = Infrastructure.Enums.BusinessType.INSERT)]
|
[Log(Title = "添加角色用户", BusinessType = BusinessType.INSERT)]
|
||||||
public IActionResult Create([FromBody] RoleUsersCreateDto roleUsersCreateDto)
|
public IActionResult Create([FromBody] RoleUsersCreateDto roleUsersCreateDto)
|
||||||
{
|
{
|
||||||
var response = SysUserRoleService.InsertRoleUser(roleUsersCreateDto);
|
var response = SysUserRoleService.InsertRoleUser(roleUsersCreateDto);
|
||||||
@@ -58,7 +59,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("delete")]
|
[HttpPost("delete")]
|
||||||
[ActionPermissionFilter(Permission = "system:roleusers:remove")]
|
[ActionPermissionFilter(Permission = "system:roleusers:remove")]
|
||||||
[Log(Title = "删除角色用户", BusinessType = Infrastructure.Enums.BusinessType.DELETE)]
|
[Log(Title = "删除角色用户", BusinessType = BusinessType.DELETE)]
|
||||||
public IActionResult Delete([FromBody] RoleUsersCreateDto roleUsersCreateDto)
|
public IActionResult Delete([FromBody] RoleUsersCreateDto roleUsersCreateDto)
|
||||||
{
|
{
|
||||||
return SUCCESS(SysUserRoleService.DeleteRoleUserByUserIds(roleUsersCreateDto.RoleId, roleUsersCreateDto.UserIds));
|
return SUCCESS(SysUserRoleService.DeleteRoleUserByUserIds(roleUsersCreateDto.RoleId, roleUsersCreateDto.UserIds));
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using Infrastructure.Extensions;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Quartz;
|
using Quartz;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
@@ -16,6 +14,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("system/Tasks")]
|
[Route("system/Tasks")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class TasksController : BaseController
|
public class TasksController : BaseController
|
||||||
{
|
{
|
||||||
private ISysTasksQzService _tasksQzService;
|
private ISysTasksQzService _tasksQzService;
|
||||||
@@ -87,7 +86,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
throw new CustomException($"程序集或者类名不能为空");
|
throw new CustomException($"程序集或者类名不能为空");
|
||||||
}
|
}
|
||||||
//从 Dto 映射到 实体
|
//从 Dto 映射到 实体
|
||||||
var tasksQz = parm.Adapt<SysTasks>().ToCreate();
|
var tasksQz = parm.Adapt<SysTasks>().ToCreate(HttpContext);
|
||||||
tasksQz.Create_by = HttpContext.GetName();
|
tasksQz.Create_by = HttpContext.GetName();
|
||||||
tasksQz.ID = SnowFlakeSingle.Instance.NextId().ToString();
|
tasksQz.ID = SnowFlakeSingle.Instance.NextId().ToString();
|
||||||
|
|
||||||
@@ -159,7 +158,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
var tasksQz = _tasksQzService.GetFirst(m => m.ID == id);
|
var tasksQz = _tasksQzService.GetFirst(m => m.ID == id);
|
||||||
var taskResult = await _schedulerServer.DeleteTaskScheduleAsync(tasksQz);
|
var taskResult = await _schedulerServer.DeleteTaskScheduleAsync(tasksQz);
|
||||||
|
|
||||||
if (taskResult.Code == 200)
|
if (taskResult.IsSuccess())
|
||||||
{
|
{
|
||||||
_tasksQzService.Delete(id);
|
_tasksQzService.Delete(id);
|
||||||
}
|
}
|
||||||
@@ -188,7 +187,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
var tasksQz = _tasksQzService.GetFirst(m => m.ID == id);
|
var tasksQz = _tasksQzService.GetFirst(m => m.ID == id);
|
||||||
var taskResult = await _schedulerServer.AddTaskScheduleAsync(tasksQz);
|
var taskResult = await _schedulerServer.AddTaskScheduleAsync(tasksQz);
|
||||||
|
|
||||||
if (taskResult.Code == 200)
|
if (taskResult.IsSuccess())
|
||||||
{
|
{
|
||||||
tasksQz.IsStart = 1;
|
tasksQz.IsStart = 1;
|
||||||
_tasksQzService.Update(tasksQz);
|
_tasksQzService.Update(tasksQz);
|
||||||
@@ -219,7 +218,7 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
var tasksQz = _tasksQzService.GetFirst(m => m.ID == id);
|
var tasksQz = _tasksQzService.GetFirst(m => m.ID == id);
|
||||||
var taskResult = await _schedulerServer.DeleteTaskScheduleAsync(tasksQz);//await _schedulerServer.PauseTaskScheduleAsync(tasksQz);
|
var taskResult = await _schedulerServer.DeleteTaskScheduleAsync(tasksQz);//await _schedulerServer.PauseTaskScheduleAsync(tasksQz);
|
||||||
|
|
||||||
if (taskResult.Code == 200)
|
if (taskResult.IsSuccess())
|
||||||
{
|
{
|
||||||
tasksQz.IsStart = 0;
|
tasksQz.IsStart = 0;
|
||||||
_tasksQzService.Update(tasksQz);
|
_tasksQzService.Update(tasksQz);
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
using Infrastructure;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Infrastructure.Attribute;
|
|
||||||
using Infrastructure.Enums;
|
|
||||||
using Infrastructure.Extensions;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Common;
|
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
@@ -18,6 +13,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("/monitor/jobLog")]
|
[Route("/monitor/jobLog")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class TasksLogController : BaseController
|
public class TasksLogController : BaseController
|
||||||
{
|
{
|
||||||
private readonly ISysTasksLogService tasksLogService;
|
private readonly ISysTasksLogService tasksLogService;
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
using Infrastructure;
|
|
||||||
using Infrastructure.Extensions;
|
using Infrastructure.Extensions;
|
||||||
using Infrastructure.Model;
|
|
||||||
using Microsoft.AspNetCore.Authorization;
|
|
||||||
using Microsoft.AspNetCore.Hosting;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
@@ -14,6 +9,7 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 系统监控
|
/// 系统监控
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class MonitorController : BaseController
|
public class MonitorController : BaseController
|
||||||
{
|
{
|
||||||
private OptionsSetting Options;
|
private OptionsSetting Options;
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using ZR.Admin.WebApi.Filters;
|
||||||
|
using ZR.Model.System.Dto;
|
||||||
|
using ZR.Service.System.IService;
|
||||||
|
|
||||||
|
//创建时间:2023-08-17
|
||||||
|
namespace ZR.Admin.WebApi.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据差异日志
|
||||||
|
/// </summary>
|
||||||
|
[Verify]
|
||||||
|
[Route("monitor/SqlDiffLog")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
|
public class SqlDiffLogController : BaseController
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据差异日志接口
|
||||||
|
/// </summary>
|
||||||
|
private readonly ISqlDiffLogService _SqlDiffLogService;
|
||||||
|
|
||||||
|
public SqlDiffLogController(ISqlDiffLogService SqlDiffLogService)
|
||||||
|
{
|
||||||
|
_SqlDiffLogService = SqlDiffLogService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查询数据差异日志列表
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parm"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("list")]
|
||||||
|
[ActionPermissionFilter(Permission = "sqldifflog:list")]
|
||||||
|
public IActionResult QuerySqlDiffLog([FromQuery] SqlDiffLogQueryDto parm)
|
||||||
|
{
|
||||||
|
var response = _SqlDiffLogService.GetList(parm);
|
||||||
|
return SUCCESS(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除数据差异日志
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("{ids}")]
|
||||||
|
[ActionPermissionFilter(Permission = "sqldifflog:delete")]
|
||||||
|
[Log(Title = "数据差异日志", BusinessType = BusinessType.DELETE)]
|
||||||
|
public IActionResult DeleteSqlDiffLog(string ids)
|
||||||
|
{
|
||||||
|
long[] idsArr = Tools.SpitLongArrary(ids);
|
||||||
|
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||||
|
|
||||||
|
var response = _SqlDiffLogService.Delete(idsArr);
|
||||||
|
|
||||||
|
return ToResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导出数据差异日志
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Log(Title = "数据差异日志", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
|
||||||
|
[HttpGet("export")]
|
||||||
|
[ActionPermissionFilter(Permission = "sqldifflog:export")]
|
||||||
|
public IActionResult Export([FromQuery] SqlDiffLogQueryDto parm)
|
||||||
|
{
|
||||||
|
parm.PageNum = 1;
|
||||||
|
parm.PageSize = 100000;
|
||||||
|
var list = _SqlDiffLogService.GetList(parm).Result;
|
||||||
|
if (list == null || list.Count <= 0)
|
||||||
|
{
|
||||||
|
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
|
||||||
|
}
|
||||||
|
var result = ExportExcelMini(list, "数据差异日志", "数据差异日志");
|
||||||
|
return ExportExcel(result.Item2, result.Item1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("/monitor/logininfor")]
|
[Route("/monitor/logininfor")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysLogininforController : BaseController
|
public class SysLogininforController : BaseController
|
||||||
{
|
{
|
||||||
private ISysLoginService sysLoginService;
|
private ISysLoginService sysLoginService;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("/monitor/operlog")]
|
[Route("/monitor/operlog")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysOperlogController : BaseController
|
public class SysOperlogController : BaseController
|
||||||
{
|
{
|
||||||
private ISysOperLogService sysOperLogService;
|
private ISysOperLogService sysOperLogService;
|
||||||
@@ -65,7 +66,7 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
|||||||
{
|
{
|
||||||
if (!HttpContextExtension.IsAdmin(HttpContext))
|
if (!HttpContextExtension.IsAdmin(HttpContext))
|
||||||
{
|
{
|
||||||
return ToResponse(Infrastructure.ResultCode.CUSTOM_ERROR,"操作失败");
|
return ToResponse(ResultCode.CUSTOM_ERROR,"操作失败");
|
||||||
}
|
}
|
||||||
sysOperLogService.CleanOperLog();
|
sysOperLogService.CleanOperLog();
|
||||||
|
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.SignalR;
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
using ZR.Admin.WebApi.Hubs;
|
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
|
using ZR.Model.System.Dto;
|
||||||
|
using ZR.ServiceCore.Signalr;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers.monitor
|
namespace ZR.Admin.WebApi.Controllers.monitor
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 在线用户
|
||||||
|
/// </summary>
|
||||||
[Verify]
|
[Verify]
|
||||||
[Route("monitor/online")]
|
[Route("monitor/online")]
|
||||||
|
[ApiExplorerSettings(GroupName = "sys")]
|
||||||
public class SysUserOnlineController : BaseController
|
public class SysUserOnlineController : BaseController
|
||||||
{
|
{
|
||||||
private IHubContext<Hub> HubContext;
|
private readonly IHubContext<MessageHub> HubContext;
|
||||||
|
|
||||||
public SysUserOnlineController(IHubContext<Hub> hubContext)
|
public SysUserOnlineController(IHubContext<MessageHub> hubContext)
|
||||||
{
|
{
|
||||||
HubContext = hubContext;
|
HubContext = hubContext;
|
||||||
}
|
}
|
||||||
@@ -25,11 +30,47 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
|||||||
[HttpGet("list")]
|
[HttpGet("list")]
|
||||||
public IActionResult Index([FromQuery] PagerInfo parm)
|
public IActionResult Index([FromQuery] PagerInfo parm)
|
||||||
{
|
{
|
||||||
var result = MessageHub.clientUsers
|
var result = MessageHub.onlineClients
|
||||||
.OrderByDescending(f => f.LoginTime)
|
.OrderByDescending(f => f.LoginTime)
|
||||||
.Skip(parm.PageNum - 1).Take(parm.PageSize);
|
.Skip(parm.PageNum - 1).Take(parm.PageSize);
|
||||||
|
|
||||||
return SUCCESS(new { result, totalNum = MessageHub.clientUsers.Count });
|
return SUCCESS(new { result, totalNum = MessageHub.onlineClients.Count });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 单个强退
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("force")]
|
||||||
|
[Log(Title = "强退", BusinessType = BusinessType.FORCE)]
|
||||||
|
[ActionPermissionFilter(Permission = "monitor:online:forceLogout")]
|
||||||
|
public async Task<IActionResult> Force([FromBody] LockUserDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null) { return ToResponse(ResultCode.PARAM_ERROR); }
|
||||||
|
|
||||||
|
await HubContext.Clients.Client(dto.ConnnectionId)
|
||||||
|
.SendAsync(HubsConstant.ForceUser, new { dto.Reason, dto.Time });
|
||||||
|
|
||||||
|
//var expirTime = DateTimeHelper.GetUnixTimeSeconds(DateTime.Now.AddMinutes(dto.Time));
|
||||||
|
////PC 端采用设备 + 用户名的方式进行封锁
|
||||||
|
//CacheService.SetLockUser(dto.ClientId + dto.Name, expirTime, dto.Time);
|
||||||
|
return SUCCESS(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 批量强退
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpDelete("batchForce")]
|
||||||
|
[Log(Title = "强退", BusinessType = BusinessType.FORCE)]
|
||||||
|
[ActionPermissionFilter(Permission = "monitor:online:batchLogout")]
|
||||||
|
public async Task<IActionResult> BatchforceLogout([FromBody] LockUserDto dto)
|
||||||
|
{
|
||||||
|
if (dto == null) { return ToResponse(ResultCode.PARAM_ERROR); }
|
||||||
|
|
||||||
|
await HubContext.Clients.All.SendAsync(HubsConstant.ForceUser, new { dto.Reason });
|
||||||
|
|
||||||
|
return SUCCESS(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Infrastructure.Extensions;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers
|
namespace ZR.Admin.WebApi.Controllers
|
||||||
@@ -11,9 +10,6 @@ namespace ZR.Admin.WebApi.Controllers
|
|||||||
[AllowAnonymous]
|
[AllowAnonymous]
|
||||||
public class WxOpenController : BaseController
|
public class WxOpenController : BaseController
|
||||||
{
|
{
|
||||||
private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
||||||
public WxOpenController() { }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取签名
|
/// 获取签名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using Infrastructure;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Swashbuckle.AspNetCore.Filters;
|
using Swashbuckle.AspNetCore.Filters;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Extensions
|
namespace ZR.Admin.WebApi.Extensions
|
||||||
@@ -33,7 +33,13 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "ZrAdmin v1"));
|
app.UseSwaggerUI(c =>
|
||||||
|
{
|
||||||
|
c.SwaggerEndpoint("sys/swagger.json", "系统管理");
|
||||||
|
c.SwaggerEndpoint("article/swagger.json", "文章管理");
|
||||||
|
c.SwaggerEndpoint("v1/swagger.json", "business");
|
||||||
|
c.DocExpansion(DocExpansion.None); //->修改界面打开时自动折叠
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddSwaggerConfig(this IServiceCollection services)
|
public static void AddSwaggerConfig(this IServiceCollection services)
|
||||||
@@ -43,6 +49,20 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
|
|
||||||
services.AddSwaggerGen(c =>
|
services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
|
c.SwaggerDoc("sys", new OpenApiInfo
|
||||||
|
{
|
||||||
|
Title = "ZrAdmin.NET Api",
|
||||||
|
Version = "v1",
|
||||||
|
Description = "系统管理",
|
||||||
|
Contact = new OpenApiContact { Name = "ZRAdmin doc", Url = new Uri("https://www.izhaorui.cn/doc") }
|
||||||
|
});
|
||||||
|
c.SwaggerDoc("article", new OpenApiInfo
|
||||||
|
{
|
||||||
|
Title = "ZrAdmin.NET Api",
|
||||||
|
Version = "v1",
|
||||||
|
Description = "文章管理",
|
||||||
|
Contact = new OpenApiContact { Name = "ZRAdmin doc", Url = new Uri("https://www.izhaorui.cn/doc") }
|
||||||
|
});
|
||||||
c.SwaggerDoc("v1", new OpenApiInfo
|
c.SwaggerDoc("v1", new OpenApiInfo
|
||||||
{
|
{
|
||||||
Title = "ZrAdmin.NET Api",
|
Title = "ZrAdmin.NET Api",
|
||||||
@@ -55,6 +75,9 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
//添加文档注释
|
//添加文档注释
|
||||||
var baseDir = AppContext.BaseDirectory;
|
var baseDir = AppContext.BaseDirectory;
|
||||||
c.IncludeXmlComments(Path.Combine(baseDir, "ZR.Model.xml"), true);
|
c.IncludeXmlComments(Path.Combine(baseDir, "ZR.Model.xml"), true);
|
||||||
|
c.IncludeXmlComments(Path.Combine(baseDir, "ZR.ServiceCore.xml"), true);
|
||||||
|
c.IncludeXmlComments(Path.Combine(baseDir, "ZR.Service.xml"), true);
|
||||||
|
c.IncludeXmlComments(Path.Combine(baseDir, "ZR.Admin.WebApi.xml"), true);
|
||||||
|
|
||||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
|
||||||
var xmlPath = Path.Combine(baseDir, xmlFile);
|
var xmlPath = Path.Combine(baseDir, xmlFile);
|
||||||
@@ -94,6 +117,20 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
new List<string>()
|
new List<string>()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//判断接口归于哪个分组
|
||||||
|
c.DocInclusionPredicate((docName, apiDescription) =>
|
||||||
|
{
|
||||||
|
if (docName == "v1")
|
||||||
|
{
|
||||||
|
//当分组为NoGroup时,只要没加特性的都属于这个组
|
||||||
|
return string.IsNullOrEmpty(apiDescription.GroupName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return apiDescription.GroupName == docName;
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace ZR.Admin.WebApi.Extensions
|
|||||||
foreach (var task in tasks.Result)
|
foreach (var task in tasks.Result)
|
||||||
{
|
{
|
||||||
var result = _schedulerServer.AddTaskScheduleAsync(task);
|
var result = _schedulerServer.AddTaskScheduleAsync(task);
|
||||||
if (result.Result.Code == 200)
|
if (result.Result.IsSuccess())
|
||||||
{
|
{
|
||||||
Console.WriteLine($"注册任务[{task.Name}]ID:{task.ID}成功");
|
Console.WriteLine($"注册任务[{task.Name}]ID:{task.ID}成功");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,3 +5,6 @@ global using Infrastructure.Attribute;
|
|||||||
global using Infrastructure.Enums;
|
global using Infrastructure.Enums;
|
||||||
global using Infrastructure.Model;
|
global using Infrastructure.Model;
|
||||||
global using Mapster;
|
global using Mapster;
|
||||||
|
global using Infrastructure.Extensions;
|
||||||
|
global using Infrastructure.Controllers;
|
||||||
|
global using ZR.ServiceCore.Middleware;
|
||||||
@@ -1,107 +0,0 @@
|
|||||||
using Infrastructure;
|
|
||||||
using Infrastructure.Constant;
|
|
||||||
using Infrastructure.Model;
|
|
||||||
using IPTools.Core;
|
|
||||||
using Microsoft.AspNetCore.SignalR;
|
|
||||||
using UAParser;
|
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Service.System.IService;
|
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Hubs
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// msghub
|
|
||||||
/// </summary>
|
|
||||||
public class MessageHub : Hub
|
|
||||||
{
|
|
||||||
//创建用户集合,用于存储所有链接的用户数据
|
|
||||||
public static readonly List<OnlineUsers> clientUsers = new();
|
|
||||||
private readonly NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
|
||||||
private readonly ISysNoticeService SysNoticeService;
|
|
||||||
|
|
||||||
public MessageHub(ISysNoticeService noticeService)
|
|
||||||
{
|
|
||||||
SysNoticeService = noticeService;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApiResult SendNotice()
|
|
||||||
{
|
|
||||||
var result = SysNoticeService.GetSysNotices();
|
|
||||||
|
|
||||||
return new ApiResult(200, "success", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 客户端连接
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 客户端连接的时候调用
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public override Task OnConnectedAsync()
|
|
||||||
{
|
|
||||||
var name = HttpContextExtension.GetName(App.HttpContext);
|
|
||||||
var ip = HttpContextExtension.GetClientUserIp(App.HttpContext);
|
|
||||||
var ip_info = IpTool.Search(ip);
|
|
||||||
|
|
||||||
ClientInfo clientInfo = HttpContextExtension.GetClientInfo(App.HttpContext);
|
|
||||||
string device = clientInfo.ToString();
|
|
||||||
|
|
||||||
var userid = HttpContextExtension.GetUId(App.HttpContext);
|
|
||||||
string uuid = device + userid + ip;
|
|
||||||
var user = clientUsers.Any(u => u.ConnnectionId == Context.ConnectionId);
|
|
||||||
var user2 = clientUsers.Any(u => u.Uuid == uuid);
|
|
||||||
|
|
||||||
//判断用户是否存在,否则添加集合!user2 && !user &&
|
|
||||||
if (!user2 && !user && Context.User.Identity.IsAuthenticated)
|
|
||||||
{
|
|
||||||
OnlineUsers users = new(Context.ConnectionId, name, userid, ip, device)
|
|
||||||
{
|
|
||||||
Location = ip_info.City,
|
|
||||||
Uuid = uuid
|
|
||||||
};
|
|
||||||
clientUsers.Add(users);
|
|
||||||
Console.WriteLine($"{DateTime.Now}:{name},{Context.ConnectionId}连接服务端success,当前已连接{clientUsers.Count}个");
|
|
||||||
//Clients.All.SendAsync("welcome", $"欢迎您:{name},当前时间:{DateTime.Now}");
|
|
||||||
Clients.All.SendAsync(HubsConstant.MoreNotice, SendNotice());
|
|
||||||
}
|
|
||||||
|
|
||||||
Clients.All.SendAsync(HubsConstant.OnlineNum, clientUsers.Count);
|
|
||||||
return base.OnConnectedAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 连接终止时调用。
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public override Task OnDisconnectedAsync(Exception? exception)
|
|
||||||
{
|
|
||||||
var user = clientUsers.Where(p => p.ConnnectionId == Context.ConnectionId).FirstOrDefault();
|
|
||||||
//判断用户是否存在,否则添加集合
|
|
||||||
if (user != null)
|
|
||||||
{
|
|
||||||
clientUsers.Remove(user);
|
|
||||||
Clients.All.SendAsync(HubsConstant.OnlineNum, clientUsers.Count);
|
|
||||||
|
|
||||||
Console.WriteLine($"用户{user?.Name}离开了,当前已连接{clientUsers.Count}个");
|
|
||||||
}
|
|
||||||
return base.OnDisconnectedAsync(exception);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 注册信息
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="connectId"></param>
|
|
||||||
/// <param name="userName"></param>
|
|
||||||
/// <param name="message"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[HubMethodName("SendMessage")]
|
|
||||||
public async Task SendMessage(string connectId, string userName, string message)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"{connectId},message={message}");
|
|
||||||
|
|
||||||
await Clients.Client(connectId).SendAsync("receiveChat", new { userName, message });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
namespace ZR.Admin.WebApi.Hubs
|
|
||||||
{
|
|
||||||
public class OnlineUsers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 客户端连接Id
|
|
||||||
/// </summary>
|
|
||||||
public string ConnnectionId { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 用户id
|
|
||||||
/// </summary>
|
|
||||||
public long? Userid { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
public DateTime LoginTime { get; set; }
|
|
||||||
public string UserIP { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 登录地点
|
|
||||||
/// </summary>
|
|
||||||
public string? Location { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 判断用户唯一
|
|
||||||
/// </summary>
|
|
||||||
public string? Uuid{ get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 浏览器
|
|
||||||
/// </summary>
|
|
||||||
public string Browser { get; set; }
|
|
||||||
|
|
||||||
public OnlineUsers(string clientid, string name, long? userid, string userip, string browser)
|
|
||||||
{
|
|
||||||
ConnnectionId = clientid;
|
|
||||||
Name = name;
|
|
||||||
LoginTime = DateTime.Now;
|
|
||||||
Userid = userid;
|
|
||||||
UserIP = userip;
|
|
||||||
Browser = browser;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+13
-15
@@ -24,29 +24,29 @@
|
|||||||
<!--${basedir}表示当前应用程序域所在的根目录-->
|
<!--${basedir}表示当前应用程序域所在的根目录-->
|
||||||
<target name="allfile" xsi:type="File"
|
<target name="allfile" xsi:type="File"
|
||||||
fileName="${basedir}/adminlogs/all.txt"
|
fileName="${basedir}/adminlogs/all.txt"
|
||||||
archiveFileName="${basedir}/adminlogs/bak/all.{###}.txt"
|
archiveFileName="${basedir}/adminlogs/bak/all/all.{###}.txt"
|
||||||
archiveEvery="Day"
|
archiveEvery="Day"
|
||||||
archiveNumbering="DateAndSequence"
|
archiveNumbering="DateAndSequence"
|
||||||
archiveAboveSize="20000000"
|
archiveAboveSize="20000000"
|
||||||
maxArchiveFiles="30"
|
maxArchiveFiles="30"
|
||||||
keepFileOpen="true"
|
keepFileOpen="true"
|
||||||
layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP:CheckForwardedForHeader=true} | ${event-properties:item=user} | ${aspnet-request-url} | ${message} | ${event-properties:item=requestParam} | ${event-properties:item=jsonResult} | ${onexception:${exception:format=tostring}"/>
|
layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${aspnet-request-connection-id}|${uppercase:${level}}|${logger}|${aspnet-request-iP:CheckForwardedForHeader=true}|${event-properties:item=user:whenEmpty=-}|url: ${aspnet-request-url}|${message:whenEmpty=-}|${event-properties:item=requestParam}|${event-properties:item=jsonResult}"/>
|
||||||
|
|
||||||
<!--错误日志-->
|
<!--错误日志-->
|
||||||
<target name="errorfile" xsi:type="File"
|
<target name="errorfile" xsi:type="File"
|
||||||
fileName="${basedir}/adminlogs/error.txt"
|
fileName="${basedir}/adminlogs/error.txt"
|
||||||
archiveFileName="${basedir}/adminlogs/bak/error.{###}.txt"
|
archiveFileName="${basedir}/adminlogs/bak/error/error.{###}.txt"
|
||||||
archiveEvery="Day"
|
archiveEvery="Day"
|
||||||
archiveNumbering="DateAndSequence"
|
archiveNumbering="DateAndSequence"
|
||||||
archiveAboveSize="20000000"
|
archiveAboveSize="20000000"
|
||||||
maxArchiveFiles="30"
|
maxArchiveFiles="30"
|
||||||
keepFileOpen="true"
|
keepFileOpen="true"
|
||||||
layout="${longdate} | ${event-properties:item=EventId_Id} | ${uppercase:${level}} | ${logger} | ${aspnet-request-iP:CheckForwardedForHeader=true} | ${event-properties:item=user} | ${aspnet-request-url} | ${message} | ${event-properties:item=requestParam} | ${event-properties:item=jsonResult} | ${onexception:${exception:format=tostring}"/>
|
layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${uppercase:${level}}|${logger}${newline}用户IP:${aspnet-request-iP:CheckForwardedForHeader=true}|${event-properties:item=user}${newline}请求地址:${aspnet-request-url}${newline}错误消息:${message}${newline}请求参数:${event-properties:item=requestParam}${newline}请求结果:${event-properties:item=jsonResult}${newline}${onexception:${exception:format=tostring}"/>
|
||||||
|
|
||||||
<!--SQL文件-->
|
<!--SQL文件-->
|
||||||
<target name="sqlfile" xsi:type="File"
|
<target name="sqlfile" xsi:type="File"
|
||||||
fileName="${basedir}/adminlogs/admin-sql.txt"
|
fileName="${basedir}/adminlogs/sql.txt"
|
||||||
archiveFileName="${basedir}/adminlogs/bak/admin-sql{###}.txt"
|
archiveFileName="${basedir}/adminlogs/bak/sql/sql{###}.txt"
|
||||||
archiveEvery="Day"
|
archiveEvery="Day"
|
||||||
archiveNumbering="DateAndSequence"
|
archiveNumbering="DateAndSequence"
|
||||||
archiveAboveSize="20000000"
|
archiveAboveSize="20000000"
|
||||||
@@ -56,18 +56,17 @@
|
|||||||
|
|
||||||
<!--写入彩色控制台-->
|
<!--写入彩色控制台-->
|
||||||
<target name="consoleSql" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
|
<target name="consoleSql" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
|
||||||
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-iP} | ${aspnet-request-url} ${newline}${message}">
|
layout="${date:format=MM-dd HH\:mm\:ss}|${aspnet-request-iP}|${aspnet-request-url}${newline}${message}">
|
||||||
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
|
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
|
||||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
|
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
|
||||||
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
|
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
|
||||||
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
|
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
|
||||||
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
|
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
|
||||||
<highlight-word regex="SQL语句" foregroundColor="Blue" />
|
<highlight-word regex="SQL" foregroundColor="Blue" />
|
||||||
|
<highlight-word regex="【" foregroundColor="Blue" />
|
||||||
|
<highlight-word regex="】" foregroundColor="Blue" />
|
||||||
</target>
|
</target>
|
||||||
|
|
||||||
<target name="console" xsi:type="ColoredConsole"
|
|
||||||
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-url} ${newline} ${message}"/>
|
|
||||||
|
|
||||||
<!--写入黑洞-->
|
<!--写入黑洞-->
|
||||||
<target name="blackhole" xsi:type="Null" />
|
<target name="blackhole" xsi:type="Null" />
|
||||||
</targets>
|
</targets>
|
||||||
@@ -80,11 +79,10 @@
|
|||||||
<!--<logger name="System.*" writeTo="blackhole" final="true" />-->
|
<!--<logger name="System.*" writeTo="blackhole" final="true" />-->
|
||||||
<!-- Quartz -->
|
<!-- Quartz -->
|
||||||
<logger name="Quartz*" minlevel="Trace" maxlevel="Info" final="true" />
|
<logger name="Quartz*" minlevel="Trace" maxlevel="Info" final="true" />
|
||||||
<logger name="ZR.Admin.WebApi.Middleware.GlobalExceptionMiddleware" final="true" writeTo="console,errorfile"/>
|
<logger name="*.SqlSugar.SqlsugarSetup" final="true" writeTo="consoleSql,sqlfile"/>
|
||||||
<logger name="ZR.Admin.WebApi.Extensions.DbExtension" final="true" writeTo="consoleSql,sqlfile"/>
|
|
||||||
<logger name="*" writeTo="console"/>
|
|
||||||
|
|
||||||
<logger name="*" minLevel="Trace" writeTo="allfile" />
|
<logger name="*" minLevel="Trace" writeTo="allfile" />
|
||||||
|
<logger name="*.GlobalExceptionMiddleware" final="true" writeTo="consoleSql,errorfile"/>
|
||||||
|
|
||||||
<!--Skip non-critical Microsoft logs and so log only own logs-->
|
<!--Skip non-critical Microsoft logs and so log only own logs-->
|
||||||
<logger name="Microsoft.*,Quartz.Core.QuartzSchedulerThread" maxlevel="Info" final="true" />
|
<logger name="Microsoft.*,Quartz.Core.QuartzSchedulerThread" maxlevel="Info" final="true" />
|
||||||
</rules>
|
</rules>
|
||||||
|
|||||||
+31
-36
@@ -1,17 +1,19 @@
|
|||||||
using AspNetCoreRateLimit;
|
using AspNetCoreRateLimit;
|
||||||
using Infrastructure;
|
using Infrastructure.Converter;
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
||||||
using Microsoft.AspNetCore.DataProtection;
|
using Microsoft.AspNetCore.DataProtection;
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using NLog.Web;
|
||||||
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
using ZR.Admin.WebApi.Extensions;
|
||||||
using ZR.Admin.WebApi.Filters;
|
|
||||||
using ZR.Admin.WebApi.Framework;
|
|
||||||
using ZR.Admin.WebApi.Hubs;
|
|
||||||
using ZR.Admin.WebApi.Middleware;
|
|
||||||
using ZR.Common.Cache;
|
using ZR.Common.Cache;
|
||||||
|
using ZR.Infrastructure.WebExtensions;
|
||||||
|
using ZR.ServiceCore.Signalr;
|
||||||
|
using ZR.ServiceCore.SqlSugar;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
// NLog: Setup NLog for Dependency injection
|
||||||
|
//builder.Logging.ClearProviders();
|
||||||
|
builder.Host.UseNLog();
|
||||||
|
|
||||||
// Add services to the container.
|
// Add services to the container.
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
@@ -24,8 +26,6 @@ builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
|||||||
builder.Services.AddCors(builder.Configuration);
|
builder.Services.AddCors(builder.Configuration);
|
||||||
// 显示logo
|
// 显示logo
|
||||||
builder.Services.AddLogo();
|
builder.Services.AddLogo();
|
||||||
//注入SignalR实时通讯,默认用json传输
|
|
||||||
builder.Services.AddSignalR();
|
|
||||||
//消除Error unprotecting the session cookie警告
|
//消除Error unprotecting the session cookie警告
|
||||||
builder.Services.AddDataProtection()
|
builder.Services.AddDataProtection()
|
||||||
.PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));
|
.PersistKeysToFileSystem(new DirectoryInfo(Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar + "DataProtection"));
|
||||||
@@ -39,30 +39,10 @@ builder.Services.AddHttpContextAccessor();
|
|||||||
builder.Services.Configure<OptionsSetting>(builder.Configuration);
|
builder.Services.Configure<OptionsSetting>(builder.Configuration);
|
||||||
|
|
||||||
//jwt 认证
|
//jwt 认证
|
||||||
builder.Services.AddAuthentication(options =>
|
builder.Services.AddJwt();
|
||||||
{
|
//配置文件
|
||||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
}).AddCookie()
|
|
||||||
.AddJwtBearer(o =>
|
|
||||||
{
|
|
||||||
o.TokenValidationParameters = JwtUtil.ValidParameters();
|
|
||||||
o.Events = new JwtBearerEvents
|
|
||||||
{
|
|
||||||
OnAuthenticationFailed = context =>
|
|
||||||
{
|
|
||||||
// 如果过期,把过期信息添加到头部
|
|
||||||
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
|
|
||||||
{
|
|
||||||
context.Response.Headers.Add("Token-Expired", "true");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.Services.AddSingleton(new AppSettings(builder.Configuration));
|
builder.Services.AddSingleton(new AppSettings(builder.Configuration));
|
||||||
|
//app服务注册
|
||||||
builder.Services.AddAppService();
|
builder.Services.AddAppService();
|
||||||
//开启计划任务
|
//开启计划任务
|
||||||
builder.Services.AddTaskSchedulers();
|
builder.Services.AddTaskSchedulers();
|
||||||
@@ -80,12 +60,21 @@ builder.Services.AddMvc(options =>
|
|||||||
})
|
})
|
||||||
.AddJsonOptions(options =>
|
.AddJsonOptions(options =>
|
||||||
{
|
{
|
||||||
options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString;
|
//options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString;
|
||||||
options.JsonSerializerOptions.WriteIndented = true;
|
options.JsonSerializerOptions.WriteIndented = true;
|
||||||
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeConverter());
|
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeConverter());
|
||||||
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeNullConverter());
|
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeNullConverter());
|
||||||
|
options.JsonSerializerOptions.Converters.Add(new StringConverter());
|
||||||
|
//PropertyNamingPolicy属性用于前端传过来的属性的格式策略,目前内置的仅有一种策略CamelCase
|
||||||
|
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||||
|
//options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;//属性可以忽略大小写格式,开启后性能会降低
|
||||||
|
});
|
||||||
|
//注入SignalR实时通讯,默认用json传输
|
||||||
|
builder.Services.AddSignalR()
|
||||||
|
.AddJsonProtocol(options =>
|
||||||
|
{
|
||||||
|
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddSwaggerConfig();
|
builder.Services.AddSwaggerConfig();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
@@ -93,11 +82,18 @@ InternalApp.ServiceProvider = app.Services;
|
|||||||
InternalApp.Configuration = builder.Configuration;
|
InternalApp.Configuration = builder.Configuration;
|
||||||
InternalApp.WebHostEnvironment = app.Environment;
|
InternalApp.WebHostEnvironment = app.Environment;
|
||||||
//初始化db
|
//初始化db
|
||||||
builder.Services.AddDb(builder.Configuration, app.Environment);
|
builder.Services.AddDb(app.Environment);
|
||||||
|
|
||||||
//使用全局异常中间件
|
//使用全局异常中间件
|
||||||
app.UseMiddleware<GlobalExceptionMiddleware>();
|
app.UseMiddleware<GlobalExceptionMiddleware>();
|
||||||
|
|
||||||
|
//请求头转发
|
||||||
|
//ForwardedHeaders中间件会自动把反向代理服务器转发过来的X-Forwarded-For(客户端真实IP)以及X-Forwarded-Proto(客户端请求的协议)自动填充到HttpContext.Connection.RemoteIPAddress和HttpContext.Request.Scheme中,这样应用代码中读取到的就是真实的IP和真实的协议了,不需要应用做特殊处理。
|
||||||
|
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||||
|
{
|
||||||
|
ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto
|
||||||
|
});
|
||||||
|
|
||||||
app.Use((context, next) =>
|
app.Use((context, next) =>
|
||||||
{
|
{
|
||||||
//设置可以多次获取body内容
|
//设置可以多次获取body内容
|
||||||
@@ -138,5 +134,4 @@ app.MapControllerRoute(
|
|||||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
|
|
||||||
app.Run();
|
app.Run();
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<NoWarn>1701;1702;1591,8603,8602,8604,8600</NoWarn>
|
<NoWarn>1701;1702;1591,8603,8602,8604,8600,8618</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -15,17 +15,12 @@
|
|||||||
<ProjectReference Include="..\ZR.Tasks\ZR.Tasks.csproj" />
|
<ProjectReference Include="..\ZR.Tasks\ZR.Tasks.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
|
||||||
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.3" />
|
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.3" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" />
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" />
|
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" />
|
||||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.3" />
|
||||||
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
|
||||||
<PackageReference Include="NLog" Version="5.2.0" />
|
|
||||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
|
|
||||||
<PackageReference Include="Mapster" Version="7.3.0" />
|
<PackageReference Include="Mapster" Version="7.3.0" />
|
||||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.3" />
|
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.5" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -36,5 +31,11 @@
|
|||||||
<None Update="ip2region.db">
|
<None Update="ip2region.db">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<Content Update="wwwroot\Generatecode\**\*">
|
||||||
|
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Update="wwwroot\export\**\*">
|
||||||
|
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||||
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
"Conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog={dbName};",
|
"Conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog={dbName};",
|
||||||
"DbType": 1,
|
"DbType": 1,
|
||||||
"IsAutoCloseConnection": true,
|
"IsAutoCloseConnection": true,
|
||||||
"DbName": "ZrAdmin" //代码生成默认连接数据库
|
"DbName": "ZrAdmin" //代码生成默认连接数据库,Oracle库是实例的名称
|
||||||
},
|
},
|
||||||
"urls": "http://localhost:8888", //项目启动url,如果改动端口前端对应devServer也需要进行修改
|
"urls": "http://localhost:8888", //项目启动url,如果改动端口前端对应devServer也需要进行修改
|
||||||
"corsUrls": [ "http://localhost:8887", "http://localhost:8886" ], //跨域地址(前端启动项目,前后端分离单独部署需要设置),多个用","隔开
|
"corsUrls": [ "http://localhost:8887", "http://localhost:8886" ], //跨域地址(前端启动项目,前后端分离单独部署需要设置),多个用","隔开
|
||||||
@@ -29,11 +29,15 @@
|
|||||||
"Issuer": "ZRAdmin.NET", //即token的签发者。
|
"Issuer": "ZRAdmin.NET", //即token的签发者。
|
||||||
"Audience": "ZRAdmin.NET", //指该token是服务于哪个群体的(群体范围)
|
"Audience": "ZRAdmin.NET", //指该token是服务于哪个群体的(群体范围)
|
||||||
"SecretKey": "SecretKey-ZRADMIN.NET-20210101",
|
"SecretKey": "SecretKey-ZRADMIN.NET-20210101",
|
||||||
"Expire": 1440 //jwt登录过期时间(分)
|
"Expire": 1440, //jwt登录过期时间(分)
|
||||||
|
"RefreshTokenTime": 5,//分钟
|
||||||
|
"TokenType": "Bearer"
|
||||||
},
|
},
|
||||||
"InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks" ], //自动注入类
|
"InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks", "ZR.ServiceCore" ], //自动注入类
|
||||||
|
"ShowDbLog": true, //是否打印db日志
|
||||||
"InitDb": false, //是否初始化db
|
"InitDb": false, //是否初始化db
|
||||||
"DemoMode": false, //是否演示模式
|
"DemoMode": false, //是否演示模式
|
||||||
|
"SingleLogin": false,//是否单点登录
|
||||||
"Upload": {
|
"Upload": {
|
||||||
"uploadUrl": "http://localhost:8888", //本地存储资源访问路径
|
"uploadUrl": "http://localhost:8888", //本地存储资源访问路径
|
||||||
"localSavePath": "", //本地上传默认文件存储目录 wwwroot
|
"localSavePath": "", //本地上传默认文件存储目录 wwwroot
|
||||||
@@ -108,7 +112,7 @@
|
|||||||
"RealIpHeader": "X-Real-IP",
|
"RealIpHeader": "X-Real-IP",
|
||||||
"ClientIdHeader": "X-ClientId",
|
"ClientIdHeader": "X-ClientId",
|
||||||
"HttpStatusCode": 429,
|
"HttpStatusCode": 429,
|
||||||
"EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile" ],
|
"EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
|
||||||
"QuotaExceededResponse": {
|
"QuotaExceededResponse": {
|
||||||
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
|
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
|
||||||
"ContentType": "application/json",
|
"ContentType": "application/json",
|
||||||
@@ -127,12 +131,7 @@
|
|||||||
"Period": "3s",
|
"Period": "3s",
|
||||||
"Limit": 1
|
"Limit": 1
|
||||||
}
|
}
|
||||||
],
|
|
||||||
"IpRateLimitPolicies": {
|
|
||||||
//ip规则
|
|
||||||
"IpRules": [
|
|
||||||
]
|
]
|
||||||
}
|
|
||||||
},
|
},
|
||||||
//验证码配置
|
//验证码配置
|
||||||
"CaptchaOptions": {
|
"CaptchaOptions": {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using ${options.DtosNamespace};
|
using ${options.DtosNamespace};
|
||||||
using ${options.ModelsNamespace}.${options.SubNamespace};
|
using ${options.ModelsNamespace}.${options.SubNamespace};
|
||||||
using ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNamespace}Service;
|
using ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNamespace}Service;
|
||||||
using ${options.ApiControllerNamespace}.Extensions;
|
|
||||||
using ${options.ApiControllerNamespace}.Filters;
|
using ${options.ApiControllerNamespace}.Filters;
|
||||||
$if(replaceDto.ShowBtnImport)
|
$if(replaceDto.ShowBtnImport)
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ $end
|
|||||||
$if(null != genTable.SubTableName && "" != genTable.SubTableName)
|
$if(null != genTable.SubTableName && "" != genTable.SubTableName)
|
||||||
return Context.InsertNav(model).Include(s1 => s1.${genTable.SubTable.ClassName}Nav).ExecuteReturnEntity();
|
return Context.InsertNav(model).Include(s1 => s1.${genTable.SubTable.ClassName}Nav).ExecuteReturnEntity();
|
||||||
$else
|
$else
|
||||||
return Insertable(model).IgnoreColumns(true).ExecuteReturnEntity();
|
return Context.Insertable(model).ExecuteReturnEntity();
|
||||||
$end
|
$end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -69,12 +69,14 @@ $end
|
|||||||
|
|
||||||
</u--form>
|
</u--form>
|
||||||
|
|
||||||
<view class="btn-group">
|
<view class="form-footer">
|
||||||
|
<view class="btn_wrap">
|
||||||
<view class="btn-item">
|
<view class="btn-item">
|
||||||
<u-button text="取消" shape="circle" icon="close" type="info" @click="handleCancel"></u-button>
|
<u-button text="取消" shape="circle" type="info" @click="handleCancel"></u-button>
|
||||||
</view>
|
</view>
|
||||||
<view class="btn-item" v-if="opertype != 3">
|
<view class="btn-item" v-if="opertype != 3">
|
||||||
<u-button text="确定" shape="circle" icon="checkmark" type="primary" @click="submit"></u-button>
|
<u-button text="确定" shape="circle" type="primary" @click="submit"></u-button>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -110,7 +112,6 @@ $end
|
|||||||
return {
|
return {
|
||||||
form: {},
|
form: {},
|
||||||
rules: {
|
rules: {
|
||||||
xxx: {},
|
|
||||||
$foreach(column in genTable.Columns)
|
$foreach(column in genTable.Columns)
|
||||||
$if(column.IsRequired && column.IsIncrement == false)
|
$if(column.IsRequired && column.IsIncrement == false)
|
||||||
${column.CsharpFieldFl}: [{
|
${column.CsharpFieldFl}: [{
|
||||||
@@ -185,12 +186,10 @@ $end
|
|||||||
update${genTable.BusinessName}(this.form).then((res) => {
|
update${genTable.BusinessName}(this.form).then((res) => {
|
||||||
this.${modal}modal.msgSuccess("修改成功")
|
this.${modal}modal.msgSuccess("修改成功")
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
|
||||||
} else {
|
} else {
|
||||||
add${genTable.BusinessName}(this.form).then((res) => {
|
add${genTable.BusinessName}(this.form).then((res) => {
|
||||||
this.${modal}modal.msgSuccess("新增成功")
|
this.${modal}modal.msgSuccess("新增成功")
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
|
||||||
}
|
}
|
||||||
}).catch(errors => {
|
}).catch(errors => {
|
||||||
this.${modal}modal.msg('表单校验失败')
|
this.${modal}modal.msg('表单校验失败')
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ $elseif(tool.CheckTree(genTable ,column.CsharpField))
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
$elseif(column.IsPK || column.IsIncrement)
|
$elseif(column.IsPK || column.IsIncrement)
|
||||||
<el-col :lg="12">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
$if(column.IsIncrement == false)
|
$if(column.IsIncrement == false)
|
||||||
<el-input-number v-model.number="form.${columnName}" controls-position="right" placeholder="请输入${labelName}" :disabled="title=='修改数据'"/>
|
<el-input-number v-model.number="form.${columnName}" controls-position="right" placeholder="请输入${labelName}" :disabled="title=='修改数据'"/>
|
||||||
@@ -208,13 +208,13 @@ $end
|
|||||||
</el-col>
|
</el-col>
|
||||||
$else
|
$else
|
||||||
$if(column.HtmlType == "inputNumber")
|
$if(column.HtmlType == "inputNumber")
|
||||||
<el-col :lg="12">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-input-number v-model.number="form.${columnName}" controls-position="right" placeholder="请输入${labelName}" ${labelDisabled}/>
|
<el-input-number v-model.number="form.${columnName}" controls-position="right" placeholder="请输入${labelName}" ${labelDisabled}/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
$elseif(column.HtmlType == "datetime")
|
$elseif(column.HtmlType == "datetime")
|
||||||
<el-col :lg="12">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-date-picker v-model="form.${columnName}" type="datetime" placeholder="选择日期时间"></el-date-picker>
|
<el-date-picker v-model="form.${columnName}" type="datetime" placeholder="选择日期时间"></el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -232,7 +232,7 @@ $elseif(column.HtmlType == "fileUpload")
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
$elseif(column.HtmlType == "radio")
|
$elseif(column.HtmlType == "radio")
|
||||||
<el-col :lg="12">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-radio-group v-model="form.${columnName}">
|
<el-radio-group v-model="form.${columnName}">
|
||||||
<el-radio v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="${value}">{{item.dictLabel}}</el-radio>
|
<el-radio v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="${value}">{{item.dictLabel}}</el-radio>
|
||||||
@@ -252,7 +252,7 @@ $elseif(column.HtmlType == "editor")
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
$elseif(column.HtmlType == "select" || column.HtmlType == "selectMulti")
|
$elseif(column.HtmlType == "select" || column.HtmlType == "selectMulti")
|
||||||
<el-col :lg="12">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-select v-model="form.${columnName}" placeholder="请选择${labelName}"${column.DisabledStr}>
|
<el-select v-model="form.${columnName}" placeholder="请选择${labelName}"${column.DisabledStr}>
|
||||||
<el-option v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="item.dictLabel" :value="${value}"></el-option>
|
<el-option v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="item.dictLabel" :value="${value}"></el-option>
|
||||||
@@ -268,7 +268,7 @@ $elseif(column.HtmlType == "checkbox")
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
$else
|
$else
|
||||||
<el-col :lg="12">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-input v-model="form.${columnName}" placeholder="请输入${labelName}" ${labelDisabled}/>
|
<el-input v-model="form.${columnName}" placeholder="请输入${labelName}" ${labelDisabled}/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -301,10 +301,8 @@ import Editor from '@/components/Editor'
|
|||||||
$end
|
$end
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
// 是否展开,默认全部折叠
|
|
||||||
const isExpandAll = ref(false)
|
const isExpandAll = ref(false)
|
||||||
const refreshTable = ref(true)
|
const refreshTable = ref(true)
|
||||||
// 展开/折叠操作
|
|
||||||
function toggleExpandAll() {
|
function toggleExpandAll() {
|
||||||
refreshTable.value = false
|
refreshTable.value = false
|
||||||
isExpandAll.value = !isExpandAll.value
|
isExpandAll.value = !isExpandAll.value
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ $elseif(column.HtmlType == "datePicker")
|
|||||||
:default-time="defaultTime">
|
:default-time="defaultTime">
|
||||||
</el-date-picker>
|
</el-date-picker>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
$elseif(column.HtmlType.Contains("select") || column.HtmlType == "radio")
|
$elseif(column.HtmlType.Contains("select"))
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-select clearable $if(column.HtmlType == "selectMulti")multiple$end v-model="queryParams.${columnName}" placeholder="请选择${labelName}">
|
<el-select clearable $if(column.HtmlType == "selectMulti")multiple$end v-model="queryParams.${columnName}" placeholder="请选择${labelName}">
|
||||||
<el-option v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue">
|
<el-option v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue">
|
||||||
@@ -65,6 +65,7 @@ $elseif(column.HtmlType.Contains("select") || column.HtmlType == "radio")
|
|||||||
$elseif(column.HtmlType == "radio")
|
$elseif(column.HtmlType == "radio")
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-radio-group v-model="queryParams.${columnName}">
|
<el-radio-group v-model="queryParams.${columnName}">
|
||||||
|
<el-radio>全部</el-radio>
|
||||||
<el-radio v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="item.dictValue">{{item.dictLabel}}</el-radio>
|
<el-radio v-for="item in $if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :key="item.dictValue" :label="item.dictValue">{{item.dictLabel}}</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -81,7 +82,7 @@ $end
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<!-- 工具区域 -->
|
<!-- 工具区域 -->
|
||||||
<el-row :gutter="10" class="mb8">
|
<el-row :gutter="15" class="mb10">
|
||||||
$if(replaceDto.ShowBtnAdd)
|
$if(replaceDto.ShowBtnAdd)
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="primary" v-hasPermi="['${replaceDto.PermissionPrefix}:add']" plain icon="plus" @click="handleAdd">
|
<el-button type="primary" v-hasPermi="['${replaceDto.PermissionPrefix}:add']" plain icon="plus" @click="handleAdd">
|
||||||
@@ -187,7 +188,7 @@ $elseif(column.HtmlType == "imageUpload")
|
|||||||
$elseif(column.HtmlType == "checkbox" || column.HtmlType.Contains("select") || column.HtmlType == "radio")
|
$elseif(column.HtmlType == "checkbox" || column.HtmlType.Contains("select") || column.HtmlType == "radio")
|
||||||
<el-table-column prop="${columnName}" label="${labelName}" align="center"${column.sortStr} v-if="columns.showColumn('${columnName}')">
|
<el-table-column prop="${columnName}" label="${labelName}" align="center"${column.sortStr} v-if="columns.showColumn('${columnName}')">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :options="$if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :value="scope.row.${columnName}" $if(column.HtmlType == "checkbox")split=","$end />
|
<dict-tag :options="$if(column.DictType != "") options.${column.DictType} $else options.${column.CsharpFieldFl}Options$end" :value="scope.row.${columnName}" $if(column.HtmlType == "checkbox" || column.HtmlType == "selectMulti")split=","$end />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
$elseif(column.HtmlType == "datetime")
|
$elseif(column.HtmlType == "datetime")
|
||||||
@@ -213,13 +214,13 @@ $end
|
|||||||
</el-button-group>
|
</el-button-group>
|
||||||
$else
|
$else
|
||||||
$if(replaceDto.ShowBtnView)
|
$if(replaceDto.ShowBtnView)
|
||||||
<el-button type="primary" icon="view" title="详情" @click="handlePreview(scope.row)"></el-button>
|
<el-button type="primary" size="small" icon="view" title="详情" @click="handlePreview(scope.row)"></el-button>
|
||||||
$end
|
$end
|
||||||
$if(replaceDto.ShowBtnEdit)
|
$if(replaceDto.ShowBtnEdit)
|
||||||
<el-button v-hasPermi="['${replaceDto.PermissionPrefix}:edit']" type="success" icon="edit" title="编辑" @click="handleUpdate(scope.row)"></el-button>
|
<el-button type="success" size="small" icon="edit" title="编辑" v-hasPermi="['${replaceDto.PermissionPrefix}:edit']" @click="handleUpdate(scope.row)"></el-button>
|
||||||
$end
|
$end
|
||||||
$if(replaceDto.ShowBtnDelete)
|
$if(replaceDto.ShowBtnDelete)
|
||||||
<el-button v-hasPermi="['${replaceDto.PermissionPrefix}:delete']" type="danger" icon="delete" title="删除" @click="handleDelete(scope.row)"></el-button>
|
<el-button type="danger" size="small" icon="delete" title="删除" v-hasPermi="['${replaceDto.PermissionPrefix}:delete']" @click="handleDelete(scope.row)"></el-button>
|
||||||
$end
|
$end
|
||||||
$end
|
$end
|
||||||
</template>
|
</template>
|
||||||
@@ -326,10 +327,16 @@ $elseif(column.HtmlType == "editor")
|
|||||||
<editor v-model="form.${columnName}" :min-height="200" />
|
<editor v-model="form.${columnName}" :min-height="200" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
$elseif(column.HtmlType == "slider")
|
||||||
|
<el-col :lg="24">
|
||||||
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
|
<el-slider v-model="form.${columnName}" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
$elseif(column.HtmlType == "select" || column.HtmlType == "selectMulti")
|
$elseif(column.HtmlType == "select" || column.HtmlType == "selectMulti")
|
||||||
<el-col :lg="${options.ColNum}">
|
<el-col :lg="${options.ColNum}">
|
||||||
<el-form-item label="${labelName}" prop="${columnName}">
|
<el-form-item label="${labelName}" prop="${columnName}">
|
||||||
<el-select v-model="form.${columnName}" placeholder="请选择${labelName}"${column.DisabledStr}>
|
<el-select v-model="form.${columnName}$if(column.HtmlType == "selectMulti")Checked$end" $if(column.HtmlType == "selectMulti")multiple$end placeholder="请选择${labelName}"${column.DisabledStr}>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in $if(column.DictType != "")options.${column.DictType}${else}options.${column.CsharpFieldFl}Options$end"
|
v-for="item in $if(column.DictType != "")options.${column.DictType}${else}options.${column.CsharpFieldFl}Options$end"
|
||||||
:key="item.dictValue"
|
:key="item.dictValue"
|
||||||
@@ -442,7 +449,9 @@ $end
|
|||||||
</el-form>
|
</el-form>
|
||||||
<template #footer v-if="opertype != 3">
|
<template #footer v-if="opertype != 3">
|
||||||
<el-button text @click="cancel">{{ ${t}t('btn.cancel') }}</el-button>
|
<el-button text @click="cancel">{{ ${t}t('btn.cancel') }}</el-button>
|
||||||
|
$if(replaceDto.ShowBtnEdit || replaceDto.ShowBtnAdd)
|
||||||
<el-button type="primary" @click="submitForm">{{ ${t}t('btn.submit') }}</el-button>
|
<el-button type="primary" @click="submitForm">{{ ${t}t('btn.submit') }}</el-button>
|
||||||
|
$end
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -654,7 +663,7 @@ function cancel(){
|
|||||||
function reset() {
|
function reset() {
|
||||||
form.value = {
|
form.value = {
|
||||||
$foreach(item in genTable.Columns)
|
$foreach(item in genTable.Columns)
|
||||||
$if((item.HtmlType == "checkbox"))
|
$if(item.HtmlType == "checkbox" || item.HtmlType == "selectMulti")
|
||||||
${item.CsharpFieldFl}Checked: [],
|
${item.CsharpFieldFl}Checked: [],
|
||||||
$else
|
$else
|
||||||
$item.CsharpFieldFl: null,
|
$item.CsharpFieldFl: null,
|
||||||
@@ -666,7 +675,7 @@ $if(sub)
|
|||||||
$end
|
$end
|
||||||
proxy.resetForm("formRef")
|
proxy.resetForm("formRef")
|
||||||
}
|
}
|
||||||
|
$if(replaceDto.ShowBtnAdd)
|
||||||
// 添加按钮操作
|
// 添加按钮操作
|
||||||
function handleAdd() {
|
function handleAdd() {
|
||||||
reset();
|
reset();
|
||||||
@@ -674,7 +683,8 @@ function handleAdd() {
|
|||||||
title.value = '添加${genTable.functionName}'
|
title.value = '添加${genTable.functionName}'
|
||||||
opertype.value = 1
|
opertype.value = 1
|
||||||
}
|
}
|
||||||
|
$end
|
||||||
|
$if(replaceDto.ShowBtnEdit)
|
||||||
// 修改按钮操作
|
// 修改按钮操作
|
||||||
function handleUpdate(row) {
|
function handleUpdate(row) {
|
||||||
reset()
|
reset()
|
||||||
@@ -689,7 +699,7 @@ function handleUpdate(row) {
|
|||||||
form.value = {
|
form.value = {
|
||||||
...data,
|
...data,
|
||||||
$foreach(item in genTable.Columns)
|
$foreach(item in genTable.Columns)
|
||||||
$if(item.HtmlType == "checkbox")
|
$if(item.HtmlType == "checkbox" || item.HtmlType == "selectMulti")
|
||||||
${item.CsharpFieldFl}Checked: data.${item.CsharpFieldFl} ? data.${item.CsharpFieldFl}.split(',') : [],
|
${item.CsharpFieldFl}Checked: data.${item.CsharpFieldFl} ? data.${item.CsharpFieldFl}.split(',') : [],
|
||||||
$end
|
$end
|
||||||
$end
|
$end
|
||||||
@@ -700,13 +710,14 @@ $end
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
$end
|
||||||
|
|
||||||
// 添加&修改 表单提交
|
// 添加&修改 表单提交
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
proxy.${refs}refs["formRef"].validate((valid) => {
|
proxy.${refs}refs["formRef"].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
$foreach(item in genTable.Columns)
|
$foreach(item in genTable.Columns)
|
||||||
$if(item.HtmlType == "checkbox")
|
$if(item.HtmlType == "checkbox" || item.HtmlType == "selectMulti")
|
||||||
form.value.${item.CsharpFieldFl} = form.value.${item.CsharpFieldFl}Checked.toString();
|
form.value.${item.CsharpFieldFl} = form.value.${item.CsharpFieldFl}Checked.toString();
|
||||||
$end
|
$end
|
||||||
$end
|
$end
|
||||||
@@ -715,24 +726,27 @@ $if(sub)
|
|||||||
form.value.${tool.FirstLowerCase(genTable.SubTable.ClassName)}Nav = ${tool.FirstLowerCase(genTable.SubTable.ClassName)}List.value
|
form.value.${tool.FirstLowerCase(genTable.SubTable.ClassName)}Nav = ${tool.FirstLowerCase(genTable.SubTable.ClassName)}List.value
|
||||||
$end
|
$end
|
||||||
if (form.value.${replaceDto.FistLowerPk} != undefined && opertype.value === 2) {
|
if (form.value.${replaceDto.FistLowerPk} != undefined && opertype.value === 2) {
|
||||||
|
$if(replaceDto.ShowBtnEdit)
|
||||||
update${genTable.BusinessName}(form.value).then((res) => {
|
update${genTable.BusinessName}(form.value).then((res) => {
|
||||||
proxy.${modal}modal.msgSuccess("修改成功")
|
proxy.${modal}modal.msgSuccess("修改成功")
|
||||||
open.value = false
|
open.value = false
|
||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
$end
|
||||||
} else {
|
} else {
|
||||||
|
$if(replaceDto.ShowBtnAdd)
|
||||||
add${genTable.BusinessName}(form.value).then((res) => {
|
add${genTable.BusinessName}(form.value).then((res) => {
|
||||||
proxy.${modal}modal.msgSuccess("新增成功")
|
proxy.${modal}modal.msgSuccess("新增成功")
|
||||||
open.value = false
|
open.value = false
|
||||||
getList()
|
getList()
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
$end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$if(replaceDto.ShowBtnMultiDel || replaceDto.ShowBtnDelete)
|
||||||
// 删除按钮操作
|
// 删除按钮操作
|
||||||
function handleDelete(row) {
|
function handleDelete(row) {
|
||||||
const Ids = row.${replaceDto.FistLowerPk} || ids.value
|
const Ids = row.${replaceDto.FistLowerPk} || ids.value
|
||||||
@@ -746,8 +760,8 @@ function handleDelete(row) {
|
|||||||
getList()
|
getList()
|
||||||
proxy.${modal}modal.msgSuccess("删除成功")
|
proxy.${modal}modal.msgSuccess("删除成功")
|
||||||
})
|
})
|
||||||
.catch(() => {})
|
|
||||||
}
|
}
|
||||||
|
$end
|
||||||
|
|
||||||
$if(replaceDto.ShowBtnTruncate)
|
$if(replaceDto.ShowBtnTruncate)
|
||||||
// 清空
|
// 清空
|
||||||
@@ -778,7 +792,7 @@ function handlePreview(row) {
|
|||||||
open.value = true
|
open.value = true
|
||||||
title.value = '查看'
|
title.value = '查看'
|
||||||
opertype.value = 3
|
opertype.value = 3
|
||||||
form.value = row
|
form.value = { ...row }
|
||||||
}
|
}
|
||||||
$end
|
$end
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -1,5 +1,7 @@
|
|||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
using Infrastructure.Extensions;
|
using Infrastructure.Extensions;
|
||||||
|
using Infrastructure.Helper;
|
||||||
|
using Infrastructure.Model;
|
||||||
using JinianNet.JNTemplate;
|
using JinianNet.JNTemplate;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System;
|
using System;
|
||||||
@@ -7,7 +9,6 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using ZR.CodeGenerator.Model;
|
using ZR.CodeGenerator.Model;
|
||||||
using ZR.Common;
|
|
||||||
using ZR.Model.System.Generate;
|
using ZR.Model.System.Generate;
|
||||||
|
|
||||||
namespace ZR.CodeGenerator
|
namespace ZR.CodeGenerator
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
|
using Infrastructure.Model;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
|
using Infrastructure.Model;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
@@ -5,13 +5,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
|
<ProjectReference Include="..\Infrastructure\ZR.Infrastructure.csproj" />
|
||||||
<ProjectReference Include="..\ZR.Common\ZR.Common.csproj" />
|
<ProjectReference Include="..\ZR.Common\ZR.Common.csproj" />
|
||||||
<ProjectReference Include="..\ZR.Model\ZR.Model.csproj" />
|
<ProjectReference Include="..\ZR.ServiceCore\ZR.ServiceCore.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" />
|
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" />
|
||||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.94" />
|
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.105" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
+11
-1
@@ -1,4 +1,5 @@
|
|||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
|
using Infrastructure.Model;
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using MimeKit.Text;
|
using MimeKit.Text;
|
||||||
@@ -19,7 +20,7 @@ namespace ZR.Common
|
|||||||
public MailHelper()
|
public MailHelper()
|
||||||
{
|
{
|
||||||
AppSettings.Bind("MailOptions", mailOptions);
|
AppSettings.Bind("MailOptions", mailOptions);
|
||||||
FromEmail= mailOptions.FromEmail;
|
FromEmail = mailOptions.FromEmail;
|
||||||
}
|
}
|
||||||
public MailHelper(MailOptions _mailOptions)
|
public MailHelper(MailOptions _mailOptions)
|
||||||
{
|
{
|
||||||
@@ -132,11 +133,20 @@ namespace ZR.Common
|
|||||||
//特别说明,对于服务器端的中文相应,Exception中有编码问题,显示乱码了
|
//特别说明,对于服务器端的中文相应,Exception中有编码问题,显示乱码了
|
||||||
client.Authenticate(System.Text.Encoding.UTF8, mailOptions.FromEmail, mailOptions.Password);
|
client.Authenticate(System.Text.Encoding.UTF8, mailOptions.FromEmail, mailOptions.Password);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
var result = client.Send(message);
|
var result = client.Send(message);
|
||||||
//断开
|
//断开
|
||||||
client.Disconnect(true);
|
client.Disconnect(true);
|
||||||
Console.WriteLine($"【{DateTime.Now}】发送邮件结果{result}");
|
Console.WriteLine($"【{DateTime.Now}】发送邮件结果{result}");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
client.Disconnect(true);
|
||||||
|
Log.WriteLine(ConsoleColor.Red, "发送邮件失败" + ex.Message);
|
||||||
|
return "fail";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,14 +6,10 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
|
||||||
<PackageReference Include="CSRedisCore" Version="3.8.670" />
|
|
||||||
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" />
|
|
||||||
<PackageReference Include="MailKit" Version="4.1.0" />
|
<PackageReference Include="MailKit" Version="4.1.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="7.0.0" />
|
|
||||||
<PackageReference Include="MiniExcel" Version="1.31.0" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
|
<ProjectReference Include="..\Infrastructure\ZR.Infrastructure.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
此文件夹用于存放业务代码数据库实体类
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace ZR.Model
|
|
||||||
{
|
|
||||||
public enum ProteryConstant
|
|
||||||
{
|
|
||||||
NOTNULL = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
|
|
||||||
namespace ZR.Model.System.Dto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 登录用户信息存储
|
|
||||||
/// </summary>
|
|
||||||
public class LoginUser
|
|
||||||
{
|
|
||||||
public long UserId { get; set; }
|
|
||||||
public long DeptId { get; set; }
|
|
||||||
public string UserName { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 角色集合
|
|
||||||
/// </summary>
|
|
||||||
public List<string> RoleIds { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 角色集合(数据权限过滤使用)
|
|
||||||
/// </summary>
|
|
||||||
public List<SysRole> Roles { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 权限集合
|
|
||||||
/// </summary>
|
|
||||||
public List<string> Permissions { get; set; } = new List<string>();
|
|
||||||
public LoginUser()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public LoginUser(SysUser user, List<SysRole> roles, List<string> permissions)
|
|
||||||
{
|
|
||||||
UserId = user.UserId;
|
|
||||||
UserName = user.UserName;
|
|
||||||
DeptId = user.DeptId;
|
|
||||||
Roles = roles;
|
|
||||||
RoleIds = roles.Select(f => f.RoleKey).ToList();
|
|
||||||
Permissions = permissions;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="MiniExcel" Version="1.31.0" />
|
<PackageReference Include="MiniExcel" Version="1.31.2" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.94" />
|
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.105" />
|
||||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace ZR.Repository
|
|||||||
|
|
||||||
public int Insert(List<T> t)
|
public int Insert(List<T> t)
|
||||||
{
|
{
|
||||||
return Context.Insertable(t).ExecuteCommand();
|
return InsertRange(t) ? 1 : 0;
|
||||||
}
|
}
|
||||||
public int Insert(T parm, Expression<Func<T, object>> iClumns = null, bool ignoreNull = true)
|
public int Insert(T parm, Expression<Func<T, object>> iClumns = null, bool ignoreNull = true)
|
||||||
{
|
{
|
||||||
@@ -61,10 +61,10 @@ namespace ZR.Repository
|
|||||||
#endregion add
|
#endregion add
|
||||||
|
|
||||||
#region update
|
#region update
|
||||||
public IUpdateable<T> Updateable(T entity)
|
//public IUpdateable<T> Updateable(T entity)
|
||||||
{
|
//{
|
||||||
return Context.Updateable(entity);
|
// return Context.Updateable(entity);
|
||||||
}
|
//}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 实体根据主键更新
|
/// 实体根据主键更新
|
||||||
@@ -72,9 +72,10 @@ namespace ZR.Repository
|
|||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
/// <param name="ignoreNullColumns"></param>
|
/// <param name="ignoreNullColumns"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public int Update(T entity, bool ignoreNullColumns = false)
|
public int Update(T entity, bool ignoreNullColumns = false, object data = null)
|
||||||
{
|
{
|
||||||
return Context.Updateable(entity).IgnoreColumns(ignoreNullColumns).ExecuteCommand();
|
return Context.Updateable(entity).IgnoreColumns(ignoreNullColumns)
|
||||||
|
.EnableDiffLogEventIF(data.IsNotEmpty(), data).ExecuteCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -103,37 +104,6 @@ namespace ZR.Repository
|
|||||||
return Context.Updateable(entity).UpdateColumns(expression).Where(where).ExecuteCommand();
|
return Context.Updateable(entity).UpdateColumns(expression).Where(where).ExecuteCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Update(SqlSugarClient client, T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where)
|
|
||||||
{
|
|
||||||
return client.Updateable(entity).UpdateColumns(expression).Where(where).ExecuteCommand();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="entity"></param>
|
|
||||||
/// <param name="list"></param>
|
|
||||||
/// <param name="isNull">默认为true</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public int Update(T entity, List<string> list = null, bool isNull = true)
|
|
||||||
{
|
|
||||||
list ??= new List<string>()
|
|
||||||
{
|
|
||||||
"Create_By",
|
|
||||||
"Create_time"
|
|
||||||
};
|
|
||||||
return Context.Updateable(entity).IgnoreColumns(isNull).IgnoreColumns(list.ToArray()).ExecuteCommand();
|
|
||||||
}
|
|
||||||
|
|
||||||
//public bool Update(List<T> entity)
|
|
||||||
//{
|
|
||||||
// var result = base.Context.Ado.UseTran(() =>
|
|
||||||
// {
|
|
||||||
// base.Context.Updateable(entity).ExecuteCommand();
|
|
||||||
// });
|
|
||||||
// return result.IsSuccess;
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新指定列 eg:Update(w => w.NoticeId == model.NoticeId, it => new SysNotice(){ Update_time = DateTime.Now, Title = "通知标题" });
|
/// 更新指定列 eg:Update(w => w.NoticeId == model.NoticeId, it => new SysNotice(){ Update_time = DateTime.Now, Title = "通知标题" });
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -160,14 +130,6 @@ namespace ZR.Repository
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public IStorageable<T> Storageable(T t)
|
|
||||||
{
|
|
||||||
return Context.Storageable<T>(t);
|
|
||||||
}
|
|
||||||
public IStorageable<T> Storageable(List<T> t)
|
|
||||||
{
|
|
||||||
return Context.Storageable(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ namespace ZR.Repository
|
|||||||
#endregion add
|
#endregion add
|
||||||
|
|
||||||
#region update
|
#region update
|
||||||
IUpdateable<T> Updateable(T entity);
|
int Update(T entity, bool ignoreNullColumns = false, object data = null);
|
||||||
int Update(T entity, bool ignoreNullColumns = false);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 只更新表达式的值
|
/// 只更新表达式的值
|
||||||
@@ -32,13 +31,9 @@ namespace ZR.Repository
|
|||||||
|
|
||||||
int Update(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where);
|
int Update(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where);
|
||||||
|
|
||||||
int Update(SqlSugarClient client, T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where);
|
|
||||||
|
|
||||||
int Update(Expression<Func<T, bool>> where, Expression<Func<T, T>> columns);
|
int Update(Expression<Func<T, bool>> where, Expression<Func<T, T>> columns);
|
||||||
|
|
||||||
#endregion update
|
#endregion update
|
||||||
IStorageable<T> Storageable(T t);
|
|
||||||
IStorageable<T> Storageable(List<T> t);
|
|
||||||
DbResult<bool> UseTran(Action action);
|
DbResult<bool> UseTran(Action action);
|
||||||
|
|
||||||
DbResult<bool> UseTran(SqlSugarClient client, Action action);
|
DbResult<bool> UseTran(SqlSugarClient client, Action action);
|
||||||
|
|||||||
@@ -5,16 +5,14 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
|
<ProjectReference Include="..\Infrastructure\ZR.Infrastructure.csproj" />
|
||||||
<ProjectReference Include="..\ZR.Model\ZR.Model.csproj" />
|
<ProjectReference Include="..\ZR.Model\ZR.Model.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Mapster" Version="7.3.0" />
|
<PackageReference Include="Mapster" Version="7.3.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.1" />
|
|
||||||
<PackageReference Include="MySqlConnector" Version="2.2.6" />
|
<PackageReference Include="MySqlConnector" Version="2.2.6" />
|
||||||
<PackageReference Include="NETCore.Encrypt" Version="2.1.1" />
|
|
||||||
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
||||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.94" />
|
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.105" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
global using System.Collections.Generic;
|
global using System.Collections.Generic;
|
||||||
|
global using System;
|
||||||
|
global using SqlSugar;
|
||||||
|
global using Newtonsoft.Json;
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
using Infrastructure;
|
||||||
|
using Infrastructure.Attribute;
|
||||||
|
using SqlSugar.IOC;
|
||||||
|
using ZR.Model.System;
|
||||||
|
using ZR.Repository;
|
||||||
|
using ZR.Service.IService;
|
||||||
|
using ZR.Service.System.IService;
|
||||||
|
|
||||||
|
namespace ZR.Service
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 注意:下面的AppService不要漏了
|
||||||
|
/// </summary>
|
||||||
|
[AppService(ServiceType = typeof(IHelloService), ServiceLifetime = LifeTime.Transient)]
|
||||||
|
public class HelloService : BaseService<ArticleCategory>, IHelloService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 引用User服务
|
||||||
|
/// </summary>
|
||||||
|
private readonly ISysUserService userService;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userService"></param>
|
||||||
|
public HelloService(ISysUserService userService)
|
||||||
|
{
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 数据库使用案例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string SayHello(string name)
|
||||||
|
{
|
||||||
|
//构造函数式使用
|
||||||
|
var user = JsonConvert.SerializeObject(userService.GetFirst(f => f.UserId == 1));
|
||||||
|
Console.WriteLine(user);
|
||||||
|
|
||||||
|
var postService = App.GetRequiredService<ISysPostService>();
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(postService.GetId(1)));
|
||||||
|
|
||||||
|
BaseRepository<SysDept> deptRepo = new();
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(deptRepo.GetId(1)));
|
||||||
|
|
||||||
|
var result = DbScoped.SugarScope.Queryable<SysDictType>().Where(f => f.DictId == 1).First();
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(result));
|
||||||
|
|
||||||
|
//切换库
|
||||||
|
//DbScoped.SugarScope.GetConnectionScope(2);
|
||||||
|
|
||||||
|
GetFirst(x => x.CategoryId == 1);
|
||||||
|
Context.Queryable<SysUser>().First(f => f.UserId == 1);
|
||||||
|
|
||||||
|
return "Hello:" + name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using ZR.Model.System;
|
||||||
|
|
||||||
|
namespace ZR.Service.IService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Hello接口
|
||||||
|
/// </summary>
|
||||||
|
public interface IHelloService : IBaseService<ArticleCategory>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
string SayHello(string name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using ZR.Common;
|
|
||||||
using ZR.Common.Cache;
|
|
||||||
|
|
||||||
namespace ZR.Service.System
|
|
||||||
{
|
|
||||||
public class CacheService
|
|
||||||
{
|
|
||||||
#region 用户权限 缓存
|
|
||||||
public static List<string> GetUserPerms(string key)
|
|
||||||
{
|
|
||||||
return (List<string>)CacheHelper.GetCache(key);
|
|
||||||
//return RedisServer.Cache.Get<List<string>>(key).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SetUserPerms(string key, object data)
|
|
||||||
{
|
|
||||||
CacheHelper.SetCache(key, data);
|
|
||||||
//RedisServer.Cache.Set(key, data);
|
|
||||||
}
|
|
||||||
public static void RemoveUserPerms(string key)
|
|
||||||
{
|
|
||||||
CacheHelper.Remove(key);
|
|
||||||
//RedisServer.Cache.Del(key);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -2,11 +2,14 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net7.0</TargetFramework>
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<NoWarn>1591</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\ZR.Common\ZR.Common.csproj" />
|
<ProjectReference Include="..\ZR.ServiceCore\ZR.ServiceCore.csproj" />
|
||||||
<ProjectReference Include="..\ZR.Repository\ZR.Repository.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -8,11 +8,5 @@ namespace ZR.Service
|
|||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public class BaseService<T> : BaseRepository<T> where T : class, new()
|
public class BaseService<T> : BaseRepository<T> where T : class, new()
|
||||||
{
|
{
|
||||||
//public IBaseRepository<T> baseRepository;
|
|
||||||
|
|
||||||
//public BaseService(IBaseRepository<T> repository)
|
|
||||||
//{
|
|
||||||
// this.baseRepository = repository ?? throw new ArgumentNullException(nameof(repository));
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+28
-15
@@ -2,9 +2,11 @@
|
|||||||
using Infrastructure.Model;
|
using Infrastructure.Model;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System;
|
||||||
|
using ZR.Service.System;
|
||||||
|
using ZR.Service.System.IService;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Filters
|
namespace ZR.ServiceCore.Middleware
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// API授权判断
|
/// API授权判断
|
||||||
@@ -17,8 +19,11 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
/// 权限字符串,例如 system:user:view
|
/// 权限字符串,例如 system:user:view
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Permission { get; set; } = string.Empty;
|
public string Permission { get; set; } = string.Empty;
|
||||||
|
/// <summary>
|
||||||
|
/// 角色字符串,例如 common,admin
|
||||||
|
/// </summary>
|
||||||
|
public string RolePermi { get; set; } = string.Empty;
|
||||||
private bool HasPermi { get; set; }
|
private bool HasPermi { get; set; }
|
||||||
private bool HasRole { get; set; }
|
|
||||||
public ActionPermissionFilter() { }
|
public ActionPermissionFilter() { }
|
||||||
public ActionPermissionFilter(string permission)
|
public ActionPermissionFilter(string permission)
|
||||||
{
|
{
|
||||||
@@ -34,12 +39,22 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||||
{
|
{
|
||||||
LoginUser info = Framework.JwtUtil.GetLoginUser(context.HttpContext);
|
TokenModel info = JwtUtil.GetLoginUser(context.HttpContext);
|
||||||
|
|
||||||
if (info != null && info?.UserId > 0)
|
if (info != null && info?.UserId > 0)
|
||||||
{
|
{
|
||||||
List<string> perms = info.Permissions;
|
long userId = info.UserId;
|
||||||
|
List<string> perms = CacheService.GetUserPerms(GlobalConstant.UserPermKEY + userId);
|
||||||
List<string> rolePerms = info.RoleIds;
|
List<string> rolePerms = info.RoleIds;
|
||||||
|
|
||||||
|
if (perms == null)
|
||||||
|
{
|
||||||
|
var sysPermissionService = App.GetService<ISysPermissionService>();
|
||||||
|
perms = sysPermissionService.GetMenuPermission(new SysUser() { UserId = userId });
|
||||||
|
|
||||||
|
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + userId, perms);
|
||||||
|
}
|
||||||
|
|
||||||
if (perms.Exists(f => f.Equals(GlobalConstant.AdminPerm)))
|
if (perms.Exists(f => f.Equals(GlobalConstant.AdminPerm)))
|
||||||
{
|
{
|
||||||
HasPermi = true;
|
HasPermi = true;
|
||||||
@@ -52,24 +67,22 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
{
|
{
|
||||||
HasPermi = perms.Exists(f => f.ToLower() == Permission.ToLower());
|
HasPermi = perms.Exists(f => f.ToLower() == Permission.ToLower());
|
||||||
}
|
}
|
||||||
|
if (!HasPermi && !string.IsNullOrEmpty(RolePermi))
|
||||||
|
{
|
||||||
|
HasPermi = info.RoleIds.Contains(RolePermi);
|
||||||
|
}
|
||||||
bool isDemoMode = AppSettings.GetAppConfig("DemoMode", false);
|
bool isDemoMode = AppSettings.GetAppConfig("DemoMode", false);
|
||||||
var url = context.HttpContext.Request.Path;
|
var url = context.HttpContext.Request.Path;
|
||||||
//演示公开环境屏蔽权限
|
//演示公开环境屏蔽权限
|
||||||
string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear", "send", "export", "upload", "common", "gencode", "reset" };
|
string[] denyPerms = new string[] { "update", "add", "remove", "add", "edit", "delete", "import", "run", "start", "stop", "clear", "send", "export", "upload", "common", "gencode", "reset", "forceLogout", "batchLogout" };
|
||||||
if (isDemoMode && denyPerms.Any(f => Permission.ToLower().Contains(f)))
|
if (isDemoMode && denyPerms.Any(f => Permission.Contains(f, StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
context.Result = new JsonResult(new { code = ResultCode.FORBIDDEN, msg = "演示模式 , 不允许操作" });
|
context.Result = new JsonResult(new { code = (int)ResultCode.FORBIDDEN, msg = "演示模式 , 不允许操作" });
|
||||||
}
|
}
|
||||||
if (!HasPermi && !Permission.Equals("common"))
|
if (!HasPermi && !Permission.Equals("common"))
|
||||||
{
|
{
|
||||||
logger.Info($"用户{info.UserName}没有权限访问{url},当前权限[{Permission}]");
|
logger.Info($"用户{info.UserName}没有权限访问{url},当前权限[{Permission}]");
|
||||||
JsonResult result = new(new ApiResult()
|
JsonResult result = new(new ApiResult((int)ResultCode.FORBIDDEN, $"你当前没有权限[{Permission}]访问,请联系管理员", url))
|
||||||
{
|
|
||||||
Code = (int)ResultCode.FORBIDDEN,
|
|
||||||
Msg = $"你当前没有权限[{Permission}]访问,请联系管理员",
|
|
||||||
Data = url
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
ContentType = "application/json",
|
ContentType = "application/json",
|
||||||
};
|
};
|
||||||
+15
-19
@@ -2,20 +2,20 @@
|
|||||||
using Infrastructure.Attribute;
|
using Infrastructure.Attribute;
|
||||||
using Infrastructure.Model;
|
using Infrastructure.Model;
|
||||||
using IPTools.Core;
|
using IPTools.Core;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using NLog;
|
using NLog;
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Filters
|
namespace ZR.ServiceCore.Middleware
|
||||||
{
|
{
|
||||||
public class GlobalActionMonitor : ActionFilterAttribute
|
public class GlobalActionMonitor : ActionFilterAttribute
|
||||||
{
|
{
|
||||||
static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||||
private ISysOperLogService OperLogService;
|
private readonly ISysOperLogService OperLogService;
|
||||||
public GlobalActionMonitor(ISysOperLogService operLogService)
|
public GlobalActionMonitor(ISysOperLogService operLogService)
|
||||||
{
|
{
|
||||||
OperLogService = operLogService;
|
OperLogService = operLogService;
|
||||||
@@ -29,29 +29,25 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||||
{
|
{
|
||||||
ApiResult response = new();
|
string msg = string.Empty;
|
||||||
response.Code = (int)ResultCode.PARAM_ERROR;
|
|
||||||
|
|
||||||
var values = context.ModelState.Values;
|
var values = context.ModelState.Values;
|
||||||
foreach (var item in values)
|
foreach (var item in values)
|
||||||
{
|
{
|
||||||
foreach (var err in item.Errors)
|
foreach (var err in item.Errors)
|
||||||
{
|
{
|
||||||
if (err.ErrorMessage.Contains("JSON"))
|
if (!string.IsNullOrEmpty(msg))
|
||||||
{
|
{
|
||||||
return next();
|
msg += " | ";
|
||||||
}
|
|
||||||
if (!string.IsNullOrEmpty(response.Msg))
|
|
||||||
{
|
|
||||||
response.Msg += " | ";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.Msg += err.ErrorMessage;
|
msg += err.ErrorMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(response.Msg))
|
if (!string.IsNullOrEmpty(msg))
|
||||||
{
|
{
|
||||||
logger.Info($"请求参数错误,{response.Msg}");
|
logger.Info($"请求参数错误,{msg}");
|
||||||
|
ApiResult response = new((int)ResultCode.PARAM_ERROR, msg);
|
||||||
|
|
||||||
context.Result = new JsonResult(response);
|
context.Result = new JsonResult(response);
|
||||||
}
|
}
|
||||||
return base.OnActionExecutionAsync(context, next);
|
return base.OnActionExecutionAsync(context, next);
|
||||||
@@ -101,12 +97,12 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
OperUrl = HttpContextExtension.GetRequestUrl(context.HttpContext),
|
OperUrl = HttpContextExtension.GetRequestUrl(context.HttpContext),
|
||||||
RequestMethod = method,
|
RequestMethod = method,
|
||||||
JsonResult = jsonResult,
|
JsonResult = jsonResult,
|
||||||
OperLocation = ip_info.Province + " " + ip_info.City,
|
OperLocation = HttpContextExtension.GetIpInfo(ip),
|
||||||
Method = controller + "." + action + "()",
|
Method = controller + "." + action + "()",
|
||||||
//Elapsed = _stopwatch.ElapsedMilliseconds,
|
//Elapsed = _stopwatch.ElapsedMilliseconds,
|
||||||
OperTime = DateTime.Now
|
OperTime = DateTime.Now,
|
||||||
|
OperParam = HttpContextExtension.GetRequestValue(context.HttpContext, method)
|
||||||
};
|
};
|
||||||
HttpContextExtension.GetRequestValue(context.HttpContext, sysOperLog);
|
|
||||||
|
|
||||||
if (logAttribute != null)
|
if (logAttribute != null)
|
||||||
{
|
{
|
||||||
@@ -131,7 +127,7 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LogAttribute? GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor)
|
private LogAttribute GetLogAttribute(ControllerActionDescriptor controllerActionDescriptor)
|
||||||
{
|
{
|
||||||
var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
|
var attribute = controllerActionDescriptor.MethodInfo.GetCustomAttributes(inherit: true)
|
||||||
.FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute)));
|
.FirstOrDefault(a => a.GetType().Equals(typeof(LogAttribute)));
|
||||||
+28
-14
@@ -4,23 +4,18 @@ using Microsoft.AspNetCore.Authorization;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
using NLog;
|
using ZR.Common;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Admin.WebApi.Framework;
|
|
||||||
using ZR.Model.System.Dto;
|
|
||||||
|
|
||||||
|
//本命名空间暂时先不改,改动比较大2023年9月2日
|
||||||
namespace ZR.Admin.WebApi.Filters
|
namespace ZR.Admin.WebApi.Filters
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 授权校验访问
|
/// 授权校验访问
|
||||||
/// 如果跳过授权登录在Action 或controller加上 AllowAnonymousAttribute
|
/// 如果跳过授权登录在Action 或controller加上 AllowAnonymousAttribute
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[AttributeUsage(AttributeTargets.All)]
|
||||||
public class VerifyAttribute : Attribute, IAuthorizationFilter
|
public class VerifyAttribute : Attribute, IAuthorizationFilter
|
||||||
{
|
{
|
||||||
static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 只判断token是否正确,不判断权限
|
/// 只判断token是否正确,不判断权限
|
||||||
/// 如果需要判断权限的在Action上加上ApiActionPermission属性标识权限类别,ActionPermissionFilter作权限处理
|
/// 如果需要判断权限的在Action上加上ApiActionPermission属性标识权限类别,ActionPermissionFilter作权限处理
|
||||||
@@ -40,16 +35,35 @@ namespace ZR.Admin.WebApi.Filters
|
|||||||
string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
|
string ip = HttpContextExtension.GetClientUserIp(context.HttpContext);
|
||||||
string url = context.HttpContext.Request.Path;
|
string url = context.HttpContext.Request.Path;
|
||||||
var isAuthed = context.HttpContext.User.Identity.IsAuthenticated;
|
var isAuthed = context.HttpContext.User.Identity.IsAuthenticated;
|
||||||
|
string osType = context.HttpContext.Request.Headers["os"];
|
||||||
//使用jwt token校验2020-11-21
|
//使用jwt token校验2020-11-21
|
||||||
LoginUser info = JwtUtil.GetLoginUser(context.HttpContext);
|
TokenModel loginUser = JwtUtil.GetLoginUser(context.HttpContext);
|
||||||
|
if (loginUser != null)
|
||||||
|
{
|
||||||
|
var nowTime = DateTime.UtcNow;
|
||||||
|
TimeSpan ts = loginUser.ExpireTime - nowTime;
|
||||||
|
|
||||||
if (info == null || !isAuthed)
|
//Console.WriteLine($"jwt到期剩余:{ts.TotalMinutes}分,{ts.TotalSeconds}秒");
|
||||||
|
|
||||||
|
var CK = "token_" + loginUser.UserId;
|
||||||
|
if (!CacheHelper.Exists(CK) && ts.TotalMinutes < 5)
|
||||||
|
{
|
||||||
|
var newToken = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser));
|
||||||
|
|
||||||
|
CacheHelper.SetCache(CK, CK, 1);
|
||||||
|
//移动端不加下面这个获取不到自定义Header
|
||||||
|
if (osType != null)
|
||||||
|
{
|
||||||
|
context.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "X-Refresh-Token");
|
||||||
|
}
|
||||||
|
context.HttpContext.Response.Headers.Add("X-Refresh-Token", newToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (loginUser == null || !isAuthed)
|
||||||
{
|
{
|
||||||
string msg = $"请求访问[{url}]失败,无法访问系统资源";
|
string msg = $"请求访问[{url}]失败,无法访问系统资源";
|
||||||
logger.Info($"{msg}");
|
//logger.Info(msg);
|
||||||
|
context.Result = new JsonResult(ApiResult.Error(ResultCode.DENY, msg));
|
||||||
context.Result = new JsonResult(new ApiResult((int)ResultCode.DENY, msg));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
global using Newtonsoft.Json;
|
||||||
|
global using SqlSugar;
|
||||||
|
global using System;
|
||||||
|
global using System.Collections.Generic;
|
||||||
|
global using Infrastructure.Extensions;
|
||||||
+14
-12
@@ -2,17 +2,16 @@
|
|||||||
using Infrastructure.Attribute;
|
using Infrastructure.Attribute;
|
||||||
using Infrastructure.Model;
|
using Infrastructure.Model;
|
||||||
using IPTools.Core;
|
using IPTools.Core;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Http.Features;
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using NLog;
|
using NLog;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text.Encodings.Web;
|
using System.Text.Encodings.Web;
|
||||||
using System.Text.Json;
|
|
||||||
using ZR.Admin.WebApi.Extensions;
|
|
||||||
using ZR.Common;
|
using ZR.Common;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
using textJson = System.Text.Json;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Middleware
|
namespace ZR.ServiceCore.Middleware
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 全局异常处理中间件
|
/// 全局异常处理中间件
|
||||||
@@ -45,16 +44,18 @@ namespace ZR.Admin.WebApi.Middleware
|
|||||||
|
|
||||||
private async Task HandleExceptionAsync(HttpContext context, Exception ex)
|
private async Task HandleExceptionAsync(HttpContext context, Exception ex)
|
||||||
{
|
{
|
||||||
NLog.LogLevel logLevel = NLog.LogLevel.Info;
|
LogLevel logLevel = LogLevel.Info;
|
||||||
int code = (int)ResultCode.GLOBAL_ERROR;
|
int code = (int)ResultCode.GLOBAL_ERROR;
|
||||||
string msg;
|
string msg;
|
||||||
string error = string.Empty;
|
string error = string.Empty;
|
||||||
|
bool notice = true;
|
||||||
//自定义异常
|
//自定义异常
|
||||||
if (ex is CustomException customException)
|
if (ex is CustomException customException)
|
||||||
{
|
{
|
||||||
code = customException.Code;
|
code = customException.Code;
|
||||||
msg = customException.Message;
|
msg = customException.Message;
|
||||||
error = customException.LogMsg;
|
error = customException.LogMsg;
|
||||||
|
notice = customException.Notice;
|
||||||
}
|
}
|
||||||
else if (ex is ArgumentException)//参数异常
|
else if (ex is ArgumentException)//参数异常
|
||||||
{
|
{
|
||||||
@@ -65,18 +66,18 @@ namespace ZR.Admin.WebApi.Middleware
|
|||||||
{
|
{
|
||||||
msg = "服务器好像出了点问题,请联系系统管理员...";
|
msg = "服务器好像出了点问题,请联系系统管理员...";
|
||||||
error = $"{ex.Message}";
|
error = $"{ex.Message}";
|
||||||
logLevel = NLog.LogLevel.Error;
|
logLevel = LogLevel.Error;
|
||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
}
|
}
|
||||||
var options = new JsonSerializerOptions
|
var options = new textJson.JsonSerializerOptions
|
||||||
{
|
{
|
||||||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
|
||||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
PropertyNamingPolicy = textJson.JsonNamingPolicy.CamelCase,
|
||||||
WriteIndented = true
|
WriteIndented = true
|
||||||
};
|
};
|
||||||
|
|
||||||
ApiResult apiResult = new(code, msg);
|
ApiResult apiResult = new(code, msg);
|
||||||
string responseResult = JsonSerializer.Serialize(apiResult, options).ToLower();
|
string responseResult = textJson.JsonSerializer.Serialize(apiResult, options);
|
||||||
string ip = HttpContextExtension.GetClientUserIp(context);
|
string ip = HttpContextExtension.GetClientUserIp(context);
|
||||||
var ip_info = IpTool.Search(ip);
|
var ip_info = IpTool.Search(ip);
|
||||||
|
|
||||||
@@ -90,9 +91,9 @@ namespace ZR.Admin.WebApi.Middleware
|
|||||||
ErrorMsg = string.IsNullOrEmpty(error) ? msg : error,
|
ErrorMsg = string.IsNullOrEmpty(error) ? msg : error,
|
||||||
OperName = HttpContextExtension.GetName(context),
|
OperName = HttpContextExtension.GetName(context),
|
||||||
OperLocation = ip_info.Province + " " + ip_info.City,
|
OperLocation = ip_info.Province + " " + ip_info.City,
|
||||||
OperTime = DateTime.Now
|
OperTime = DateTime.Now,
|
||||||
|
OperParam = HttpContextExtension.GetRequestValue(context, context.Request.Method)
|
||||||
};
|
};
|
||||||
HttpContextExtension.GetRequestValue(context, sysOperLog);
|
|
||||||
var endpoint = GetEndpoint(context);
|
var endpoint = GetEndpoint(context);
|
||||||
if (endpoint != null)
|
if (endpoint != null)
|
||||||
{
|
{
|
||||||
@@ -125,8 +126,9 @@ namespace ZR.Admin.WebApi.Middleware
|
|||||||
$"\n> 操作地址:{sysOperLog.OperUrl}" +
|
$"\n> 操作地址:{sysOperLog.OperUrl}" +
|
||||||
$"\n> 错误信息:{msg}\n\n> {error}";
|
$"\n> 错误信息:{msg}\n\n> {error}";
|
||||||
|
|
||||||
WxNoticeHelper.SendMsg("系统出错", errorMsg, "", WxNoticeHelper.MsgType.markdown);
|
|
||||||
SysOperLogService.InsertOperlog(sysOperLog);
|
SysOperLogService.InsertOperlog(sysOperLog);
|
||||||
|
if (!notice) return;
|
||||||
|
WxNoticeHelper.SendMsg("系统异常", errorMsg, msgType: WxNoticeHelper.MsgType.markdown);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Endpoint GetEndpoint(HttpContext context)
|
public static Endpoint GetEndpoint(HttpContext context)
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace ZR.Model.System.Dto
|
||||||
|
{
|
||||||
|
public class LockUserDto
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string ClientId { get; set; }
|
||||||
|
public string ConnnectionId { get; set; }
|
||||||
|
public string Reason { get; set; }
|
||||||
|
public int Time { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user