Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7afaad77ca | ||
|
|
0009d99ff7 | ||
|
|
bc6ae48588 | ||
|
|
2a3d8bab6c | ||
|
|
24c2cd1cc7 | ||
|
|
41dbfd511e | ||
|
|
f9276f10b9 | ||
|
|
589c707647 | ||
|
|
09b6a8fb81 | ||
|
|
563c757741 | ||
|
|
542fdd8ff6 | ||
|
|
22b2c35392 | ||
|
|
78213d91cf | ||
|
|
0ee1ab8af5 | ||
|
|
7c78ce8ed5 | ||
|
|
d67d401f14 | ||
|
|
5103a83e1f | ||
|
|
01daf4f591 | ||
|
|
bfe8b68a94 | ||
|
|
925440716b | ||
|
|
10f0d12842 | ||
|
|
df10dd2cbd | ||
|
|
dac25c8785 | ||
|
|
0d60d4f650 | ||
|
|
f05dec13da | ||
|
|
5375b9e308 | ||
|
|
dc6f41d96e | ||
|
|
1316e14664 | ||
|
|
eed3ffa650 | ||
|
|
c7e6e322bc | ||
|
|
0bcdb1cdfc | ||
|
|
d8504a194e | ||
|
|
8745df6ece | ||
|
|
9393b3f6a5 | ||
|
|
e6e4009ea0 | ||
|
|
f2a58057d1 | ||
|
|
9a93282ce7 | ||
|
|
ae4bb658fd | ||
|
|
b01335a125 | ||
|
|
9f6ee330ae | ||
|
|
18702eaa38 | ||
|
|
9f8e7dbecc | ||
|
|
3aec182f0d | ||
|
|
b250cc21df | ||
|
|
9b37c26e0d | ||
|
|
8867c7ba45 | ||
|
|
3337b9abb3 | ||
|
|
eef8962974 | ||
|
|
98663c9d7e | ||
|
|
913a155b50 | ||
|
|
fe929db358 | ||
|
|
367a78a04c | ||
|
|
11d02d451c | ||
|
|
11de19a735 | ||
|
|
40c4070c49 | ||
|
|
780b32abc4 | ||
|
|
e42530379d | ||
|
|
302a2e06c7 | ||
|
|
0d68423ce0 | ||
|
|
4c91f65759 | ||
|
|
aa27674b9c | ||
|
|
ea4acde028 | ||
|
|
332acde5a0 | ||
|
|
d49d59f1e9 | ||
|
|
de143b04bc | ||
|
|
e8812787ad | ||
|
|
a8fbf4e156 | ||
|
|
65e1fcfd49 | ||
|
|
baf3630847 | ||
|
|
df36de52fa | ||
|
|
f859748825 | ||
|
|
3f8486f6ce | ||
|
|
e234189af3 | ||
|
|
2e0db37d42 | ||
|
|
f78ccc2b4c | ||
|
|
2bc2911718 | ||
|
|
bc4e92bcad | ||
|
|
2071219c34 | ||
|
|
eca2d2fd73 | ||
|
|
d0158f0eef | ||
|
|
945f64e46a | ||
|
|
31980c80bb | ||
|
|
56c4b8897b | ||
|
|
1db16082be | ||
|
|
0dc97f3b9a | ||
|
|
cf0559c5d9 |
@@ -1,25 +0,0 @@
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/.idea
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
@@ -0,0 +1,88 @@
|
||||
name: 问题反馈
|
||||
description: 当你在代码中发现了一个 Bug,导致应用崩溃或抛出异常,或者有一个组件存在问题,或者某些地方看起来不对劲。
|
||||
title: "[Bug]: "
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢对项目的支持与关注。在提出问题之前,请确保你已查看相关开发或使用文档:
|
||||
- http://www.izhaorui.cn/doc
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 这个问题是否已经存在?
|
||||
options:
|
||||
- label: 我已经搜索过现有的问题 (https://gitee.com/../../issues)
|
||||
required: true
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 代码是否是最新获取的?
|
||||
options:
|
||||
- label: 我已经确认代码是最新主分支的代码
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 如何复现
|
||||
description: 请详细告诉我们如何复现你遇到的问题,如涉及代码,可提供一个最小代码示例,并使用反引号```附上它
|
||||
placeholder: |
|
||||
1. ...
|
||||
2. ...
|
||||
3. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 预期结果
|
||||
description: 请告诉我们你预期会发生什么。
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 实际结果
|
||||
description: 请告诉我们实际发生了什么。
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 截图或视频
|
||||
description: 如果可以的话,上传任何关于 bug 的截图。
|
||||
value: |
|
||||
[在这里上传图片]
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: vue版本
|
||||
description: 你当前正在使用我们软件的哪个前端版本
|
||||
options:
|
||||
- vue3 (默认)
|
||||
- vue2
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: 运行环境
|
||||
options:
|
||||
- 开发环境 (development)
|
||||
- 生产环境(production)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: version
|
||||
attributes:
|
||||
label: 应用程序托管
|
||||
options:
|
||||
- 前端iis + 后端iis
|
||||
- 前端nginx + 后端 iis
|
||||
- 前端nginx + 后端自启动
|
||||
- docker
|
||||
- 其他
|
||||
validations:
|
||||
required: true
|
||||
contact_links:
|
||||
- name: 使用文档
|
||||
url: http://www.izhaorui.cn/doc/
|
||||
about: 官方文档
|
||||
- name: ♥️ VIP 服务 ♥️
|
||||
url: https://www.izhaorui.cn/doc/support.html
|
||||
about: 支持作者
|
||||
@@ -0,0 +1,13 @@
|
||||
name: 功能建议
|
||||
description: 对本项目提出一个功能建议
|
||||
title: "[功能建议]: "
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
感谢对项目的支持与关注。如果你在使用中有什么好的建议欢迎提出来
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 请输入内容
|
||||
description: 如果可以的话,上传任何关于 功能 的截图。
|
||||
+5
-20
@@ -259,31 +259,16 @@ paket-files/
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
/ZR.Admin.WebApi/appsettings.Development.json
|
||||
/CodeGenerate
|
||||
/ZR.Admin.WebApi/appsettings.Production.json
|
||||
/ZR.Admin.WebApi/wwwroot/uploads
|
||||
/ZR.Admin.WebApi/wwwroot/Generatecode
|
||||
/ZR.Admin.WebApi/wwwroot/export
|
||||
/ZR.Vue/src/views/business/Gendemo.vue
|
||||
/ZR.Admin.WebApi/Properties/launchSettings.json
|
||||
/ZR.Admin.WebApi/ZRAdmin.xml
|
||||
/ZR.Admin.WebApi/DataProtection
|
||||
/Quartz.NET.WindowsService
|
||||
/ZRAdmin-vue/node_modules/
|
||||
/ZRAdmin-vue/.DS_Store
|
||||
/ZRAdmin-vue/dist/
|
||||
/ZRAdmin-vue/npm-debug.log*
|
||||
/ZRAdmin-vue/yarn-debug.log*
|
||||
/ZRAdmin-vue/yarn-error.log*
|
||||
/ZRAdmin-vue/**/*.log
|
||||
/ZRAdmin-vue/tests/**/coverage/
|
||||
/ZRAdmin-vue/tests/e2e/reports
|
||||
/ZRAdmin-vue/selenium-debug.log
|
||||
/ZRAdmin-vue/.idea
|
||||
/ZRAdmin-vue/*.suo
|
||||
/ZRAdmin-vue/*.ntvs*
|
||||
/ZRAdmin-vue/*.njsproj
|
||||
/ZRAdmin-vue/*.sln
|
||||
/ZRAdmin-vue/*.local
|
||||
/ZRAdmin-vue/package-lock.json
|
||||
/ZRAdmin-vue/deploy.js
|
||||
/ZRAdmin-vue
|
||||
/ZR.Admin.WebApi/ZRModel.xml
|
||||
ZRAdmin-vue/dist.zip
|
||||
**/.vshistory/
|
||||
@@ -1,7 +1,7 @@
|
||||
using CSRedis;
|
||||
using Infrastructure;
|
||||
|
||||
namespace ZR.Infrastructure.Cache
|
||||
namespace ZR.Common.Cache
|
||||
{
|
||||
public class RedisServer
|
||||
{
|
||||
@@ -12,7 +12,6 @@ namespace ZR.Infrastructure.Cache
|
||||
{
|
||||
Cache = new CSRedisClient(AppSettings.GetConfig("RedisServer:Cache"));
|
||||
Session = new CSRedisClient(AppSettings.GetConfig("RedisServer:Session"));
|
||||
RedisHelper.Initialization(Session);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace ZR.Infrastructure.Constant;
|
||||
|
||||
public class SysNoticeLogStatus
|
||||
{
|
||||
public const string Unread = "0";
|
||||
|
||||
public const string Read = "1";
|
||||
}
|
||||
@@ -8,6 +8,7 @@ using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
|
||||
namespace Infrastructure.Controllers
|
||||
@@ -15,6 +16,7 @@ namespace Infrastructure.Controllers
|
||||
/// <summary>
|
||||
/// web层通用数据处理
|
||||
/// </summary>
|
||||
//[ApiController]
|
||||
public class BaseController : ControllerBase
|
||||
{
|
||||
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
|
||||
@@ -74,6 +76,23 @@ namespace Infrastructure.Controllers
|
||||
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="fileName">文件名,一定要带扩展名</param>
|
||||
/// <returns></returns>
|
||||
protected IActionResult DownFile(string path, string fileName)
|
||||
{
|
||||
if (!System.IO.File.Exists(path))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
var stream = System.IO.File.OpenRead(path); //创建文件流
|
||||
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
|
||||
return File(stream, "application/octet-stream", HttpUtility.UrlEncode(fileName));
|
||||
}
|
||||
|
||||
#region 方法
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace Infrastructure.Extensions
|
||||
{
|
||||
try
|
||||
{
|
||||
return bool.Parse(str.ToString() ?? string.Empty);
|
||||
return bool.Parse(str.ToString());
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -284,9 +284,6 @@ namespace Infrastructure.Extensions
|
||||
return DateTime.ParseExact(str, "yyyyMMddHH", System.Globalization.CultureInfo.CurrentCulture);
|
||||
case 12:
|
||||
return DateTime.ParseExact(str, "yyyyMMddHHmm", System.Globalization.CultureInfo.CurrentCulture);
|
||||
case 13:
|
||||
return DateTime.ParseExact(str, "yyyy.MM.dd ddd",
|
||||
System.Globalization.CultureInfo.CurrentCulture);
|
||||
case 14:
|
||||
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
|
||||
default:
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
/// </summary>
|
||||
public class GlobalConstant
|
||||
{
|
||||
/// <summary>
|
||||
/// 代码生成常量
|
||||
/// </summary>
|
||||
public static readonly string CodeGenDbConfig;
|
||||
|
||||
/// <summary>
|
||||
/// 管理员权限
|
||||
/// </summary>
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace Infrastructure
|
||||
/// 写文件
|
||||
/// </summary>
|
||||
/// <param name="path">完整路径带扩展名的</param>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="content">写入文件内容</param>
|
||||
public static void WriteAndSave(string path, string content)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
@@ -158,17 +158,7 @@ namespace Infrastructure
|
||||
Console.WriteLine("开始写入文件,Path=" + path);
|
||||
try
|
||||
{
|
||||
//实例化一个文件流--->与写入文件相关联
|
||||
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
|
||||
//实例化一个StreamWriter-->与fs相关联
|
||||
using var sw = new StreamWriter(fs);
|
||||
//开始写入
|
||||
sw.Write(content);
|
||||
//清空缓冲区
|
||||
sw.Flush();
|
||||
//关闭流
|
||||
sw.Close();
|
||||
fs.Close();
|
||||
File.WriteAllText(path, content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace ZR.Infrastructure.Helper
|
||||
{
|
||||
public class RandomHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成n为验证码
|
||||
/// </summary>
|
||||
/// <param name="Length"></param>
|
||||
/// <returns></returns>
|
||||
public static string GenerateNum(int Length)
|
||||
{
|
||||
char[] constant = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||
StringBuilder newRandom = new(constant.Length);
|
||||
Random rd = new();
|
||||
for (int i = 0; i < Length; i++)
|
||||
{
|
||||
newRandom.Append(constant[rd.Next(constant.Length - 1)]);
|
||||
}
|
||||
return newRandom.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,10 +155,11 @@ namespace Infrastructure
|
||||
{
|
||||
var claims = new List<Claim>()
|
||||
{
|
||||
new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()),
|
||||
new Claim(ClaimTypes.Name, user.UserName),
|
||||
new Claim(ClaimTypes.UserData, JsonConvert.SerializeObject(user)),
|
||||
new Claim("NickName", user.NickName)
|
||||
new(ClaimTypes.PrimarySid, user.UserId.ToString()),
|
||||
new(ClaimTypes.NameIdentifier, user.UserId.ToString()),
|
||||
new(ClaimTypes.Name, user.UserName),
|
||||
new(ClaimTypes.GroupSid, user.DeptId.ToString()),
|
||||
new(ClaimTypes.UserData, JsonConvert.SerializeObject(user))
|
||||
};
|
||||
|
||||
return claims;
|
||||
|
||||
@@ -1,26 +1,24 @@
|
||||
using Infrastructure.Constant;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Infrastructure.Model
|
||||
{
|
||||
public class ApiResult : Dictionary<string, object>
|
||||
{
|
||||
/** 状态码 */
|
||||
/// <summary>
|
||||
/// 状态码
|
||||
/// </summary>
|
||||
public static readonly string CODE_TAG = "code";
|
||||
|
||||
/** 返回内容 */
|
||||
/// <summary>
|
||||
/// 返回内容
|
||||
/// </summary>
|
||||
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>
|
||||
/// 如果data值为null,则忽略序列化将不会返回data字段
|
||||
/// 数据对象
|
||||
/// </summary>
|
||||
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
//public object Data { get; set; }
|
||||
public static readonly string DATA_TAG = "data";
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个新创建的APIResult对象,使其表示一个空消息
|
||||
@@ -55,6 +53,7 @@ namespace Infrastructure.Model
|
||||
Add(DATA_TAG, data);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回成功消息
|
||||
/// </summary>
|
||||
@@ -125,9 +124,4 @@ namespace Infrastructure.Model
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public class ApiResult<T> : ApiResult
|
||||
{
|
||||
public T Result { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Infrastructure.Model
|
||||
public Upload Upload { get; set; }
|
||||
public ALIYUN_OSS ALIYUN_OSS { get; set; }
|
||||
public JwtSettings JwtSettings { get; set; }
|
||||
public Gen Gen { get; set; }
|
||||
public CodeGen CodeGen { get; set; }
|
||||
public List<DbConfigs> DbConfigs { get; set; }
|
||||
public DbConfigs CodeGenDbConfig { get; set; }
|
||||
}
|
||||
@@ -94,13 +94,15 @@ namespace Infrastructure.Model
|
||||
public string TokenType { get; set; } = "Bearer";
|
||||
}
|
||||
|
||||
public class Gen
|
||||
public class CodeGen
|
||||
{
|
||||
public bool ShowApp { get; set; }
|
||||
public bool AutoPre { get; set; }
|
||||
public string VuePath { get; set; }
|
||||
public string Author { get; set; }
|
||||
public DbConfigs GenDbConfig { get; set; }
|
||||
public string TablePrefix { get; set; }
|
||||
public string ModuleName { get; set; }
|
||||
public int FrontTpl { get; set; }
|
||||
public CsharpTypeArr CsharpTypeArr { get; set; }
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@ namespace Infrastructure.Model
|
||||
/// <summary>
|
||||
/// 主题
|
||||
/// </summary>
|
||||
// [Required(ErrorMessage = "主题不能为空")]
|
||||
[Required(ErrorMessage = "主题不能为空")]
|
||||
public string Subject { get; set; }
|
||||
// [Required(ErrorMessage = "发送人不能为空")]
|
||||
[Required(ErrorMessage = "发送人不能为空")]
|
||||
public string ToUser { get; set; }
|
||||
public string Content { get; set; } = "";
|
||||
public string HtmlContent { get; set; }
|
||||
@@ -23,5 +23,9 @@ namespace Infrastructure.Model
|
||||
/// </summary>
|
||||
public bool SendMe { get; set; }
|
||||
public DateTime AddTime { get; set; }
|
||||
/// <summary>
|
||||
/// 是否发送
|
||||
/// </summary>
|
||||
public bool IsSend { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace Infrastructure.Model
|
||||
public long UserId { get; set; }
|
||||
public long DeptId { get; set; }
|
||||
public string UserName { get; set; }
|
||||
public string NickName { get; set; }
|
||||
/// <summary>
|
||||
/// 角色集合
|
||||
/// </summary>
|
||||
@@ -34,7 +33,6 @@ namespace Infrastructure.Model
|
||||
{
|
||||
UserId = info.UserId;
|
||||
UserName = info.UserName;
|
||||
NickName = info.NickName;
|
||||
DeptId = info.DeptId;
|
||||
Roles = roles;
|
||||
RoleIds = roles.Select(f => f.RoleKey).ToList();
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace ZR.Infrastructure.Resolver;
|
||||
|
||||
public static class AntPathMatcher
|
||||
{
|
||||
public static bool Match(string pattern, string value)
|
||||
{
|
||||
if (pattern == null || value == null)
|
||||
return false;
|
||||
|
||||
if (pattern == "**")
|
||||
return true;
|
||||
|
||||
var patternSegments = pattern.Split('/');
|
||||
var valueSegments = value.Split('/');
|
||||
|
||||
int patternIndex = 0;
|
||||
int valueIndex = 0;
|
||||
int patternWildcardIndex = -1;
|
||||
int valueWildcardIndex = -1;
|
||||
|
||||
while (valueIndex < valueSegments.Length)
|
||||
{
|
||||
if (patternIndex < patternSegments.Length && IsMatch(patternSegments[patternIndex], valueSegments[valueIndex]))
|
||||
{
|
||||
patternIndex++;
|
||||
valueIndex++;
|
||||
}
|
||||
else if (patternWildcardIndex != -1)
|
||||
{
|
||||
patternIndex = patternWildcardIndex + 1;
|
||||
valueIndex = ++valueWildcardIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
while (patternIndex < patternSegments.Length && patternSegments[patternIndex] == "**")
|
||||
{
|
||||
patternIndex++;
|
||||
}
|
||||
|
||||
return patternIndex >= patternSegments.Length && valueIndex >= valueSegments.Length;
|
||||
}
|
||||
|
||||
private static bool IsMatch(string patternSegment, string valueSegment)
|
||||
{
|
||||
if (patternSegment == "*")
|
||||
return true;
|
||||
|
||||
if (patternSegment.StartsWith("{") && patternSegment.EndsWith("}"))
|
||||
return true; // 支持占位符的匹配逻辑
|
||||
|
||||
return string.Equals(patternSegment, valueSegment, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace ZR.Infrastructure.Resolver;
|
||||
|
||||
public class JsonPropertyContractResolver : CamelCasePropertyNamesContractResolver
|
||||
{
|
||||
private HashSet<string> _propertySet;
|
||||
|
||||
public JsonPropertyContractResolver(IEnumerable<string> propertyNames)
|
||||
{
|
||||
if (propertyNames != null)
|
||||
{
|
||||
_propertySet = new HashSet<string>(propertyNames, StringComparer.Ordinal);
|
||||
}
|
||||
}
|
||||
|
||||
// protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
// {
|
||||
// var list = base.CreateProperties(type, memberSerialization).ToList();
|
||||
// var resList = list
|
||||
// .Where(a => !this._lstInclude.Contains(a.PropertyName))
|
||||
// .ToList();
|
||||
// return resList;
|
||||
// // .FindAll(p => _lstInclude.Contains(p.PropertyName));
|
||||
// }
|
||||
|
||||
protected override List<MemberInfo> GetSerializableMembers(Type objectType)
|
||||
{
|
||||
List<MemberInfo> serializableMembers = null;
|
||||
var allMembers = base.GetSerializableMembers(objectType);
|
||||
|
||||
if (_propertySet != null && _propertySet.Count > 0)
|
||||
{
|
||||
serializableMembers = allMembers.Where(m => !_propertySet.Contains(m.Name)).ToList();
|
||||
}
|
||||
return serializableMembers != null && serializableMembers.Count > 0 ? serializableMembers : allMembers;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace ZR.Infrastructure.Resolver;
|
||||
|
||||
public class PropertyFilterContractResolver : CamelCasePropertyNamesContractResolver
|
||||
{
|
||||
private readonly HashSet<string> _includedPaths;
|
||||
private readonly HashSet<string> _excludedPaths;
|
||||
|
||||
public PropertyFilterContractResolver(IEnumerable<string> includedPaths, IEnumerable<string> excludedPaths)
|
||||
{
|
||||
_includedPaths = includedPaths.ToHashSet();
|
||||
_excludedPaths = excludedPaths.ToHashSet();
|
||||
}
|
||||
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
var properties = base.CreateProperties(type, memberSerialization);
|
||||
|
||||
properties = properties.Where(p => IsIncluded(p) && !IsExcluded(p)).ToList();
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private bool IsIncluded(JsonProperty property)
|
||||
{
|
||||
if (_includedPaths == null || _includedPaths.Count == 0)
|
||||
return true;
|
||||
|
||||
return _includedPaths.Any(path => AntPathMatcher.Match(path, property.PropertyName));
|
||||
}
|
||||
|
||||
private bool IsExcluded(JsonProperty property)
|
||||
{
|
||||
if (_excludedPaths == null || _excludedPaths.Count == 0)
|
||||
return false;
|
||||
|
||||
return _excludedPaths.Any(path => AntPathMatcher.Match(path, property.PropertyName));
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,10 @@ namespace Infrastructure
|
||||
|
||||
types.GetProperty("CreateTime", flag)?.SetValue(source, DateTime.Now, null);
|
||||
types.GetProperty("AddTime", flag)?.SetValue(source, DateTime.Now, null);
|
||||
types.GetProperty("CreateBy", flag)?.SetValue(source, context.GetUId(), null);
|
||||
types.GetProperty("CreateName", flag)?.SetValue(source, context.GetNickName(), null);
|
||||
types.GetProperty("Create_by", flag)?.SetValue(source, context.GetUId(), null);
|
||||
types.GetProperty("Create_name", flag)?.SetValue(source, context.GetNickName(), null);
|
||||
types.GetProperty("CreateBy", flag)?.SetValue(source, context.GetName(), null);
|
||||
types.GetProperty("Create_by", flag)?.SetValue(source, context.GetName(), null);
|
||||
types.GetProperty("UserId", flag)?.SetValue(source, context.GetUId(), null);
|
||||
types.GetProperty("DeptId", flag)?.SetValue(source, context.GetDeptId(), null);
|
||||
|
||||
return source;
|
||||
}
|
||||
@@ -33,10 +32,9 @@ namespace Infrastructure
|
||||
|
||||
types.GetProperty("UpdateTime", flag)?.SetValue(source, DateTime.Now, null);
|
||||
types.GetProperty("Update_time", flag)?.SetValue(source, DateTime.Now, null);
|
||||
types.GetProperty("UpdateBy", flag)?.SetValue(source, context.GetUId(), null);
|
||||
types.GetProperty("Update_by", flag)?.SetValue(source, context.GetUId(), null);
|
||||
types.GetProperty("UpdateName", flag)?.SetValue(source, context.GetNickName(), null);
|
||||
types.GetProperty("Update_name", flag)?.SetValue(source, context.GetNickName(), null);
|
||||
types.GetProperty("UpdateBy", flag)?.SetValue(source, context.GetName(), null);
|
||||
types.GetProperty("Update_by", flag)?.SetValue(source, context.GetName(), null);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,17 @@ namespace Infrastructure.Extensions
|
||||
return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取部门id
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetDeptId(this HttpContext context)
|
||||
{
|
||||
var deptId = context.User.FindFirstValue(ClaimTypes.GroupSid);
|
||||
return !string.IsNullOrEmpty(deptId) ? long.Parse(deptId) : 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取登录用户名
|
||||
/// </summary>
|
||||
@@ -91,14 +102,6 @@ namespace Infrastructure.Extensions
|
||||
|
||||
return uid;
|
||||
}
|
||||
|
||||
public static string? GetNickName(this HttpContext context)
|
||||
{
|
||||
var nickName = context.User.FindFirstValue("NickName");
|
||||
if (string.IsNullOrEmpty(nickName))
|
||||
nickName = null;
|
||||
return nickName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否是管理员
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace ZR.Infrastructure.WebExtensions
|
||||
//从appsettings.json中加载Ip规则
|
||||
services.Configure<IpRateLimitPolicies>(configuration.GetSection("IpRateLimitPolicies"));
|
||||
//注入计数器和规则存储
|
||||
services.AddSingleton<IIpPolicyStore, DistributedCacheIpPolicyStore>();
|
||||
services.AddSingleton<IRateLimitCounterStore, DistributedCacheRateLimitCounterStore>();
|
||||
services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();
|
||||
services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();
|
||||
//配置(解析器、计数器密钥生成器)
|
||||
services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();
|
||||
services.AddSingleton<IProcessingStrategy, AsyncKeyLockProcessingStrategy>();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ZR.Infrastructure.WebExtensions
|
||||
{
|
||||
public static class RequestLimitExtension
|
||||
{
|
||||
/// <summary>
|
||||
/// 请求body大小设置
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <param name="configuration"></param>
|
||||
public static void AddRequestLimit(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
var sizeM = configuration.GetSection("upload:requestLimitSize").Get<int>();
|
||||
services.Configure<FormOptions>(x =>
|
||||
{
|
||||
x.MultipartBodyLengthLimit = sizeM * 1024 * 1024;
|
||||
x.MemoryBufferThreshold = sizeM * 1024 * 1024;
|
||||
x.ValueLengthLimit = int.MaxValue;
|
||||
});
|
||||
services.Configure<KestrelServerOptions>(options =>
|
||||
{
|
||||
options.Limits.MaxRequestBodySize = sizeM * 1024 * 1024;
|
||||
});
|
||||
services.Configure<IISServerOptions>(options =>
|
||||
{
|
||||
options.MaxRequestBodySize = sizeM * 1024 * 1024; // 设置最大请求体大小为500MB
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>8632</NoWarn>
|
||||
@@ -12,19 +12,14 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AspectCore.Abstractions" Version="2.4.0" />
|
||||
<PackageReference Include="Caching.CSRedis" Version="3.8.670" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="7.0.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="RulesEngine" Version="5.0.2" />
|
||||
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.109" />
|
||||
<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="JinianNet.JNTemplate" Version="2.4.2" />
|
||||
<PackageReference Include="MiniExcel" Version="1.31.3" />
|
||||
<PackageReference Include="CSRedisCore" Version="3.8.802" />
|
||||
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
+33
-12
@@ -1,12 +1,17 @@
|
||||
<h2 align="center"> ZR.Admin.NET Back-end management system</h2>
|
||||
<h4 align="center">base .Net7 + vue2.x/vue3.x/uniapp Front-end and back-end separation of .NET rapid development framework</h4>
|
||||
|
||||
<p align="center">
|
||||
<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/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/更新日志-20230920-yellow"/></a>
|
||||
</p>
|
||||
<div style="text-align:center">
|
||||
|
||||
[](https://gitee.com/izory/ZrAdminNetCore)
|
||||
[](https://gitee.com/izory/ZrAdminNetCore/members)
|
||||
[](http://www.izhaorui.cn/doc/changelog.html)
|
||||
|
||||
[](https://github.com/izhaorui/ZrAdmin.NET/blob/main/LICENSE)
|
||||
[](https://github.com/izhaorui/ZrAdmin.NET/stargazers)
|
||||
[](https://github.com/izhaorui/ZrAdmin.NET/network)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
@@ -27,6 +32,10 @@
|
||||
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! ~
|
||||
```
|
||||
|
||||
## 📈 Quick start
|
||||
|
||||
- Quick start:[https://www.izhaorui.cn/doc/quickstart.html](https://www.izhaorui.cn/doc/quickstart.html)
|
||||
|
||||
## 🍿 Online experience
|
||||
|
||||
- Official documentation:http://www.izhaorui.cn/doc
|
||||
@@ -46,10 +55,10 @@ Since it is a personal project, the funds are limited, and the experience server
|
||||
|
||||
## 💒 Code repository
|
||||
|
||||
| repository | Github | Gitee |
|
||||
| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
|
||||
| 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) |
|
||||
| repository | Github | Gitee |
|
||||
| ---------- | ----------------------------------------------------------- | -------------------------------------------------------- |
|
||||
| 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) |
|
||||
|
||||
## 🍁 Front-end technology
|
||||
|
||||
@@ -149,9 +158,16 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/19.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/20.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/21.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/22.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/23.png"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Mobile Storyplate
|
||||
## 📱 Mobile Storyplate
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -170,8 +186,12 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a7.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a9.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a10.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a11.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a12.png"/></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
@@ -192,6 +212,7 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
|
||||
- 👉SqlSugar:[SqlSugar](https://gitee.com/dotnetchina/SqlSugar)
|
||||
- 👉vue-element-admin:[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
|
||||
- 👉Meiam.System:[Meiam.System](https://github.com/91270/Meiam.System)
|
||||
- 👉Furion:[Furion](https://gitee.com/dotnetchina/Furion)
|
||||
|
||||
## 🎀 donation
|
||||
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
<h2 align="center"> ZR.Admin.NET后台管理系统</h2>
|
||||
<h4 align="center">基于.Net7 + vue2.x/vue3.x/uniapp前后端分离的.net快速开发框架</h4>
|
||||
|
||||
<p align="center">
|
||||
<!-- <p align="center">
|
||||
<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/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/更新日志-20230920-yellow"/></a>
|
||||
</p>
|
||||
</p> -->
|
||||
|
||||
<div style="text-align:center">
|
||||
|
||||
[](https://gitee.com/izory/ZrAdminNetCore)
|
||||
[](https://gitee.com/izory/ZrAdminNetCore/members)
|
||||
[](http://www.izhaorui.cn/doc/changelog.html)
|
||||
|
||||
[](https://github.com/izhaorui/ZrAdmin.NET/blob/main/LICENSE)
|
||||
[](https://github.com/izhaorui/ZrAdmin.NET/stargazers)
|
||||
[](https://github.com/izhaorui/ZrAdmin.NET/network)
|
||||
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
@@ -31,13 +43,17 @@
|
||||
如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,谢谢!~
|
||||
```
|
||||
|
||||
## 📈 快速开始
|
||||
|
||||
- 快速开始:[https://www.izhaorui.cn/doc/quickstart.html](https://www.izhaorui.cn/doc/quickstart.html)
|
||||
|
||||
## 🍿 在线体验
|
||||
|
||||
- 官方文档:http://www.izhaorui.cn/doc
|
||||
- 加入群聊:[立即加入](http://www.izhaorui.cn/doc/contact.html)
|
||||
- Vue3.x 版本体验:[http://www.izhaorui.cn/vue3](http://www.izhaorui.cn/vue3)
|
||||
- Vue2.x 版本体验:[http://www.izhaorui.cn/admin](http://www.izhaorui.cn/admin)
|
||||
- Uniapp 版本体验:[http://www.izhaorui.cn/h5](http://www.izhaorui.cn/h5)
|
||||
- Vue3.x 版本体验:[http://demo.izhaorui.cn/vue3](http://demo.izhaorui.cn/vue3)
|
||||
- Vue2.x 版本体验:[http://demo.izhaorui.cn/admin](http://demo.izhaorui.cn/admin)
|
||||
- Uniapp 版本体验:[http://demo.izhaorui.cn/h5](http://demo.izhaorui.cn/h5)
|
||||
- 账号密码:admin/123456,普通用户 user/123456
|
||||
|
||||
| H5 | 微信小程序 |
|
||||
@@ -61,7 +77,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
|
||||
## 🍀 后端技术
|
||||
|
||||
- 核心框架:.Net5.0/.Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis
|
||||
- 核心框架:.Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis
|
||||
- 定时计划任务:Quartz.Net 组件,支持执行程序集或者 http 网络请求
|
||||
- 安全支持:过滤器(数据权限过滤)、Sql 注入、请求伪造
|
||||
- 日志管理:NLog、登录日志、操作日志、定时任务日志
|
||||
@@ -70,7 +86,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
- 代码生成:高效率开发,代码生成器可以一键生成所有前后端代码
|
||||
- 数据字典:支持数据字典,可以方便对一些状态进行管理
|
||||
- 分库分表:使用 orm sqlsugar 可以很轻松的实现分库分库性能优越
|
||||
- 多 租 户:支持多租户功能
|
||||
- 多 租 户:支持多租户功能(多数据库源)
|
||||
- 缓存数据:内置内存缓存和 Redis
|
||||
- signalR:使用 signalr 管理用户在线状态
|
||||
|
||||
@@ -87,7 +103,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
9. 系统接口:使用 swagger 生成相关 api 接口文档。
|
||||
10. 服务监控:监视当前系统 CPU、内存、磁盘、堆栈等相关信息。
|
||||
11. 在线构建器:拖动表单元素生成相应的 VUE 代码(仅支持 vue2)。
|
||||
12. 任务系统:基于 Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。
|
||||
12. 任务系统:基于 Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。
|
||||
13. 文章管理:可以写文章记录。
|
||||
14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、.sql、uniapp 等)支持下载,自定义配置前端展示控件、让开发更快捷高效(史上最强)。
|
||||
15. 参数管理:对系统动态配置常用参数。
|
||||
@@ -99,6 +115,8 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
21. 在线用户:可以查看正在登录使用的用户,可以对其踢出、通知操作
|
||||
22. db 审计日志:数据库审计功能
|
||||
23. 三方登录:提供三方登录实现逻辑
|
||||
24. 导入导出:支持中文表头导入、字典数据转换成文本导出
|
||||
25. 数据大屏:更直观的展示数据
|
||||
|
||||
## 🍻 项目结构
|
||||
|
||||
@@ -161,10 +179,15 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/21.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/22.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/23.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/24.png"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## 移动端演示图
|
||||
## 📱 移动端演示图
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
@@ -183,8 +206,12 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a7.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a9.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a10.png"/></td>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a11.png"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a12.png"/></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
@@ -196,9 +223,8 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
|
||||
3. 前台与后台系统分离,分别为不同的系统(域名可独立)
|
||||
4. 全局异常统一处理
|
||||
5. 自定义的代码生成功能
|
||||
6. 依赖少,上手容易
|
||||
6. 依赖少(只需数据库即可使用),上手容易
|
||||
7. 文档全面
|
||||
8. 支持中文表头导入数据
|
||||
|
||||
## 💐 特别鸣谢
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace ZR.Admin.Grpc.Extensions;
|
||||
|
||||
public static class GrpcServiceExtensions
|
||||
{
|
||||
public static void AddGrpcServiceConfiguration(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
// services.AddTransient<AuthUn>()
|
||||
|
||||
services.AddGrpcClient<Greeter.GreeterClient>(options =>
|
||||
{
|
||||
options.Address = new Uri(configuration.GetValue<string>("GrpcUrls:FindTeacher"));
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option csharp_namespace = "ZR.Admin.Grpc";
|
||||
|
||||
package filetransfer;
|
||||
|
||||
service FileTransfer {
|
||||
rpc InitUpload (InitUploadRequest) returns (InitUploadResponse);
|
||||
rpc UploadChunk (stream UploadChunkRequest) returns (UploadChunkResponse);
|
||||
rpc CompleteUpload (CompleteUploadRequest) returns (CompleteUploadResponse);
|
||||
rpc CheckUploadStatus (CheckUploadStatusRequest) returns (CheckUploadStatusResponse);
|
||||
}
|
||||
|
||||
message InitUploadRequest {
|
||||
string file_name = 1;
|
||||
int64 file_size = 2;
|
||||
string file_hash = 3;
|
||||
}
|
||||
|
||||
message InitUploadResponse {
|
||||
string session_id = 1;
|
||||
int64 uploaded_bytes = 2;
|
||||
}
|
||||
|
||||
message UploadChunkRequest {
|
||||
string session_id = 1;
|
||||
bytes chunk_data = 2;
|
||||
int64 offset = 3;
|
||||
}
|
||||
|
||||
message UploadChunkResponse {
|
||||
int64 uploaded_bytes = 1;
|
||||
}
|
||||
|
||||
message CompleteUploadRequest {
|
||||
string session_id = 1;
|
||||
string file_hash = 2;
|
||||
}
|
||||
|
||||
message CompleteUploadResponse {
|
||||
bool success = 1;
|
||||
string message = 2;
|
||||
}
|
||||
|
||||
message CheckUploadStatusRequest {
|
||||
string file_name = 1;
|
||||
string file_hash = 2;
|
||||
}
|
||||
|
||||
message CheckUploadStatusResponse {
|
||||
string session_id = 1;
|
||||
int64 uploaded_bytes = 2;
|
||||
bool exists = 3;
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option csharp_namespace = "GrpcService1";
|
||||
|
||||
package block;
|
||||
|
||||
service Block {
|
||||
rpc GetBlock (BlockRequest) returns (BlockReply);
|
||||
}
|
||||
|
||||
message BlockRequest {
|
||||
string in = 1;
|
||||
}
|
||||
|
||||
message BlockReply {
|
||||
string out = 1;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option csharp_namespace = "ZR.Admin.Grpc";
|
||||
|
||||
package greet;
|
||||
|
||||
// The greeting service definition.
|
||||
service Greeter {
|
||||
// Sends a greeting
|
||||
rpc SayHello (HelloRequest) returns (HelloReply);
|
||||
}
|
||||
|
||||
// The request message containing the user's name.
|
||||
message HelloRequest {
|
||||
string name = 1;
|
||||
}
|
||||
|
||||
// The response message containing the greetings.
|
||||
message HelloReply {
|
||||
string message = 1;
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option csharp_namespace = "ZR.Admin.Grpc";
|
||||
|
||||
package my.diary;
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
// The greeting service definition.
|
||||
service MyDiary {
|
||||
// Sends a greeting
|
||||
rpc Edit (EditRequest) returns (EditReply);
|
||||
rpc Query (QueryRequest) returns (QueryReply);
|
||||
}
|
||||
|
||||
// The request message containing the user's name.
|
||||
message EditRequest {
|
||||
string content = 1;
|
||||
int64 user_id = 2;
|
||||
google.protobuf.Timestamp create_time = 3; // 字段名仍然建议使用 snake_case
|
||||
}
|
||||
|
||||
// The response message containing the greetings.
|
||||
message EditReply {
|
||||
string result_message = 1;
|
||||
}
|
||||
|
||||
message QueryRequest {
|
||||
int64 user_id = 1;
|
||||
google.protobuf.Timestamp create_time = 2;
|
||||
}
|
||||
|
||||
message QueryReply {
|
||||
string content = 1;
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
using Grpc.Core;
|
||||
using ZR.Admin.Grpc;
|
||||
|
||||
namespace GrpcService.Services
|
||||
{
|
||||
public class FileTransferService : FileTransfer.FileTransferBase
|
||||
{
|
||||
private readonly string _storagePath = "Îļþ";
|
||||
private readonly IUploadSessionManager _sessionManager;
|
||||
|
||||
public FileTransferService(IUploadSessionManager sessionManager)
|
||||
{
|
||||
Directory.CreateDirectory(_storagePath);
|
||||
_sessionManager = sessionManager;
|
||||
}
|
||||
|
||||
public override Task<InitUploadResponse> InitUpload(InitUploadRequest request, ServerCallContext context)
|
||||
{
|
||||
var sessionId = _sessionManager.CreateSession(request.FileName, request.FileSize, request.FileHash);
|
||||
var uploadedBytes = _sessionManager.GetUploadedBytes(sessionId);
|
||||
|
||||
return Task.FromResult(new InitUploadResponse
|
||||
{
|
||||
SessionId = sessionId,
|
||||
UploadedBytes = uploadedBytes
|
||||
});
|
||||
}
|
||||
|
||||
public override async Task<UploadChunkResponse> UploadChunk(IAsyncStreamReader<UploadChunkRequest> requestStream, ServerCallContext context)
|
||||
{
|
||||
UploadChunkRequest currentRequest = null;
|
||||
var response = new UploadChunkResponse();
|
||||
|
||||
while (await requestStream.MoveNext())
|
||||
{
|
||||
currentRequest = requestStream.Current;
|
||||
var session = _sessionManager.GetSession(currentRequest.SessionId);
|
||||
|
||||
if (session == null)
|
||||
{
|
||||
throw new RpcException(new Status(StatusCode.NotFound, "Session not found"));
|
||||
}
|
||||
|
||||
using (var fileStream = new FileStream(session.TempFilePath, FileMode.OpenOrCreate, FileAccess.Write))
|
||||
{
|
||||
fileStream.Seek(currentRequest.Offset, SeekOrigin.Begin);
|
||||
await fileStream.WriteAsync(currentRequest.ChunkData.ToByteArray(), 0, currentRequest.ChunkData.Length);
|
||||
}
|
||||
|
||||
_sessionManager.UpdateSessionProgress(currentRequest.SessionId, currentRequest.Offset + currentRequest.ChunkData.Length);
|
||||
response.UploadedBytes = currentRequest.Offset + currentRequest.ChunkData.Length;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public override async Task<CompleteUploadResponse> CompleteUpload(CompleteUploadRequest request, ServerCallContext context)
|
||||
{
|
||||
var session = _sessionManager.GetSession(request.SessionId);
|
||||
if (session == null)
|
||||
{
|
||||
return await Task.FromResult(new CompleteUploadResponse
|
||||
{
|
||||
Success = false,
|
||||
Message = "Session not found"
|
||||
});
|
||||
}
|
||||
|
||||
// Verify file hash if needed
|
||||
if (!string.IsNullOrEmpty(request.FileHash))
|
||||
{
|
||||
var actualHash = await FileHelper.GetQuickFileIdentity(session.TempFilePath);
|
||||
if (actualHash != request.FileHash)
|
||||
{
|
||||
return await Task.FromResult(new CompleteUploadResponse
|
||||
{
|
||||
Success = false,
|
||||
Message = "File hash mismatch"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Move temp file to final location
|
||||
var finalPath = Path.Combine(_storagePath, session.FileName);
|
||||
//var finalPath = FileHelper.GetUniqueFilePath(_storagePath, session.FileName);
|
||||
File.Move(session.TempFilePath, finalPath, true);
|
||||
|
||||
_sessionManager.CompleteSession(request.SessionId);
|
||||
|
||||
return await Task.FromResult(new CompleteUploadResponse
|
||||
{
|
||||
Success = true,
|
||||
Message = "File uploaded successfully"
|
||||
});
|
||||
}
|
||||
|
||||
public override Task<CheckUploadStatusResponse> CheckUploadStatus(CheckUploadStatusRequest request, ServerCallContext context)
|
||||
{
|
||||
var session = _sessionManager.FindSession(request.FileName, request.FileHash);
|
||||
|
||||
return Task.FromResult(new CheckUploadStatusResponse
|
||||
{
|
||||
SessionId = session?.SessionId ?? "",
|
||||
UploadedBytes = session?.UploadedBytes ?? 0,
|
||||
Exists = session != null
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using Grpc.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ZR.Admin.Grpc.Services
|
||||
{
|
||||
public class GreeterService : Greeter.GreeterBase
|
||||
{
|
||||
private readonly ILogger<GreeterService> _logger;
|
||||
|
||||
public GreeterService(ILogger<GreeterService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
// 实现 SayHello 方法
|
||||
// 第一个参数是请求消息 (HelloRequest)
|
||||
// 第二个参数是服务器上下文 (ServerCallContext),提供关于当前调用的信息
|
||||
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
|
||||
{
|
||||
_logger.LogInformation($"接收到来自 {request.Name} 的请求");
|
||||
|
||||
// 构建并返回回复消息
|
||||
var reply = new HelloReply
|
||||
{
|
||||
Message = $"你好,{request.Name} 来自 gRPC 服务器!"
|
||||
};
|
||||
|
||||
// 返回一个 Task<HelloReply>
|
||||
return Task.FromResult(reply);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
using Grpc.Core;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using ZR.Service.IService;
|
||||
|
||||
namespace ZR.Admin.Grpc.Services
|
||||
{
|
||||
public class MyDiaryService(ILogger<MyDiaryService> logger, IMyDiaryService myDiaryService) : MyDiary.MyDiaryBase
|
||||
{
|
||||
public override async Task<EditReply> Edit(EditRequest request, ServerCallContext context)
|
||||
{
|
||||
logger.LogInformation($"接收到来自 {request.UserId} 的请求");
|
||||
|
||||
var myDiary = new Model.MyDiary()
|
||||
{
|
||||
Content = request.Content,
|
||||
CreateTime = request.CreateTime.ToDateTime().ToLocalTime(),
|
||||
UserId = request.UserId
|
||||
};
|
||||
|
||||
var myDiaryToday = await myDiaryService.Queryable()
|
||||
.Where(it => it.CreateTime.Date == myDiary.CreateTime.Date && it.UserId == myDiary.UserId)
|
||||
.FirstAsync();
|
||||
if (myDiaryToday != null)
|
||||
{
|
||||
myDiaryToday.Content = myDiary.Content;
|
||||
await myDiaryService.Updateable(myDiaryToday)
|
||||
.ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await myDiaryService.Insertable(myDiary).ExecuteReturnSnowflakeIdAsync();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 构建并返回回复消息
|
||||
var reply = new EditReply()
|
||||
{
|
||||
ResultMessage = $"日记已记录 来自 gRPC 服务器!"
|
||||
};
|
||||
|
||||
logger.LogInformation($"日记已记录");
|
||||
|
||||
// 返回一个 Task<HelloReply>
|
||||
return reply;
|
||||
}
|
||||
|
||||
public override async Task<QueryReply> Query(QueryRequest request, ServerCallContext context)
|
||||
{
|
||||
logger.LogInformation($"接收到来自 {request.UserId} 的请求");
|
||||
|
||||
var myDiary = new Model.MyDiary()
|
||||
{
|
||||
CreateTime = request.CreateTime.ToDateTime().ToLocalTime(),
|
||||
UserId = request.UserId
|
||||
};
|
||||
|
||||
var myDiaryToday = await myDiaryService.Queryable()
|
||||
.Where(it => it.CreateTime.Date == myDiary.CreateTime.Date && it.UserId == myDiary.UserId)
|
||||
.FirstAsync();
|
||||
|
||||
if (myDiaryToday != null)
|
||||
{
|
||||
myDiary.Content = myDiaryToday.Content;
|
||||
}
|
||||
|
||||
// 构建并返回回复消息
|
||||
var reply = new QueryReply()
|
||||
{
|
||||
Content = myDiary.Content ?? ""
|
||||
};
|
||||
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Services\FileTransferService.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Protobuf Include="Protos\greet.proto" GrpcServices="Both" />
|
||||
<Protobuf Include="Protos\block.proto" GrpcServices="Client" />
|
||||
<Protobuf Include="Protos\my_diary.proto" GrpcServices="Server" />
|
||||
<Protobuf Include="Protos\FileTransfer.proto" GrpcServices="Server" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Grpc.AspNetCore" Version="2.49.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ZR.Service\ZR.Service.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
+2
-4
@@ -1,10 +1,8 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.Dto;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
+4
-8
@@ -1,13 +1,9 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Filters;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
@@ -36,8 +32,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
// [ActionPermissionFilter(RolePermi = "admin")]
|
||||
[DataFieldFilter(typeof(PagedInfo<ArticleDto>))]
|
||||
[ActionPermissionFilter(Permission = "system:article:list")]
|
||||
public IActionResult Query([FromQuery] ArticleQueryDto parm)
|
||||
{
|
||||
var response = _ArticleService.GetList(parm);
|
||||
@@ -90,6 +85,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
long userId = HttpContext.GetUId();
|
||||
var response = _ArticleService.GetId(id);
|
||||
var model = response.Adapt<ArticleDto>();
|
||||
if (model == null) return ToResponse(ResultCode.FAIL, "文章不存在");
|
||||
if (model.IsPublic == 0 && userId != model.UserId)
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "访问失败");
|
||||
@@ -1,12 +1,8 @@
|
||||
using Infrastructure.Helper;
|
||||
using JinianNet.JNTemplate;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.IService;
|
||||
using ZR.Service.System;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
@@ -45,11 +41,8 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
[HttpGet]
|
||||
public IActionResult Index()
|
||||
{
|
||||
var contentTpl = JnHelper.ReadTemplate("", "logo.txt");
|
||||
var content = contentTpl?.Render();
|
||||
// return Ok("看到这里页面说明你已经成功启动了本项目:)\n\n" +
|
||||
// $"{content}如果觉得项目有用,打赏作者喝杯咖啡作为奖励\n☛☛http://www.izhaorui.cn/doc/support.html\n");
|
||||
return Ok($"{content}\n\n看到这里页面说明你已经成功启动了本项目:)\n");
|
||||
return Ok("看到这里页面说明你已经成功启动了本项目:)\n\n" +
|
||||
"如果觉得项目有用,打赏作者喝杯咖啡作为奖励\n☛☛http://www.izhaorui.cn/doc/support.html\n");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -79,39 +72,6 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
return SUCCESS(msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送邮件
|
||||
/// </summary>
|
||||
/// <param name="sendEmailVo">请求参数接收实体</param>
|
||||
/// <returns></returns>
|
||||
[ActionPermissionFilter(Permission = "tool:email:send")]
|
||||
[Log(Title = "发送邮件")]
|
||||
[HttpPost]
|
||||
public IActionResult SendEmail([FromBody] SendEmailDto sendEmailVo)
|
||||
{
|
||||
if (sendEmailVo == null)
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"请求参数不完整"));
|
||||
}
|
||||
if (string.IsNullOrEmpty(OptionsSetting.MailOptions.FromEmail) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password))
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"请配置邮箱信息"));
|
||||
}
|
||||
|
||||
MailHelper mailHelper = new();
|
||||
|
||||
string[] toUsers = sendEmailVo.ToUser.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
||||
if (sendEmailVo.SendMe)
|
||||
{
|
||||
toUsers.Append(mailHelper.FromEmail);
|
||||
}
|
||||
string result = mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent);
|
||||
|
||||
logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}, 结果{result}");
|
||||
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
#region 上传
|
||||
|
||||
/// <summary>
|
||||
@@ -130,7 +90,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
SysFile file = new();
|
||||
string fileExt = Path.GetExtension(formFile.FileName);//文件后缀
|
||||
double fileSize = Math.Round(formFile.Length / 1024.0, 2);//文件大小KB
|
||||
|
||||
|
||||
if (OptionsSetting.Upload.NotAllowedExt.Contains(fileExt))
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "上传失败,未经允许上传类型");
|
||||
@@ -151,8 +111,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
uploadDto.FileDir = OptionsSetting.Upload.LocalSavePath;
|
||||
}
|
||||
file = await SysFileService.SaveFileToLocal(savePath, uploadDto.FileName, uploadDto.FileDir,
|
||||
HttpContext.GetUId(), HttpContext.GetNickName(), formFile, OptionsSetting.Upload.UploadUrl);
|
||||
file = await SysFileService.SaveFileToLocal(savePath, uploadDto.FileName, uploadDto.FileDir, HttpContext.GetName(), formFile);
|
||||
break;
|
||||
case StoreType.REMOTE:
|
||||
break;
|
||||
@@ -166,8 +125,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "上传文件过大,不能超过 " + AlimaxContentLength + " MB");
|
||||
}
|
||||
file = new(formFile.FileName, uploadDto.FileName, fileExt, fileSize + "kb",
|
||||
uploadDto.FileDir, HttpContext.GetUId(), HttpContext.GetNickName())
|
||||
file = new(formFile.FileName, uploadDto.FileName, fileExt, fileSize + "kb", uploadDto.FileDir, HttpContext.GetName())
|
||||
{
|
||||
StoreType = (int)StoreType.ALIYUN,
|
||||
FileType = formFile.ContentType
|
||||
@@ -193,6 +151,36 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Verify]
|
||||
[ActionPermissionFilter(Permission = "common")]
|
||||
[Log(Title = "下载文件", IsSaveResponseData = false)]
|
||||
public IActionResult DownloadFile(string? path, long fileId = 0)
|
||||
{
|
||||
var tempPath = path;
|
||||
if (fileId > 0)
|
||||
{
|
||||
var fileInfo = SysFileService.GetById(fileId);
|
||||
if (fileInfo != null)
|
||||
{
|
||||
tempPath = fileInfo.FileUrl;
|
||||
}
|
||||
}
|
||||
string fullPath = tempPath;
|
||||
if (tempPath.StartsWith("/"))
|
||||
{
|
||||
fullPath = Path.Combine(WebHostEnvironment.WebRootPath, tempPath.ReplaceFirst("/", ""));
|
||||
}
|
||||
string fileName = Path.GetFileName(fullPath);
|
||||
return DownFile(fullPath, fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化种子数据
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.Dto;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Services;
|
||||
|
||||
//创建时间:2023-11-20
|
||||
namespace ZR.Admin.WebApi.Controllers.Email
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件发送记录
|
||||
/// </summary>
|
||||
[Verify]
|
||||
[Route("system/EmailLog")]
|
||||
[ApiExplorerSettings(GroupName = "sys")]
|
||||
public class EmailLogController : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件发送记录接口
|
||||
/// </summary>
|
||||
private readonly IEmailLogService _EmailLogService;
|
||||
private OptionsSetting OptionsSetting;
|
||||
public EmailLogController(
|
||||
IEmailLogService EmailLogService,
|
||||
IOptions<OptionsSetting> options)
|
||||
{
|
||||
_EmailLogService = EmailLogService;
|
||||
OptionsSetting = options.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询邮件发送记录列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
[ActionPermissionFilter(Permission = "emaillog:list")]
|
||||
public IActionResult QueryEmailLog([FromQuery] EmailLogQueryDto parm)
|
||||
{
|
||||
var response = _EmailLogService.GetList(parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询邮件发送记录详情
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{Id}")]
|
||||
[ActionPermissionFilter(Permission = "emaillog:query")]
|
||||
public IActionResult GetEmailLog(long Id)
|
||||
{
|
||||
var response = _EmailLogService.GetInfo(Id);
|
||||
|
||||
var info = response.Adapt<EmailLogDto>();
|
||||
return SUCCESS(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件发送记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("sendEmail")]
|
||||
[ActionPermissionFilter(Permission = "tool:email:send")]
|
||||
[Log(Title = "邮件发送", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult SendEmail([FromBody] EmailLogDto dto)
|
||||
{
|
||||
if (dto.IdArr.Length <= 0) { return ToResponse(ApiResult.Error($"发送失败Id 不能为空")); }
|
||||
int count = 0;
|
||||
foreach (var item in dto.IdArr)
|
||||
{
|
||||
var response = _EmailLogService.GetInfo(item);
|
||||
if (response?.IsSend == 0)
|
||||
{
|
||||
MailHelper mailHelper = new();
|
||||
string[] toUsers = response.ToEmails.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
string result = mailHelper.SendMail(toUsers, response.Subject, "", response.FileUrl, response.EmailContent);
|
||||
count += _EmailLogService.Update(x => x.Id == item, x => new EmailLog()
|
||||
{
|
||||
IsSend = 1,
|
||||
SendTime = DateTime.Now,
|
||||
SendResult = result
|
||||
});
|
||||
}
|
||||
}
|
||||
return SUCCESS(count);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件发送记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{ids}")]
|
||||
[ActionPermissionFilter(Permission = "emaillog:delete")]
|
||||
[Log(Title = "邮件发送记录", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult DeleteEmailLog(string ids)
|
||||
{
|
||||
long[] idsArr = Tools.SpitLongArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
|
||||
var response = _EmailLogService.Delete(idsArr);
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送邮件
|
||||
/// </summary>
|
||||
/// <param name="sendEmailVo">请求参数接收实体</param>
|
||||
/// <returns></returns>
|
||||
[ActionPermissionFilter(Permission = "tool:email:send")]
|
||||
[Log(Title = "发送邮件")]
|
||||
[HttpPost("/common/SendEmail")]
|
||||
public IActionResult SendEmail([FromBody] SendEmailDto sendEmailVo)
|
||||
{
|
||||
if (sendEmailVo == null)
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"请求参数不完整"));
|
||||
}
|
||||
if (string.IsNullOrEmpty(OptionsSetting.MailOptions.FromEmail) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password))
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"请配置邮箱信息"));
|
||||
}
|
||||
|
||||
MailHelper mailHelper = new();
|
||||
|
||||
string[] toUsers = sendEmailVo.ToUser.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
||||
string result = string.Empty;
|
||||
if (sendEmailVo.IsSend)
|
||||
{
|
||||
result = mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent);
|
||||
}
|
||||
_EmailLogService.AddEmailLog(new EmailLog() { EmailContent = sendEmailVo.HtmlContent, Subject = sendEmailVo.Subject, ToEmails = sendEmailVo.ToUser, AddTime = DateTime.Now, FromEmail = OptionsSetting.MailOptions.FromEmail, IsSend = sendEmailVo.IsSend ? 1 : 0, SendResult = result });
|
||||
//logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}, 结果{result}");
|
||||
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.Dto;
|
||||
using ZR.ServiceCore.Model;
|
||||
|
||||
//创建时间:2023-11-12
|
||||
namespace ZR.Admin.WebApi.Controllers.Email
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件模板
|
||||
/// </summary>
|
||||
[Verify]
|
||||
[Route("system/EmailTpl")]
|
||||
[ApiExplorerSettings(GroupName = "sys")]
|
||||
public class EmailTplController : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// 邮件模板接口
|
||||
/// </summary>
|
||||
private readonly IEmailTplService _EmailTplService;
|
||||
|
||||
public EmailTplController(IEmailTplService EmailTplService)
|
||||
{
|
||||
_EmailTplService = EmailTplService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询邮件模板列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
[ActionPermissionFilter(Permission = "tool:emailtpl:list")]
|
||||
public IActionResult QueryEmailTpl([FromQuery] EmailTplQueryDto parm)
|
||||
{
|
||||
var response = _EmailTplService.GetList(parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询邮件模板详情
|
||||
/// </summary>
|
||||
/// <param name="Id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{Id}")]
|
||||
public IActionResult GetEmailTpl(int Id)
|
||||
{
|
||||
var response = _EmailTplService.GetInfo(Id);
|
||||
|
||||
var info = response.Adapt<EmailTpl>();
|
||||
return SUCCESS(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加邮件模板
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
[ActionPermissionFilter(Permission = "tool:emailtpl:add")]
|
||||
[Log(Title = "邮件模板", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult AddEmailTpl([FromBody] EmailTplDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<EmailTpl>().ToCreate(HttpContext);
|
||||
|
||||
var response = _EmailTplService.AddEmailTpl(modal);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新邮件模板
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut]
|
||||
[ActionPermissionFilter(Permission = "tool:emailtpl:edit")]
|
||||
[Log(Title = "邮件模板", BusinessType = BusinessType.UPDATE)]
|
||||
public IActionResult UpdateEmailTpl([FromBody] EmailTplDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<EmailTpl>().ToUpdate(HttpContext);
|
||||
var response = _EmailTplService.UpdateEmailTpl(modal);
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除邮件模板
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{ids}")]
|
||||
[ActionPermissionFilter(Permission = "tool:emailtpl:delete")]
|
||||
[Log(Title = "邮件模板", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult DeleteEmailTpl(string ids)
|
||||
{
|
||||
int[] idsArr = Tools.SpitIntArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
|
||||
var response = _EmailTplService.Delete(idsArr);
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System;
|
||||
[Route("base/codeRule")]
|
||||
public class BaseCodeRuleController : BaseController
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly IBaseCodeRuleService _baseCodeRuleService;
|
||||
|
||||
public BaseCodeRuleController(IBaseCodeRuleService baseCodeRuleService)
|
||||
{
|
||||
_baseCodeRuleService = baseCodeRuleService;
|
||||
}
|
||||
|
||||
[HttpPost("addBaseCodeRule")]
|
||||
public async Task<IActionResult> AddBaseCodeRule([FromBody] BaseCodeRule baseCodeRule)
|
||||
{
|
||||
var result = await _baseCodeRuleService.InsertBaseCodeRuleAsync(baseCodeRule);
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
[HttpDelete("deleteBaseCodeRule/{code}")]
|
||||
public async Task<IActionResult> DeleteBaseCodeRule(string code)
|
||||
{
|
||||
var result = await _baseCodeRuleService.DeleteBaseCodeRuleAsync(code);
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
[HttpPut("updateBaseCodeRule")]
|
||||
public async Task<IActionResult> UpdateBaseCodeRule([FromBody] BaseCodeRule baseCodeRule)
|
||||
{
|
||||
var result = await _baseCodeRuleService.UpdateBaseCodeRule(baseCodeRule);
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
[HttpGet("getBaseCodeRuleList")]
|
||||
public IActionResult GetBaseCodeRuleList([FromQuery] BaseCodeRule baseCodeRule, [FromQuery] PagerInfo pagerInfo)
|
||||
{
|
||||
var result = _baseCodeRuleService.SelectBaseCodeRulePage(baseCodeRule, pagerInfo);
|
||||
return SUCCESS(result);
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using SqlSugar;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.CodeGenerator;
|
||||
using ZR.CodeGenerator.Model;
|
||||
using ZR.CodeGenerator.Service;
|
||||
using ZR.Model;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Model.Generate;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.Model.System.Dto;
|
||||
using ZR.Model.System.Generate;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
@@ -26,16 +24,20 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
private readonly IGenTableColumnService GenTableColumnService;
|
||||
private readonly ISysMenuService SysMenuService;
|
||||
private readonly IWebHostEnvironment WebHostEnvironment;
|
||||
private readonly OptionsSetting OptionsSetting;
|
||||
|
||||
public CodeGeneratorController(
|
||||
IGenTableService genTableService,
|
||||
IGenTableColumnService genTableColumnService,
|
||||
IWebHostEnvironment webHostEnvironment,
|
||||
IOptions<OptionsSetting> options,
|
||||
ISysMenuService sysMenuService)
|
||||
{
|
||||
GenTableService = genTableService;
|
||||
GenTableColumnService = genTableColumnService;
|
||||
WebHostEnvironment = webHostEnvironment;
|
||||
SysMenuService = sysMenuService;
|
||||
OptionsSetting = options.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -135,43 +137,47 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
/// <summary>
|
||||
/// 导入表结构(保存)
|
||||
/// </summary>
|
||||
/// <param name="tables"></param>
|
||||
/// <param name="dbName"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("importTable")]
|
||||
[Log(Title = "代码生成", BusinessType = BusinessType.IMPORT)]
|
||||
[ActionPermissionFilter(Permission = "tool:gen:import")]
|
||||
public IActionResult ImportTableSave(string tables, string dbName)
|
||||
public IActionResult ImportTableSave([FromBody] ImportCodeGenTableDto dto)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tables))
|
||||
if (string.IsNullOrEmpty(dto.DbName) || dto.Tables == null)
|
||||
{
|
||||
throw new CustomException("表不能为空");
|
||||
throw new CustomException("表或数据库不能为空");
|
||||
}
|
||||
DbConfigs dbConfig = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig));
|
||||
string[] tableNames = tables.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
int result = 0;
|
||||
foreach (var tableName in tableNames)
|
||||
foreach (var table in dto.Tables)
|
||||
{
|
||||
var tabInfo = _CodeGeneraterService.GetTableInfo(dbName, tableName);
|
||||
if (tabInfo != null)
|
||||
List<OracleSeq> seqs = new();
|
||||
InitTableDto initTableDto = new()
|
||||
{
|
||||
List<OracleSeq> seqs = new();
|
||||
GenTable genTable = CodeGeneratorTool.InitTable(dbName, HttpContext.GetName(), tableName, tabInfo?.Description);
|
||||
genTable.TableId = GenTableService.ImportGenTable(genTable);
|
||||
if (dbConfig.DbType == 3)
|
||||
{
|
||||
seqs = _CodeGeneraterService.GetAllOracleSeqs(dbName);
|
||||
}
|
||||
if (genTable.TableId > 0)
|
||||
{
|
||||
//保存列信息
|
||||
List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(dbName, tableName);
|
||||
List<GenTableColumn> genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos, seqs);
|
||||
GenTableColumnService.DeleteGenTableColumnByTableName(tableName);
|
||||
GenTableColumnService.InsertGenTableColumn(genTableColumns);
|
||||
genTable.Columns = genTableColumns;
|
||||
result++;
|
||||
}
|
||||
DbName = dto.DbName,
|
||||
UserName = HttpContext.GetName(),
|
||||
TableName = table.Name,
|
||||
Desc = table.Description,
|
||||
CodeGen = OptionsSetting.CodeGen,
|
||||
FrontTpl = dto.FrontTpl,
|
||||
};
|
||||
|
||||
GenTable genTable = CodeGeneratorTool.InitTable(initTableDto);
|
||||
genTable.TableId = GenTableService.ImportGenTable(genTable);
|
||||
if (OptionsSetting.CodeGenDbConfig.DbType == 3)
|
||||
{
|
||||
seqs = _CodeGeneraterService.GetAllOracleSeqs(table.Name);
|
||||
}
|
||||
if (genTable.TableId > 0)
|
||||
{
|
||||
//保存列信息
|
||||
List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(dto.DbName, table.Name);
|
||||
List<GenTableColumn> genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos, seqs, OptionsSetting.CodeGen);
|
||||
GenTableColumnService.DeleteGenTableColumnByTableName(table.Name);
|
||||
GenTableColumnService.InsertGenTableColumn(genTableColumns);
|
||||
genTable.Columns = genTableColumns;
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +202,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
var genTable = genTableDto.Adapt<GenTable>().ToUpdate(HttpContext);
|
||||
|
||||
//将前端额外参数转成字符串存入Options中
|
||||
genTable.Options = genTableDto.Params.Adapt<Options>();
|
||||
genTable.Options = genTableDto.Params.Adapt<CodeOptions>();
|
||||
DbResult<bool> result = GenTableService.UseTran(() =>
|
||||
{
|
||||
int rows = GenTableService.UpdateGenTable(genTable);
|
||||
@@ -225,9 +231,8 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
|
||||
}
|
||||
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
|
||||
var dbConfig = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig));
|
||||
|
||||
dto.DbType = dbConfig.DbType;
|
||||
dto.DbType = OptionsSetting.CodeGenDbConfig.DbType;
|
||||
dto.GenTable = genTableInfo;
|
||||
dto.IsPreview = true;
|
||||
|
||||
@@ -250,44 +255,53 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
|
||||
}
|
||||
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
|
||||
var dbConfig = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig));
|
||||
|
||||
dto.DbType = dbConfig.DbType;
|
||||
dto.GenTable = genTableInfo;
|
||||
//自定义路径
|
||||
if (genTableInfo.GenType == "1")
|
||||
dto.DbType = OptionsSetting.CodeGenDbConfig.DbType;
|
||||
dto.GenTable = GenTableService.GetGenTableInfo(dto.TableId);
|
||||
//生成压缩包
|
||||
string zipReturnFileName = $"ZrAdmin.NET-{dto.GenTable.TableName}-{DateTime.Now:MMddHHmmss}.zip";
|
||||
|
||||
//生成代码到指定文件夹
|
||||
CodeGeneratorTool.Generate(dto);
|
||||
if (dto.GenTable.Options.GenerateMenu)
|
||||
{
|
||||
var genPath = genTableInfo.GenPath;
|
||||
SysMenuService.AddSysMenu(dto.GenTable, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport, dto.ReplaceDto.ShowBtnImport);
|
||||
}
|
||||
if (dto.GenTable.GenType == "1")//自定义路径
|
||||
{
|
||||
var genPath = dto.GenTable.GenPath;
|
||||
string parentPath;
|
||||
string tempPath = WebHostEnvironment.ContentRootPath;
|
||||
var parentPath = tempPath[..tempPath.LastIndexOf(@"\")];
|
||||
|
||||
if (ComputerHelper.IsUnix())
|
||||
{
|
||||
parentPath = Path.Combine(WebHostEnvironment.WebRootPath, "Generatecode");
|
||||
}
|
||||
else
|
||||
{
|
||||
parentPath = tempPath[..tempPath.LastIndexOf(@"\")];
|
||||
}
|
||||
Console.WriteLine("代码生成路径" + parentPath);
|
||||
//代码生成文件夹路径
|
||||
dto.GenCodePath = (genPath.IsEmpty() || genPath.Equals("/")) ? parentPath : genTableInfo.GenPath;
|
||||
dto.GenCodePath = (genPath.IsEmpty() || genPath.Equals("/")) ? parentPath : genPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
dto.ZipPath = Path.Combine(WebHostEnvironment.WebRootPath, "Generatecode");
|
||||
dto.GenCodePath = Path.Combine(dto.ZipPath, DateTime.Now.ToString("yyyyMMdd"));
|
||||
}
|
||||
//生成压缩包
|
||||
string zipReturnFileName = $"ZrAdmin.NET-{genTableInfo.TableComment}-{DateTime.Now:MMddHHmmss}.zip";
|
||||
|
||||
//生成代码到指定文件夹
|
||||
CodeGeneratorTool.Generate(dto);
|
||||
if (genTableInfo.Options.GenerateMenu)
|
||||
{
|
||||
SysMenuService.AddSysMenu(genTableInfo, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport, dto.ReplaceDto.ShowBtnImport);
|
||||
}
|
||||
|
||||
//写入文件
|
||||
foreach (var item in dto.GenCodes)
|
||||
{
|
||||
item.Path = Path.Combine(dto.GenCodePath, item.Path);
|
||||
FileUtil.WriteAndSave(item.Path, item.Content);
|
||||
}
|
||||
|
||||
//下载文件
|
||||
FileUtil.ZipGenCode(dto.ZipPath, dto.GenCodePath, zipReturnFileName);
|
||||
|
||||
if (dto.GenTable.GenType != "1")
|
||||
{
|
||||
//压缩文件
|
||||
FileUtil.ZipGenCode(dto.ZipPath, dto.GenCodePath, zipReturnFileName);
|
||||
}
|
||||
return SUCCESS(new { path = "/Generatecode/" + zipReturnFileName, fileName = dto.ZipFileName });
|
||||
}
|
||||
|
||||
@@ -305,11 +319,11 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
if (string.IsNullOrEmpty(tableName) || tableId <= 0) throw new CustomException("参数错误");
|
||||
GenTable table = GenTableService.GetGenTableInfo(tableId);
|
||||
if (table == null) { throw new CustomException("同步数据失败,原表结构不存在"); }
|
||||
table.Update_by = HttpContext.GetUId();
|
||||
table.Update_name = HttpContext.GetNickName();
|
||||
table.Update_by = HttpContext.GetName();
|
||||
|
||||
var codeGen = AppSettings.Get<CodeGen>("codeGen");
|
||||
List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(table.DbName, tableName);
|
||||
List<GenTableColumn> dbTableColumns = CodeGeneratorTool.InitGenTableColumn(table, dbColumnInfos);
|
||||
List<GenTableColumn> dbTableColumns = CodeGeneratorTool.InitGenTableColumn(table, dbColumnInfos, codeGen: codeGen);
|
||||
|
||||
bool result = GenTableService.SynchDb(tableId, table, dbTableColumns);
|
||||
return SUCCESS(result);
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using Infrastructure.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using MiniExcelLibs;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.Dto;
|
||||
using ZR.Model.Models;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
using Infrastructure.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
using System.Collections;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -115,8 +113,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, $"新增部门{dept.DeptName}失败,部门名称已存在");
|
||||
}
|
||||
dept.Create_by = HttpContext.GetUId();
|
||||
dept.Create_name = HttpContext.GetNickName();
|
||||
dept.Create_by = HttpContext.GetName();
|
||||
return ToResponse(DeptService.InsertDept(dept));
|
||||
}
|
||||
|
||||
@@ -138,8 +135,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, $"修改部门{dept.DeptName}失败,上级部门不能是自己");
|
||||
}
|
||||
dept.Update_by = HttpContext.GetUId();
|
||||
dept.Update_name = HttpContext.GetNickName();
|
||||
dept.Update_by = HttpContext.GetName();
|
||||
return ToResponse(DeptService.UpdateDept(dept));
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -66,14 +64,14 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost("types")]
|
||||
public IActionResult DictTypes([FromBody] List<SysDictDataDto> dto)
|
||||
public IActionResult DictTypes([FromBody] List<SysdictDataDto> dto)
|
||||
{
|
||||
var list = SysDictDataService.SelectDictDataByTypes(dto.Select(f => f.DictType).ToArray());
|
||||
List<SysDictDataDto> dataVos = new();
|
||||
List<SysdictDataDto> dataVos = new();
|
||||
|
||||
foreach (var dic in dto)
|
||||
{
|
||||
SysDictDataDto vo = new()
|
||||
SysdictDataDto vo = new()
|
||||
{
|
||||
DictType = dic.DictType,
|
||||
ColumnName = dic.ColumnName,
|
||||
@@ -110,8 +108,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[HttpPost()]
|
||||
public IActionResult Add([FromBody] SysDictData dict)
|
||||
{
|
||||
dict.Create_by = HttpContext.GetUId();
|
||||
dict.Create_name = HttpContext.GetNickName();
|
||||
dict.Create_by = HttpContext.GetName();
|
||||
dict.Create_time = DateTime.Now;
|
||||
return SUCCESS(SysDictDataService.InsertDictData(dict));
|
||||
}
|
||||
@@ -126,8 +123,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[HttpPut()]
|
||||
public IActionResult Edit([FromBody] SysDictData dict)
|
||||
{
|
||||
dict.Update_by = HttpContext.GetUId();
|
||||
dict.Update_name = HttpContext.GetNickName();
|
||||
dict.Update_by = HttpContext.GetName();
|
||||
return SUCCESS(SysDictDataService.UpdateDictData(dict));
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,8 @@ using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -66,8 +65,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"新增字典'{dict.DictName}'失败,字典类型已存在"));
|
||||
}
|
||||
dict.Create_by = HttpContext.GetUId();
|
||||
dict.Create_name = HttpContext.GetNickName();
|
||||
dict.Create_by = HttpContext.GetName();
|
||||
dict.Create_time = DateTime.Now;
|
||||
return SUCCESS(SysDictService.InsertDictType(dict));
|
||||
}
|
||||
@@ -89,8 +87,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
return ToResponse(ApiResult.Error($"修改字典'{dict.DictName}'失败,字典类型已存在"));
|
||||
}
|
||||
//设置添加人
|
||||
dict.Update_by = HttpContext.GetUId();
|
||||
dict.Update_name = HttpContext.GetNickName();
|
||||
dict.Update_by = HttpContext.GetName();
|
||||
return SUCCESS(SysDictService.UpdateDictType(dict));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System;
|
||||
|
||||
[Verify]
|
||||
[Route("system/field")]
|
||||
public class SysFieldController : BaseController
|
||||
{
|
||||
private readonly ISysFieldService _sysFieldService;
|
||||
private readonly ISysRoleFieldService _sysRoleFieldService;
|
||||
|
||||
public SysFieldController(ISysFieldService sysFieldService, ISysRoleFieldService sysRoleFieldService)
|
||||
{
|
||||
_sysFieldService = sysFieldService;
|
||||
_sysRoleFieldService = sysRoleFieldService;
|
||||
}
|
||||
|
||||
[HttpGet("getModelList")]
|
||||
public async Task<IActionResult> GetModelList([FromQuery] PagerInfo pagerInfo)
|
||||
=> SUCCESS(await _sysFieldService.GetModelList(pagerInfo));
|
||||
|
||||
[HttpGet("getFields")]
|
||||
public async Task<IActionResult> GetFields([FromQuery] string fullName, long roleId)
|
||||
=> SUCCESS(await _sysFieldService.GetFields(fullName, roleId));
|
||||
|
||||
[HttpPost("initFields")]
|
||||
public async Task<IActionResult> InitFields()
|
||||
=> SUCCESS(await _sysFieldService.InitFields());
|
||||
|
||||
[HttpPut("addOrUpdateSysRoleField/{roleId}")]
|
||||
public async Task<IActionResult> AddOrUpdateSysRoleField([FromBody] List<SysFieldDto> sysFieldDtos,
|
||||
[FromRoute] long roleId)
|
||||
=> SUCCESS(await _sysRoleFieldService.InsertOrUpdateSysRoleField(sysFieldDtos, roleId));
|
||||
|
||||
[HttpPost("fieldDisplay")]
|
||||
public async Task<IActionResult> FieldDisplay(string blockCode)
|
||||
{
|
||||
var info = JwtUtil.GetLoginUser(HttpContext);
|
||||
var roleIds = info.Roles.Select(it => it.RoleId).ToList();
|
||||
var list = await _sysFieldService.Queryable()
|
||||
.LeftJoin<SysFieldBlock>((sf, sfb) => sf.Id == sfb.FieldId)
|
||||
.LeftJoin<SysBlock>((sf, sfb, sb) => sfb.BlockId == sb.Id )
|
||||
.LeftJoin<SysRoleField>((sf,sfb, sb, srf) => sf.Id == srf.FieldId)
|
||||
.Where((sf,sfb, sb, srf) => roleIds.Contains(srf.RoleId))
|
||||
.Where((sf,sfb, sb, srf) => sb.Code == blockCode)
|
||||
.WithCache(10 * 60)
|
||||
.Select((sf,sfb, sb, srf) => sf.FieldName)
|
||||
.ToListAsync();
|
||||
// var list = await _sysFieldService.Queryable()
|
||||
// .LeftJoin<SysRoleField>((sf, srf) => sf.Id == srf.FieldId)
|
||||
// .Where((sf, srf) => roleIds.Contains(srf.RoleId))
|
||||
// .WithCache(10 * 60)
|
||||
// .Select((sf, srf) => sf.FieldName)
|
||||
// .ToListAsync();
|
||||
return SUCCESS(list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
using NLog;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.Model.System;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
{
|
||||
@@ -18,14 +17,12 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
/// <summary>
|
||||
/// 文件存储接口
|
||||
/// </summary>
|
||||
private readonly ISysFileService _sysFileService;
|
||||
private readonly ISysFileService _SysFileService;
|
||||
|
||||
public SysFileController(ISysFileService sysFileService)
|
||||
public SysFileController(ISysFileService SysFileService)
|
||||
{
|
||||
_sysFileService = sysFileService;
|
||||
_SysFileService = SysFileService;
|
||||
}
|
||||
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// 查询文件存储列表
|
||||
@@ -43,7 +40,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
predicate = predicate.AndIF(parm.StoreType != null, m => m.StoreType == parm.StoreType);
|
||||
predicate = predicate.AndIF(parm.FileId != null, m => m.Id == parm.FileId);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -56,7 +53,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
[ActionPermissionFilter(Permission = "tool:file:query")]
|
||||
public IActionResult GetSysFile(long Id)
|
||||
{
|
||||
var response = _sysFileService.GetFirst(x => x.Id == Id);
|
||||
var response = _SysFileService.GetFirst(x => x.Id == Id);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
@@ -68,12 +65,13 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
[HttpDelete("{ids}")]
|
||||
[ActionPermissionFilter(Permission = "tool:file:delete")]
|
||||
[Log(Title = "文件存储", BusinessType = BusinessType.DELETE)]
|
||||
public async Task<IActionResult> DeleteSysFile(string ids)
|
||||
public IActionResult DeleteSysFile(string ids)
|
||||
{
|
||||
long[] idsArr = Tools.SpitLongArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
|
||||
var response = await _sysFileService.DeleteSysFileAsync(idsArr);
|
||||
var response = _SysFileService.Delete(idsArr);
|
||||
//TODO 删除本地资源
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
@@ -87,89 +85,10 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
[ActionPermissionFilter(Permission = "tool:file:export")]
|
||||
public IActionResult Export()
|
||||
{
|
||||
var list = _sysFileService.GetAll();
|
||||
var list = _SysFileService.GetAll();
|
||||
|
||||
string sFileName = ExportExcel(list, "SysFile", "文件存储");
|
||||
return SUCCESS(new { path = "/export/" + sFileName, fileName = sFileName });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过文件ID下载文件
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("download")]
|
||||
public IActionResult Download([FromBody] SysFile file)
|
||||
{
|
||||
var sysFile = _sysFileService.Queryable().Where(it => it.Id == file.Id).First();
|
||||
if (sysFile == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
Stream? stream = null;
|
||||
switch ((StoreType)Enum.Parse(typeof(StoreType), sysFile.StoreType.ToString() ?? string.Empty))
|
||||
{
|
||||
case StoreType.LOCAL:
|
||||
stream = sysFile.IsEncrypted == "1" ? _sysFileService.DecryptSysFileStream(sysFile.FileUrl)
|
||||
: new FileStream(sysFile.FileUrl, FileMode.Open);
|
||||
break;
|
||||
case StoreType.ALIYUN:
|
||||
stream = AliyunOssHelper.DownloadFile(sysFile.FileUrl, "", sysFile.IsEncrypted == "1");
|
||||
break;
|
||||
default:
|
||||
throw new CustomException("不支持的存储类型");
|
||||
}
|
||||
if (stream != null)
|
||||
{
|
||||
return new FileStreamResult(stream, "application/octet-stream")
|
||||
{
|
||||
FileDownloadName = sysFile.RealName
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过文件ID下载文件
|
||||
/// </summary>
|
||||
/// <param name="fileId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("download/{fileId}")]
|
||||
public IActionResult Download([FromRoute] long fileId)
|
||||
{
|
||||
var sysFile = _sysFileService.Queryable().Where(it => it.Id == fileId).First();
|
||||
if (sysFile == null)
|
||||
{
|
||||
throw new CustomException("服务器上不存在此文件");
|
||||
}
|
||||
|
||||
Stream? stream;
|
||||
switch ((StoreType)Enum.Parse(typeof(StoreType), sysFile.StoreType.ToString() ?? string.Empty))
|
||||
{
|
||||
case StoreType.LOCAL:
|
||||
Logger.Info("本地存储");
|
||||
stream = sysFile.IsEncrypted == "1" ? _sysFileService.DecryptSysFileStream(sysFile.FileUrl)
|
||||
: new FileStream(sysFile.FileUrl, FileMode.Open);
|
||||
break;
|
||||
case StoreType.ALIYUN:
|
||||
stream = AliyunOssHelper.DownloadFile(sysFile.FileUrl, "", sysFile.IsEncrypted == "1");
|
||||
break;
|
||||
default:
|
||||
throw new CustomException("不支持的存储类型");
|
||||
}
|
||||
if (stream != null)
|
||||
{
|
||||
return new FileStreamResult(stream, "application/octet-stream")
|
||||
{
|
||||
FileDownloadName = sysFile.RealName
|
||||
};
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
using Lazy.Captcha.Core;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NETCore.Encrypt;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Infrastructure.Cache;
|
||||
using ZR.Service.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.Infrastructure.Helper;
|
||||
using ZR.Model.System;
|
||||
using ZR.Model.System.Dto;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -17,8 +14,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[ApiExplorerSettings(GroupName = "sys")]
|
||||
public class SysLoginController : BaseController
|
||||
{
|
||||
//static readonly NLog.Logger logger = NLog.LogManager.GetLogger("LoginController");
|
||||
private readonly IHttpContextAccessor httpContextAccessor;
|
||||
private readonly ISysUserService sysUserService;
|
||||
private readonly ISysMenuService sysMenuService;
|
||||
private readonly ISysLoginService sysLoginService;
|
||||
@@ -26,32 +21,28 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
private readonly ICaptcha SecurityCodeHelper;
|
||||
private readonly ISysConfigService sysConfigService;
|
||||
private readonly ISysRoleService roleService;
|
||||
private readonly OptionsSetting optionSettings;
|
||||
private readonly ISmsCodeLogService smsCodeLogService;
|
||||
|
||||
public SysLoginController(
|
||||
IHttpContextAccessor contextAccessor,
|
||||
ISysMenuService sysMenuService,
|
||||
ISysUserService sysUserService,
|
||||
ISysLoginService sysLoginService,
|
||||
ISysPermissionService permissionService,
|
||||
ISysConfigService configService,
|
||||
ISysRoleService sysRoleService,
|
||||
ICaptcha captcha,
|
||||
IOptions<OptionsSetting> optionSettings)
|
||||
ISmsCodeLogService smsCodeLogService,
|
||||
ICaptcha captcha)
|
||||
{
|
||||
httpContextAccessor = contextAccessor;
|
||||
SecurityCodeHelper = captcha;
|
||||
this.sysMenuService = sysMenuService;
|
||||
this.sysUserService = sysUserService;
|
||||
this.sysLoginService = sysLoginService;
|
||||
this.permissionService = permissionService;
|
||||
this.sysConfigService = configService;
|
||||
this.smsCodeLogService = smsCodeLogService;
|
||||
roleService = sysRoleService;
|
||||
this.optionSettings = optionSettings.Value;
|
||||
}
|
||||
|
||||
// RSA私钥
|
||||
private static readonly string PrivatePem = AppSettings.GetConfig("RSA:PrivatePem");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 登录
|
||||
@@ -65,21 +56,14 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
if (loginBody == null) { throw new CustomException("请求参数错误"); }
|
||||
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
|
||||
var sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
|
||||
var headers = HttpContext.Request.Headers;
|
||||
var isRemoteInvoke = headers["Remote-Invoke"].FirstOrDefault().ParseToBool();
|
||||
if (sysConfig?.ConfigValue != "off" && !SecurityCodeHelper.Validate(loginBody.Uuid, loginBody.Code)
|
||||
&& !isRemoteInvoke)
|
||||
SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
|
||||
if (sysConfig?.ConfigValue != "off" && !SecurityCodeHelper.Validate(loginBody.Uuid, loginBody.Code))
|
||||
{
|
||||
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
|
||||
}
|
||||
|
||||
sysLoginService.CheckLockUser(loginBody.Username);
|
||||
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
|
||||
|
||||
// RSA解密
|
||||
loginBody.Password = EncryptProvider.RSADecryptWithPem(PrivatePem, loginBody.Password);
|
||||
|
||||
var user = sysLoginService.Login(loginBody, new SysLogininfor() { LoginLocation = location });
|
||||
|
||||
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
|
||||
@@ -141,7 +125,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
public IActionResult GetRouters()
|
||||
{
|
||||
long uid = HttpContext.GetUId();
|
||||
var menus = sysMenuService.SelectMenuTreeByUserId(uid);
|
||||
var menus = sysMenuService.SelectMenuTreeByUserId(uid);
|
||||
|
||||
return SUCCESS(sysMenuService.BuildMenus(menus));
|
||||
}
|
||||
@@ -183,7 +167,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
|
||||
}
|
||||
|
||||
dto.UserIP = HttpContext.GetClientUserIp();
|
||||
SysUser user = sysUserService.Register(dto);
|
||||
if (user.UserId > 0)
|
||||
{
|
||||
@@ -192,64 +176,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送邮箱验证码
|
||||
/// </summary>
|
||||
/// <param name="sendEmailVo"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("getMailCode")]
|
||||
public async Task<IActionResult> GetMailCode([FromBody] SendEmailDto sendEmailVo)
|
||||
{
|
||||
if (string.IsNullOrEmpty(sendEmailVo.ToUser))
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"邮箱不能为空"));
|
||||
}
|
||||
if (string.IsNullOrEmpty(optionSettings.MailOptions.FromEmail) || string.IsNullOrEmpty(optionSettings.MailOptions.Password))
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"请配置邮箱信息"));
|
||||
}
|
||||
|
||||
if (sendEmailVo.ToUser.Length > 32)
|
||||
{
|
||||
// 解密邮箱
|
||||
sendEmailVo.ToUser = EncryptProvider.RSADecryptWithPem(PrivatePem, sendEmailVo.ToUser);
|
||||
|
||||
// 验证邮箱是否存在于系统用户中
|
||||
var user = await sysUserService.IsAnyAsync(it => it.Email == sendEmailVo.ToUser);
|
||||
// if (user == null || user.UserId <= 0)
|
||||
// 不存在则提示错误
|
||||
if (!user)
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"邮箱错误,请联系管理员"));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] saltKey = await RedisServer.Session.LRangeAsync("saltMail:" + sendEmailVo.ToUser, 0, 1);
|
||||
if (saltKey.Length > 0)
|
||||
{
|
||||
sendEmailVo.ToUser = saltKey[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"邮箱错误,请联系管理员"));
|
||||
}
|
||||
}
|
||||
// 实例化MailHelper以准备发送邮件
|
||||
MailHelper mailHelper = new();
|
||||
// 生成6位邮箱验证码
|
||||
var verifyCode = mailHelper.VerifyCode(6);
|
||||
// 设置存入Redis的key为 verifyCode: 前缀 + (盐 + 邮箱)的MD5值
|
||||
var key = "verifyCode:" + sendEmailVo.ToUser;
|
||||
// 存入Redis中设置过期时间为15分钟
|
||||
var res = await RedisServer.Session.SetAsync(key, verifyCode, 900);
|
||||
// 发送邮件,主题为 ZRAdmin.NET邮箱验证码,内容为验证码
|
||||
mailHelper.SendMail(sendEmailVo.ToUser, "ZRAdmin.NET邮箱验证码", verifyCode);
|
||||
|
||||
return SUCCESS(res);
|
||||
}
|
||||
|
||||
#region 二维码登录
|
||||
|
||||
/// <summary>
|
||||
@@ -313,7 +239,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
if (dto == null) { return ToResponse(ResultCode.CUSTOM_ERROR, "扫码失败"); }
|
||||
var name = App.HttpContext.GetName();
|
||||
|
||||
|
||||
sysLoginService.CheckLockUser(name);
|
||||
|
||||
TokenModel tokenModel = JwtUtil.GetLoginUser(HttpContext);
|
||||
@@ -323,12 +249,80 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
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
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("checkMobile")]
|
||||
[Log(Title = "发送短息", BusinessType = BusinessType.INSERT)]
|
||||
public IActionResult CheckMobile([FromBody] PhoneLoginDto dto)
|
||||
{
|
||||
dto.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
|
||||
|
||||
SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
|
||||
if (sysConfig?.ConfigValue != "off" && !SecurityCodeHelper.Validate(dto.Uuid, dto.Code, false))
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "验证码错误");
|
||||
}
|
||||
string location = HttpContextExtension.GetIpInfo(dto.LoginIP);
|
||||
var info = sysUserService.GetFirst(f => f.Phonenumber == dto.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
|
||||
|
||||
var smsCode = RandomHelper.GenerateNum(6);
|
||||
var smsContent = $"验证码{smsCode}(随机验证码),有效期10分钟。";
|
||||
//TODO 发送短息验证码,1分钟内允许一次
|
||||
smsCodeLogService.AddSmscodeLog(new ServiceCore.Model.SmsCodeLog()
|
||||
{
|
||||
Userid = info.UserId,
|
||||
PhoneNum = dto.PhoneNum.ParseToLong(),
|
||||
AddTime = DateTime.Now,
|
||||
SendType = 1,
|
||||
SmsCode = smsCode,
|
||||
SmsContent = smsContent,
|
||||
UserIP = dto.LoginIP,
|
||||
Location = location,
|
||||
});
|
||||
CacheService.SetPhoneCode(dto.PhoneNum, smsCode);
|
||||
|
||||
return SUCCESS(new { smsCode });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手机号登录
|
||||
/// </summary>
|
||||
/// <param name="loginBody">登录对象</param>
|
||||
/// <returns></returns>
|
||||
[Route("PhoneLogin")]
|
||||
[HttpPost]
|
||||
[Log(Title = "手机号登录")]
|
||||
public IActionResult PhoneLogin([FromBody] PhoneLoginDto loginBody)
|
||||
{
|
||||
if (loginBody == null) { throw new CustomException("请求参数错误"); }
|
||||
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
|
||||
|
||||
if (!CacheService.CheckPhoneCode(loginBody.PhoneNum, loginBody.PhoneCode))
|
||||
{
|
||||
return ToResponse(ResultCode.CUSTOM_ERROR, "短信验证码错误");
|
||||
}
|
||||
var info = sysUserService.GetFirst(f => f.Phonenumber == loginBody.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
|
||||
sysLoginService.CheckLockUser(info.UserName);
|
||||
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
|
||||
var user = sysLoginService.PhoneLogin(loginBody, new SysLogininfor() { LoginLocation = location }, info);
|
||||
|
||||
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
|
||||
//权限集合 eg *:*:*,system:user:list
|
||||
List<string> permissions = permissionService.GetMenuPermission(user);
|
||||
|
||||
TokenModel loginUser = new(user.Adapt<TokenModel>(), roles.Adapt<List<Roles>>());
|
||||
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
|
||||
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -30,16 +28,28 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
this.sysRoleMenuService = sysRoleMenuService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取菜单树列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ActionPermissionFilter(Permission = "system:menu:list")]
|
||||
[HttpGet("treelist")]
|
||||
public IActionResult TreeMenuList([FromQuery] MenuQueryDto menu)
|
||||
{
|
||||
long userId = HttpContext.GetUId();
|
||||
return SUCCESS(sysMenuService.SelectTreeMenuList(menu, userId), "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取菜单列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ActionPermissionFilter(Permission = "system:menu:list")]
|
||||
[HttpGet("list")]
|
||||
public IActionResult TreeMenuList([FromQuery] MenuQueryDto menu)
|
||||
public IActionResult MenuList([FromQuery] MenuQueryDto menu)
|
||||
{
|
||||
long userId = HttpContext.GetUId();
|
||||
return SUCCESS(sysMenuService.SelectTreeMenuList(menu, userId), "yyyy-MM-dd HH:mm:ss");
|
||||
return SUCCESS(sysMenuService.SelectMenuList(menu, userId), "yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,8 +125,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"修改菜单'{modal.MenuName}'失败,上级菜单不能选择自己"));
|
||||
}
|
||||
modal.Update_by = HttpContext.GetUId();
|
||||
modal.Update_name = HttpContext.GetNickName();
|
||||
modal.Update_by = HttpContext.GetName();
|
||||
long result = sysMenuService.EditMenu(modal);
|
||||
|
||||
return ToResponse(result);
|
||||
@@ -148,8 +157,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
return ToResponse(ApiResult.Error($"新增菜单'{menu.MenuName}'失败,地址必须以http(s)://开头"));
|
||||
}
|
||||
|
||||
menu.Create_by = HttpContext.GetUId();
|
||||
menu.Create_name = HttpContext.GetNickName();
|
||||
menu.Create_by = HttpContext.GetName();
|
||||
long result = sysMenuService.AddMenu(menu);
|
||||
|
||||
return ToResponse(result);
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.AspNetCore.SignalR.Client;
|
||||
using NLog;
|
||||
using SqlSugar;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.Model.System;
|
||||
using ZR.Model.System.Dto;
|
||||
using ZR.ServiceCore.Signalr;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
@@ -25,17 +20,13 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <summary>
|
||||
/// 通知公告表接口
|
||||
/// </summary>
|
||||
private readonly ISysNoticeService _sysNoticeService;
|
||||
private readonly ISysNoticeService _SysNoticeService;
|
||||
private readonly IHubContext<MessageHub> _hubContext;
|
||||
private readonly ISysNoticeLogService _sysNoticeLogService;
|
||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||
private readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
public SysNoticeController(ISysNoticeService sysNoticeService, IHubContext<MessageHub> hubContext, ISysNoticeLogService sysNoticeLogService, IWebHostEnvironment webHostEnvironment)
|
||||
|
||||
public SysNoticeController(ISysNoticeService SysNoticeService, IHubContext<MessageHub> hubContext)
|
||||
{
|
||||
_sysNoticeService = sysNoticeService;
|
||||
_SysNoticeService = SysNoticeService;
|
||||
_hubContext = hubContext;
|
||||
_sysNoticeLogService = sysNoticeLogService;
|
||||
_webHostEnvironment = webHostEnvironment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -46,9 +37,9 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
public IActionResult QueryNotice([FromQuery] SysNoticeQueryDto parm)
|
||||
{
|
||||
var predicate = Expressionable.Create<SysNotice>();
|
||||
|
||||
|
||||
predicate = predicate.And(m => m.Status == 0);
|
||||
var response = _sysNoticeService.GetPages(predicate.ToExpression(), parm);
|
||||
var response = _SysNoticeService.GetPages(predicate.ToExpression(), parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
@@ -60,19 +51,19 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[ActionPermissionFilter(Permission = "system:notice:list")]
|
||||
public IActionResult QuerySysNotice([FromQuery] SysNoticeQueryDto parm)
|
||||
{
|
||||
PagedInfo<SysNotice> response = _sysNoticeService.GetPageList(parm);
|
||||
PagedInfo<SysNotice> response = _SysNoticeService.GetPageList(parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询通知公告表详情
|
||||
/// </summary>
|
||||
/// <param name="noticeId"></param>
|
||||
/// <param name="NoticeId"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{noticeId}")]
|
||||
public IActionResult GetSysNotice(long noticeId)
|
||||
[HttpGet("{NoticeId}")]
|
||||
public IActionResult GetSysNotice(int NoticeId)
|
||||
{
|
||||
var response = _sysNoticeService.GetFirst(x => x.NoticeId == noticeId);
|
||||
var response = _SysNoticeService.GetFirst(x => x.NoticeId == NoticeId);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
@@ -84,41 +75,21 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[HttpPost]
|
||||
[ActionPermissionFilter(Permission = "system:notice:add")]
|
||||
[Log(Title = "发布通告", BusinessType = BusinessType.INSERT)]
|
||||
public async Task<IActionResult> AddSysNotice([FromBody] SysNoticeDto parm)
|
||||
public IActionResult AddSysNotice([FromBody] SysNoticeDto parm)
|
||||
{
|
||||
var modal = parm.Adapt<SysNotice>().ToCreate(HttpContext);
|
||||
modal.Create_by = HttpContext.GetUId();
|
||||
modal.Create_name = HttpContext.GetNickName();
|
||||
modal.Create_time = DateTime.Now;
|
||||
|
||||
// int result = _SysNoticeService.Insert(modal, it => new
|
||||
// {
|
||||
// it.NoticeTitle,
|
||||
// it.NoticeType,
|
||||
// it.NoticeContent,
|
||||
// it.Status,
|
||||
// it.Remark,
|
||||
// it.Create_by,
|
||||
// it.Create_time
|
||||
// });
|
||||
|
||||
var result = await _sysNoticeService
|
||||
.Insertable(modal)
|
||||
.ExecuteReturnSnowflakeIdAsync();
|
||||
var scheme = HttpContext.Request.Scheme + "://";
|
||||
var serverIP = HttpContext.Request.Host.Value;
|
||||
if (_webHostEnvironment.IsProduction())
|
||||
int result = _SysNoticeService.Insert(modal, it => new
|
||||
{
|
||||
var host = await Dns.GetHostEntryAsync(Dns.GetHostName());
|
||||
var ip = host.AddressList
|
||||
.FirstOrDefault(it => it.AddressFamily == AddressFamily.InterNetwork);
|
||||
serverIP = ip + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
|
||||
}
|
||||
var url = scheme + serverIP;
|
||||
var hubConnection = new HubConnectionBuilder().WithUrl(url + "/msghub").Build();
|
||||
await hubConnection.StartAsync();
|
||||
await hubConnection.InvokeAsync("SendNoticeToOnlineUsers", result, true);
|
||||
await hubConnection.StopAsync();
|
||||
it.NoticeTitle,
|
||||
it.NoticeType,
|
||||
it.NoticeContent,
|
||||
it.Status,
|
||||
it.Remark,
|
||||
it.Create_by,
|
||||
it.Create_time
|
||||
});
|
||||
|
||||
return SUCCESS(result);
|
||||
}
|
||||
|
||||
@@ -129,56 +100,37 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[HttpPut]
|
||||
[ActionPermissionFilter(Permission = "system:notice:update")]
|
||||
[Log(Title = "修改公告", BusinessType = BusinessType.UPDATE)]
|
||||
public async Task<IActionResult> UpdateSysNotice([FromBody] SysNoticeDto parm)
|
||||
public IActionResult UpdateSysNotice([FromBody] SysNoticeDto parm)
|
||||
{
|
||||
var config = new TypeAdapterConfig();
|
||||
config.ForType<SysNoticeDto, SysNotice>()
|
||||
.Map(dest => dest.NoticeId, src => src.NoticeId.ParseToLong());
|
||||
var model = parm.Adapt<SysNotice>(config).ToUpdate(HttpContext);
|
||||
var nowDate = DateTime.Now;
|
||||
var response = _sysNoticeService.Update(w => w.NoticeId == model.NoticeId, it => new SysNotice()
|
||||
var model = parm.Adapt<SysNotice>().ToUpdate(HttpContext);
|
||||
model.Update_by = HttpContext.GetName();
|
||||
var response = _SysNoticeService.Update(w => w.NoticeId == model.NoticeId, it => new SysNotice()
|
||||
{
|
||||
NoticeTitle = model.NoticeTitle,
|
||||
NoticeType = model.NoticeType,
|
||||
NoticeContent = model.NoticeContent,
|
||||
Status = model.Status,
|
||||
Remark = model.Remark,
|
||||
Update_by = HttpContext.GetUId(),
|
||||
Update_name = HttpContext.GetNickName(),
|
||||
Update_time = nowDate,
|
||||
Create_time = nowDate
|
||||
Update_by = HttpContext.GetName(),
|
||||
Update_time = DateTime.Now
|
||||
});
|
||||
|
||||
var scheme = HttpContext.Request.Scheme + "://";
|
||||
var serverIP = HttpContext.Request.Host.Value;
|
||||
if (_webHostEnvironment.IsProduction())
|
||||
{
|
||||
var host = await Dns.GetHostEntryAsync(Dns.GetHostName());
|
||||
var ip = host.AddressList
|
||||
.FirstOrDefault(it => it.AddressFamily == AddressFamily.InterNetwork);
|
||||
serverIP = ip + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
|
||||
}
|
||||
var url = scheme + serverIP;
|
||||
var hubConnection = new HubConnectionBuilder().WithUrl(url + "/msghub").Build();
|
||||
await hubConnection.StartAsync();
|
||||
await hubConnection.InvokeAsync("SendNoticeToOnlineUsers", model.NoticeId, true);
|
||||
await hubConnection.StopAsync();
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
/// <summary>
|
||||
/// 发送通知公告表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPut("send/{noticeId}")]
|
||||
[HttpPut("send/{NoticeId}")]
|
||||
[ActionPermissionFilter(Permission = "system:notice:update")]
|
||||
[Log(Title = "发送通知公告", BusinessType = BusinessType.OTHER)]
|
||||
public IActionResult SendNotice(long noticeId = 0)
|
||||
public IActionResult SendNotice(int NoticeId = 0)
|
||||
{
|
||||
if (noticeId <= 0)
|
||||
if (NoticeId <= 0)
|
||||
{
|
||||
throw new CustomException("请求实体不能为空");
|
||||
}
|
||||
var response = _sysNoticeService.GetFirst(x => x.NoticeId == noticeId);
|
||||
var response = _SysNoticeService.GetFirst(x => x.NoticeId == NoticeId);
|
||||
if (response != null && response.Status == 0)
|
||||
{
|
||||
_hubContext.Clients.All.SendAsync(HubsConstant.ReceiveNotice, response.NoticeTitle, response.NoticeContent);
|
||||
@@ -193,30 +145,13 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
[HttpDelete("{ids}")]
|
||||
[ActionPermissionFilter(Permission = "system:notice:delete")]
|
||||
[Log(Title = "通知公告", BusinessType = BusinessType.DELETE)]
|
||||
public async Task<IActionResult> DeleteSysNotice(string ids)
|
||||
public IActionResult DeleteSysNotice(string ids)
|
||||
{
|
||||
var idsArr = Tools.SpitLongArrary(ids);
|
||||
int[] idsArr = Tools.SpitIntArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
|
||||
var response = _sysNoticeService.Delete(idsArr);
|
||||
await _sysNoticeLogService.Deleteable()
|
||||
.Where(it => idsArr.Contains(it.NoticeId))
|
||||
.ExecuteCommandAsync();
|
||||
|
||||
var scheme = HttpContext.Request.Scheme + "://";
|
||||
var serverIP = HttpContext.Request.Host.Value;
|
||||
if (_webHostEnvironment.IsProduction())
|
||||
{
|
||||
var host = await Dns.GetHostEntryAsync(Dns.GetHostName());
|
||||
var ip = host.AddressList
|
||||
.FirstOrDefault(it => it.AddressFamily == AddressFamily.InterNetwork);
|
||||
serverIP = ip + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
|
||||
}
|
||||
var url = scheme + serverIP;
|
||||
var hubConnection = new HubConnectionBuilder().WithUrl(url + "/msghub").Build();
|
||||
await hubConnection.StartAsync();
|
||||
await hubConnection.InvokeAsync("SendNoticeToOnlineUsers", null, false);
|
||||
await hubConnection.StopAsync();
|
||||
var response = _SysNoticeService.Delete(idsArr);
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ using SqlSugar;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.Model.System;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -21,7 +20,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
private readonly ISysDeptService DeptService;
|
||||
private readonly ISysFileService FileService;
|
||||
private IWebHostEnvironment hostEnvironment;
|
||||
private readonly OptionsSetting _optionsSetting;
|
||||
|
||||
public SysProfileController(
|
||||
ISysUserService userService,
|
||||
@@ -29,8 +27,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
ISysUserPostService postService,
|
||||
ISysDeptService deptService,
|
||||
ISysFileService sysFileService,
|
||||
IWebHostEnvironment hostEnvironment,
|
||||
IOptions<OptionsSetting> options)
|
||||
IWebHostEnvironment hostEnvironment)
|
||||
{
|
||||
UserService = userService;
|
||||
RoleService = roleService;
|
||||
@@ -38,7 +35,6 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
DeptService = deptService;
|
||||
FileService = sysFileService;
|
||||
this.hostEnvironment = hostEnvironment;
|
||||
_optionsSetting = options.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -122,10 +118,8 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
long userId = HttpContext.GetUId();
|
||||
if (formFile == null) throw new CustomException("请选择文件");
|
||||
|
||||
|
||||
var file = await FileService.SaveFileToLocal(hostEnvironment.WebRootPath, "", "avatar",
|
||||
HttpContext.GetUId(), HttpContext.GetName(), formFile, _optionsSetting.Upload.UploadUrl);
|
||||
|
||||
SysFile file = await FileService.SaveFileToLocal(hostEnvironment.WebRootPath, "", "avatar", HttpContext.GetName(), formFile);
|
||||
|
||||
UserService.UpdatePhoto(new SysUser() { Avatar = file.AccessUrl, UserId = userId });
|
||||
return SUCCESS(new { imgUrl = file.AccessUrl });
|
||||
|
||||
@@ -2,10 +2,8 @@
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -72,8 +70,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
return ToResponse(ApiResult.Error((int)ResultCode.CUSTOM_ERROR, $"新增角色'{sysRoleDto.RoleName}'失败,角色权限已存在"));
|
||||
}
|
||||
|
||||
sysRoleDto.Create_by = HttpContext.GetUId();
|
||||
sysRoleDto.Create_name = HttpContext.GetNickName();
|
||||
sysRoleDto.Create_by = HttpContext.GetName();
|
||||
long roleId = sysRoleService.InsertRole(sysRoleDto);
|
||||
|
||||
return ToResponse(roleId);
|
||||
@@ -104,8 +101,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
return ToResponse(ApiResult.Error($"编辑角色'{sysRoleDto.RoleName}'失败,角色权限已存在"));
|
||||
}
|
||||
}
|
||||
sysRoleDto.Update_by = HttpContext.GetUId();
|
||||
sysRoleDto.Update_name = HttpContext.GetNickName();
|
||||
sysRoleDto.Update_by = HttpContext.GetName();
|
||||
int upResult = sysRoleService.UpdateRole(sysRoleDto);
|
||||
if (upResult > 0)
|
||||
{
|
||||
@@ -126,8 +122,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
if (sysRoleDto == null || sysRoleDto.RoleId <= 0) return ToResponse(ApiResult.Error(101, "请求参数错误"));
|
||||
SysRole sysRole = sysRoleDto.Adapt<SysRole>();
|
||||
sysRoleDto.Create_by = HttpContext.GetUId();
|
||||
sysRoleDto.Create_name = HttpContext.GetNickName();
|
||||
sysRoleDto.Create_by = HttpContext.GetName();
|
||||
sysRoleService.CheckRoleAllowed(sysRole);
|
||||
|
||||
bool result = sysRoleService.AuthDataScope(sysRoleDto);
|
||||
@@ -173,7 +168,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <returns></returns>
|
||||
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色导出")]
|
||||
[HttpGet("export")]
|
||||
//[ActionPermissionFilter(Permission = "system:role:export")]
|
||||
[ActionPermissionFilter(Permission = "system:role:export")]
|
||||
public IActionResult Export()
|
||||
{
|
||||
var list = sysRoleService.SelectRoleAll();
|
||||
@@ -189,7 +184,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <returns></returns>
|
||||
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色菜单导出")]
|
||||
[HttpGet("exportRoleMenu")]
|
||||
[AllowAnonymous]
|
||||
[ActionPermissionFilter(Permission = "system:role:export")]
|
||||
public IActionResult ExportRoleMenu(int roleId)
|
||||
{
|
||||
MenuQueryDto dto = new() { Status = "0", MenuTypeIds = "M,C,F" };
|
||||
|
||||
@@ -4,9 +4,7 @@ using SqlSugar;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
@@ -80,22 +78,20 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <summary>
|
||||
/// 添加用户
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("edit")]
|
||||
[HttpPost("add")]
|
||||
[Log(Title = "用户管理", BusinessType = BusinessType.INSERT)]
|
||||
[ActionPermissionFilter(Permission = "system:user:add")]
|
||||
public IActionResult AddUser([FromBody] SysUser user)
|
||||
public IActionResult AddUser([FromBody] SysUserDto parm)
|
||||
{
|
||||
var user = parm.Adapt<SysUser>().ToCreate(HttpContext);
|
||||
if (user == null) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
|
||||
if (UserConstants.NOT_UNIQUE.Equals(UserService.CheckUserNameUnique(user.UserName)))
|
||||
{
|
||||
return ToResponse(ApiResult.Error($"新增用户 '{user.UserName}'失败,登录账号已存在"));
|
||||
}
|
||||
|
||||
user.Create_by = HttpContext.GetUId();
|
||||
user.Create_name = HttpContext.GetNickName();
|
||||
user.Create_time = DateTime.Now;
|
||||
user.Password = NETCore.Encrypt.EncryptProvider.Md5(user.Password);
|
||||
|
||||
return SUCCESS(UserService.InsertUser(user));
|
||||
@@ -104,17 +100,16 @@ namespace ZR.Admin.WebApi.Controllers.System
|
||||
/// <summary>
|
||||
/// 修改用户
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("edit")]
|
||||
[Log(Title = "用户管理", BusinessType = BusinessType.UPDATE)]
|
||||
[ActionPermissionFilter(Permission = "system:user:edit")]
|
||||
public IActionResult UpdateUser([FromBody] SysUser user)
|
||||
public IActionResult UpdateUser([FromBody] SysUserDto parm)
|
||||
{
|
||||
var user = parm.Adapt<SysUser>().ToUpdate(HttpContext);
|
||||
if (user == null || user.UserId <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
|
||||
|
||||
user.Update_by = HttpContext.GetUId();
|
||||
user.Update_name = HttpContext.GetNickName();
|
||||
int upResult = UserService.UpdateUser(user);
|
||||
|
||||
return ToResponse(upResult);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
|
||||
@@ -3,9 +3,8 @@ using Quartz;
|
||||
using SqlSugar;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
using ZR.Tasks;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
@@ -88,8 +87,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
}
|
||||
//从 Dto 映射到 实体
|
||||
var tasksQz = parm.Adapt<SysTasks>().ToCreate(HttpContext);
|
||||
tasksQz.Create_by = HttpContext.GetUId();
|
||||
tasksQz.Create_name = HttpContext.GetNickName();
|
||||
tasksQz.Create_by = HttpContext.GetName();
|
||||
tasksQz.ID = SnowFlakeSingle.Instance.NextId().ToString();
|
||||
|
||||
return SUCCESS(_tasksQzService.AddTasks(tasksQz));
|
||||
@@ -128,8 +126,7 @@ namespace ZR.Admin.WebApi.Controllers
|
||||
throw new CustomException($"该任务正在运行中,请先停止在更新");
|
||||
}
|
||||
var model = parm.Adapt<SysTasks>();
|
||||
model.Update_by = HttpContext.GetUId();
|
||||
model.Update_name = HttpContext.GetNickName();
|
||||
model.Update_by = HttpContextExtension.GetName(HttpContext);
|
||||
int response = _tasksQzService.UpdateTasks(model);
|
||||
if (response > 0)
|
||||
{
|
||||
|
||||
@@ -3,9 +3,8 @@ using SqlSugar;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System
|
||||
{
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
using AspNetCoreRateLimit;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using IpRateLimitPolicy = ZR.ServiceCore.Model.IpRateLimitPolicy;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.System.monitor;
|
||||
|
||||
[Verify]
|
||||
[Route("ip/route/limit")]
|
||||
public class IpRateLimitController : BaseController
|
||||
{
|
||||
private readonly IpRateLimitOptions _options;
|
||||
private readonly IIpPolicyStore _ipPolicyStore;
|
||||
private readonly IIpRateLimitPolicyService _ipRateLimitPolicyService;
|
||||
private readonly IRateLimitRuleService _rateLimitRuleService;
|
||||
private readonly IIpRateLimitLogService _ipRateLimitLogService;
|
||||
|
||||
public IpRateLimitController(IOptions<IpRateLimitOptions> optionsAccessor, IIpPolicyStore ipPolicyStore,
|
||||
IIpRateLimitPolicyService ipRateLimitPolicyService, IRateLimitRuleService rateLimitRuleService,
|
||||
IIpRateLimitLogService ipRateLimitLogService)
|
||||
{
|
||||
_options = optionsAccessor.Value;
|
||||
_ipPolicyStore = ipPolicyStore;
|
||||
_ipRateLimitPolicyService = ipRateLimitPolicyService;
|
||||
_rateLimitRuleService = rateLimitRuleService;
|
||||
_ipRateLimitLogService = ipRateLimitLogService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取限制规则
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("getIpRateLimitPolicyPage")]
|
||||
public async Task<IActionResult> GetIpRateLimitPolicyPage([FromQuery] IpRateLimitPolicy ipRateLimitPolicy,
|
||||
PagerInfo pager)
|
||||
{
|
||||
var page = await _ipRateLimitPolicyService.SelectIpRateLimitPolicyPageAsync(ipRateLimitPolicy, pager);
|
||||
return SUCCESS(page);
|
||||
}
|
||||
|
||||
[HttpPost("addIpRateLimitPolicy")]
|
||||
public async Task<IActionResult> AddIpRateLimitPolicy([FromBody] IpRateLimitPolicy ipRateLimitPolicy)
|
||||
{
|
||||
var isExist = await _ipRateLimitPolicyService.Queryable()
|
||||
.Where(it => it.Ip == ipRateLimitPolicy.Ip)
|
||||
.AnyAsync();
|
||||
if (isExist) throw new CustomException("该IP已存在");
|
||||
var res = await _ipRateLimitPolicyService.InsertNav(ipRateLimitPolicy)
|
||||
.Include(it => it.Rules)
|
||||
.ExecuteCommandAsync();
|
||||
return SUCCESS(res);
|
||||
}
|
||||
|
||||
[HttpPut("updateIpRateLimitPolicy")]
|
||||
public async Task<IActionResult> UpdateIpRateLimitPolicy(
|
||||
[FromBody] IpRateLimitPolicy ipRateLimitPolicy)
|
||||
{
|
||||
var isEnable = await _ipRateLimitPolicyService
|
||||
.Queryable()
|
||||
.Where(it => it.Id == ipRateLimitPolicy.Id
|
||||
&& it.Flag == '1')
|
||||
.AnyAsync();
|
||||
var res = await _ipRateLimitPolicyService.UpdateNav(ipRateLimitPolicy)
|
||||
.Include(it => it.Rules)
|
||||
.ExecuteCommandAsync();
|
||||
if (!isEnable) return SUCCESS(res);
|
||||
{
|
||||
await _ipPolicyStore.RemoveAsync(_options.IpPolicyPrefix);
|
||||
var ipRateLimitPolicies = _ipRateLimitPolicyService.Queryable()
|
||||
.Includes(it => it.Rules.Where(r => r.Flag == '1').ToList())
|
||||
.Where(it => it.Flag == '1')
|
||||
.ToListAsync()
|
||||
.GetAwaiter().GetResult()
|
||||
.Adapt<List<AspNetCoreRateLimit.IpRateLimitPolicy>>();
|
||||
await _ipPolicyStore.SeedAsync();
|
||||
var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
|
||||
pol.IpRules.AddRange(ipRateLimitPolicies);
|
||||
await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol);
|
||||
}
|
||||
return SUCCESS(res);
|
||||
}
|
||||
|
||||
[HttpPatch("enableIpRateLimitPolicy/{id}")]
|
||||
public async Task<IActionResult> EnableIpRateLimitPolicy([FromRoute] long id)
|
||||
{
|
||||
var isEnable = await _ipRateLimitPolicyService
|
||||
.Queryable()
|
||||
.Where(it => it.Id == id
|
||||
&& it.Flag == '1')
|
||||
.AnyAsync();
|
||||
if (isEnable)
|
||||
{
|
||||
throw new CustomException("已启用,无法再次启用");
|
||||
}
|
||||
await _ipRateLimitPolicyService.Updateable(new IpRateLimitPolicy
|
||||
{
|
||||
Id = id,
|
||||
Flag = '1'
|
||||
}).UpdateColumns(it => it.Flag)
|
||||
.ExecuteCommandAsync();
|
||||
var ipRateLimitPolicy = await _ipRateLimitPolicyService.Queryable()
|
||||
.Includes(it => it.Rules.Where(r => r.Flag == '1').ToList())
|
||||
.Where(it => it.Id == id)
|
||||
.SingleAsync();
|
||||
var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
|
||||
pol.IpRules.Add(ipRateLimitPolicy.Adapt<AspNetCoreRateLimit.IpRateLimitPolicy>());
|
||||
await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol);
|
||||
return SUCCESS('1');
|
||||
}
|
||||
|
||||
[HttpPatch("disableIpRateLimitPolicy/{id}")]
|
||||
public async Task<IActionResult> DisableIpRateLimitPolicy([FromRoute] long id)
|
||||
{
|
||||
var isEnable = await _ipRateLimitPolicyService
|
||||
.Queryable()
|
||||
.Where(it => it.Id == id
|
||||
&& it.Flag == '1')
|
||||
.AnyAsync();
|
||||
if (!isEnable)
|
||||
{
|
||||
throw new CustomException("已禁用,无法再次禁用");
|
||||
}
|
||||
await _ipRateLimitPolicyService.Updateable(new IpRateLimitPolicy
|
||||
{
|
||||
Id = id,
|
||||
Flag = '0'
|
||||
}).UpdateColumns(it => it.Flag)
|
||||
.ExecuteCommandAsync();
|
||||
var ipRateLimitPolicies = _ipRateLimitPolicyService.Queryable()
|
||||
.Includes(it => it.Rules.Where(r => r.Flag == '1').ToList())
|
||||
.Where(it => it.Flag == '1')
|
||||
.ToListAsync()
|
||||
.GetAwaiter().GetResult()
|
||||
.Adapt<List<AspNetCoreRateLimit.IpRateLimitPolicy>>();
|
||||
await _ipPolicyStore.RemoveAsync(_options.IpPolicyPrefix);
|
||||
await _ipPolicyStore.SeedAsync();
|
||||
var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
|
||||
pol.IpRules.AddRange(ipRateLimitPolicies);
|
||||
await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol);
|
||||
return SUCCESS('0');
|
||||
}
|
||||
|
||||
[HttpDelete("deleteIpRateLimitPolicy/{id}")]
|
||||
public async Task DeleteIpRateLimitPolicyAsync([FromRoute] long id)
|
||||
{
|
||||
var isEnable = await _ipRateLimitPolicyService
|
||||
.Queryable()
|
||||
.Where(it => it.Id == id
|
||||
&& it.Flag == '1')
|
||||
.AnyAsync();
|
||||
await _ipRateLimitPolicyService
|
||||
.DeleteNav(it => it.Id == id)
|
||||
.Include(it => it.Rules)
|
||||
.ExecuteCommandAsync();
|
||||
if (isEnable)
|
||||
{
|
||||
var ipRateLimitPolicies = _ipRateLimitPolicyService.Queryable()
|
||||
.Includes(it => it.Rules.Where(r => r.Flag == '1').ToList())
|
||||
.Where(it => it.Flag == '1')
|
||||
.ToListAsync()
|
||||
.GetAwaiter().GetResult()
|
||||
.Adapt<List<AspNetCoreRateLimit.IpRateLimitPolicy>>();
|
||||
await _ipPolicyStore.RemoveAsync(_options.IpPolicyPrefix);
|
||||
await _ipPolicyStore.SeedAsync();
|
||||
var pol = await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
|
||||
pol.IpRules.AddRange(ipRateLimitPolicies);
|
||||
await _ipPolicyStore.SetAsync(_options.IpPolicyPrefix, pol);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("getIpRateLimitLogPage")]
|
||||
public async Task<IActionResult> GetIpRateLimitLogPage([FromQuery] IpRateLimitLog ipRateLimitLog, PagerInfo pager)
|
||||
{
|
||||
return SUCCESS(await _ipRateLimitLogService.SelectIpRateLimitLogPageAsync(ipRateLimitLog, pager));
|
||||
}
|
||||
|
||||
[HttpGet("get")]
|
||||
public async Task<IpRateLimitPolicies> Get()
|
||||
{
|
||||
return await _ipPolicyStore.GetAsync(_options.IpPolicyPrefix);
|
||||
}
|
||||
|
||||
[HttpGet("checkIp/{ip}")]
|
||||
public async Task<IActionResult> CheckIp(string ip)
|
||||
{
|
||||
var res = await _ipRateLimitPolicyService.Queryable()
|
||||
.Where(it => it.Ip == ip)
|
||||
.AnyAsync();
|
||||
return SUCCESS(res);
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,8 @@ using Infrastructure.Extensions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
{
|
||||
@@ -12,6 +11,7 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
/// 系统监控
|
||||
/// </summary>
|
||||
[ApiExplorerSettings(GroupName = "sys")]
|
||||
[Verify]
|
||||
public class MonitorController : BaseController
|
||||
{
|
||||
private OptionsSetting Options;
|
||||
@@ -50,12 +50,8 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
string appRAM = ((double)Process.GetCurrentProcess().WorkingSet64 / 1048576).ToString("N2") + " MB";
|
||||
string startTime = Process.GetCurrentProcess().StartTime.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
string sysRunTime = ComputerHelper.GetRunTime();
|
||||
// string serverIP = Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
|
||||
var host = Dns.GetHostEntry(Dns.GetHostName());
|
||||
var ip = host.AddressList
|
||||
.FirstOrDefault(it => it.AddressFamily == AddressFamily.InterNetwork);
|
||||
var serverIP = ip + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
|
||||
|
||||
string serverIP = Request.HttpContext.Connection.LocalIpAddress.MapToIPv4().ToString() + ":" + Request.HttpContext.Connection.LocalPort;//获取服务器IP
|
||||
|
||||
var programStartTime = Process.GetCurrentProcess().StartTime;
|
||||
string programRunTime = DateTimeHelper.FormatTime((DateTime.Now - programStartTime).TotalMilliseconds.ToString().Split('.')[0].ParseToLong());
|
||||
var data = new
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model.Dto;
|
||||
using ZR.ServiceCore.Services;
|
||||
|
||||
//创建时间:2023-11-19
|
||||
namespace ZR.Admin.WebApi.Controllers.System.monitor
|
||||
{
|
||||
/// <summary>
|
||||
/// 短信验证码记录
|
||||
/// </summary>
|
||||
[Verify]
|
||||
[Route("system/SmscodeLog")]
|
||||
[ApiExplorerSettings(GroupName = "sys")]
|
||||
public class SmsCodeLogController : BaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// 短信验证码记录接口
|
||||
/// </summary>
|
||||
private readonly ISmsCodeLogService _SmscodeLogService;
|
||||
|
||||
public SmsCodeLogController(ISmsCodeLogService SmscodeLogService)
|
||||
{
|
||||
_SmscodeLogService = SmscodeLogService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询短信验证码记录列表
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("list")]
|
||||
[ActionPermissionFilter(Permission = "smscodelog:list")]
|
||||
public IActionResult QuerySmscodeLog([FromQuery] SmscodeLogQueryDto parm)
|
||||
{
|
||||
var response = _SmscodeLogService.GetList(parm);
|
||||
return SUCCESS(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除短信验证码记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{ids}")]
|
||||
[ActionPermissionFilter(Permission = "smscodelog:delete")]
|
||||
[Log(Title = "短信验证码记录", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult DeleteSmscodeLog(string ids)
|
||||
{
|
||||
long[] idsArr = Tools.SpitLongArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
|
||||
var response = _SmscodeLogService.Delete(idsArr);
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出短信验证码记录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Log(Title = "短信验证码记录", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
|
||||
[HttpGet("export")]
|
||||
[ActionPermissionFilter(Permission = "smscodelog:export")]
|
||||
public IActionResult Export([FromQuery] SmscodeLogQueryDto parm)
|
||||
{
|
||||
parm.PageNum = 1;
|
||||
parm.PageSize = 100000;
|
||||
var list = _SmscodeLogService.GetList(parm).Result;
|
||||
if (list == null || list.Count <= 0)
|
||||
{
|
||||
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
|
||||
}
|
||||
var result = ExportExcelMini(list, "短信验证码记录", "短信验证码记录");
|
||||
return ExportExcel(result.Item2, result.Item1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
//创建时间:2023-08-17
|
||||
namespace ZR.Admin.WebApi.Controllers
|
||||
|
||||
@@ -4,8 +4,7 @@ using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.Model.System;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
{
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Service.System.IService;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
{
|
||||
@@ -15,12 +14,10 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
public class SysOperlogController : BaseController
|
||||
{
|
||||
private ISysOperLogService sysOperLogService;
|
||||
private IWebHostEnvironment WebHostEnvironment;
|
||||
|
||||
public SysOperlogController(ISysOperLogService sysOperLogService, IWebHostEnvironment hostEnvironment)
|
||||
public SysOperlogController(ISysOperLogService sysOperLogService)
|
||||
{
|
||||
this.sysOperLogService = sysOperLogService;
|
||||
WebHostEnvironment = hostEnvironment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using ZR.Admin.WebApi.Filters;
|
||||
using ZR.Model;
|
||||
using ZR.ServiceCore.Model.Dto;
|
||||
using ZR.Model.System.Dto;
|
||||
using ZR.ServiceCore.Signalr;
|
||||
|
||||
namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
@@ -30,11 +30,11 @@ namespace ZR.Admin.WebApi.Controllers.monitor
|
||||
[HttpGet("list")]
|
||||
public IActionResult Index([FromQuery] PagerInfo parm)
|
||||
{
|
||||
var result = MessageHub.OnlineClients
|
||||
var result = MessageHub.onlineClients
|
||||
.OrderByDescending(f => f.LoginTime)
|
||||
.Skip(parm.PageNum - 1).Take(parm.PageSize);
|
||||
|
||||
return SUCCESS(new { result, totalNum = MessageHub.OnlineClients.Count });
|
||||
return SUCCESS(new { result, totalNum = MessageHub.onlineClients.Count });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+19
-32
@@ -1,34 +1,21 @@
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 8888
|
||||
#EXPOSE 443
|
||||
VOLUME /app/adminlogs
|
||||
VOLUME /app/wwwroot
|
||||
|
||||
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
||||
WORKDIR /src
|
||||
COPY ["ZR.Admin.WebApi/ZR.Admin.WebApi.csproj", "ZR.Admin.WebApi/"]
|
||||
COPY ["ZR.CodeGenerator/ZR.CodeGenerator.csproj", "ZR.CodeGenerator/"]
|
||||
COPY ["Infrastructure/ZR.Infrastructure.csproj", "Infrastructure/"]
|
||||
COPY ["ZR.Common/ZR.Common.csproj", "ZR.Common/"]
|
||||
COPY ["ZR.ServiceCore/ZR.ServiceCore.csproj", "ZR.ServiceCore/"]
|
||||
COPY ["ZR.Repository/ZR.Repository.csproj", "ZR.Repository/"]
|
||||
COPY ["ZR.Model/ZR.Model.csproj", "ZR.Model/"]
|
||||
COPY ["ZR.Service/ZR.Service.csproj", "ZR.Service/"]
|
||||
COPY ["ZR.Tasks/ZR.Tasks.csproj", "ZR.Tasks/"]
|
||||
COPY ["ZR.Admin.Grpc/ZR.Admin.Grpc.csproj", "ZR.Admin.Grpc/"]
|
||||
RUN dotnet restore "ZR.Admin.WebApi/ZR.Admin.WebApi.csproj"
|
||||
COPY . .
|
||||
WORKDIR "/src/ZR.Admin.WebApi"
|
||||
RUN dotnet build "ZR.Admin.WebApi.csproj" -c Release -o /app/build
|
||||
|
||||
FROM build AS publish
|
||||
RUN dotnet publish "ZR.Admin.WebApi.csproj" -c Release -o /app/publish /p:UseAppHost=false
|
||||
|
||||
FROM base AS final
|
||||
#创建 /app文件夹
|
||||
WORKDIR /app
|
||||
COPY --from=publish /app/publish .
|
||||
ENTRYPOINT ["dotnet", "ZR.Admin.WebApi.dll"]
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
RUN apt-get update && apt-get install -y libfontconfig1
|
||||
#创建挂载目录,用于将程序部署在服务器本地
|
||||
#VOLUME /app
|
||||
#设置docker容器对外暴露端口
|
||||
EXPOSE 8888
|
||||
VOLUME /app/logs
|
||||
#COPY bin/Release/net5.0/publish/ app/
|
||||
COPY . app/
|
||||
|
||||
#设置容器内的时区,如果不设置,默认时区是标准时间比北京时间晚8个小时
|
||||
RUN echo "Asia/shanghai" > /etc/timezone
|
||||
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
# 复制发布文件到工作目录
|
||||
#COPY . app/
|
||||
WORKDIR /app
|
||||
|
||||
#等价于 dotnet ZR.Admin.WebApi.dll,如果不指定启动端口默认在docker里面启动端口是80端口
|
||||
ENTRYPOINT ["dotnet", "ZR.Admin.WebApi.dll", "--server.urls","http://*:8888"]
|
||||
@@ -1,7 +1,7 @@
|
||||
using Quartz.Spi;
|
||||
using SqlSugar;
|
||||
using SqlSugar.IOC;
|
||||
using ZR.Model.System;
|
||||
using ZR.ServiceCore.Model;
|
||||
using ZR.Tasks;
|
||||
|
||||
namespace ZR.Admin.WebApi.Extensions
|
||||
@@ -50,5 +50,29 @@ namespace ZR.Admin.WebApi.Extensions
|
||||
return app;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化字典
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseInit(this IApplicationBuilder app)
|
||||
{
|
||||
Console.WriteLine("初始化字典数据...");
|
||||
var db = DbScoped.SugarScope;
|
||||
var types = db.Queryable<SysDictType>()
|
||||
.Where(it => it.Status == "0")
|
||||
.Select(it => it.DictType)
|
||||
.ToList();
|
||||
|
||||
//上面有耗时操作写在Any上面,保证程序启动后只执行一次
|
||||
if (!db.ConfigQuery.Any())
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
db.ConfigQuery.SetTable<SysDictData>(it => SqlFunc.ToString(it.DictValue), it => it.DictLabel, type, it => it.DictType == type);
|
||||
}
|
||||
}
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,4 +8,4 @@ global using Mapster;
|
||||
global using Infrastructure.Extensions;
|
||||
global using Infrastructure.Controllers;
|
||||
global using ZR.ServiceCore.Middleware;
|
||||
global using Microsoft.AspNetCore.Mvc;
|
||||
global using ZR.ServiceCore.Services;
|
||||
+16
-43
@@ -1,11 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
|
||||
autoReload="true"
|
||||
internalLogLevel="Info"
|
||||
internalLogFile="nlog-internal.log"
|
||||
throwConfigExceptions="true">
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
|
||||
autoReload="true"
|
||||
internalLogLevel="Info"
|
||||
internalLogFile="nlog-internal.log">
|
||||
|
||||
<!--Nlog 文档参考地址:https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-2-->
|
||||
<!--internalLogLevel Nlog内部日志记录为Off关闭。除非纠错,不可以设为Trace否则速度很慢,起码Debug以上-->
|
||||
@@ -46,14 +45,14 @@
|
||||
|
||||
<!--SQL文件-->
|
||||
<target name="sqlfile" xsi:type="File"
|
||||
fileName="${basedir}/adminlogs/sql.txt"
|
||||
archiveFileName="${basedir}/adminlogs/bak/sql/sql.{###}.txt"
|
||||
archiveEvery="Day"
|
||||
archiveNumbering="DateAndSequence"
|
||||
archiveAboveSize="20000000"
|
||||
maxArchiveFiles="30"
|
||||
keepFileOpen="false"
|
||||
layout="${longdate} | ${uppercase:${level}} | ${aspnet-request-iP} | ${aspnet-request-headers:HeaderNames=userName} | ${aspnet-request-url} ${newline}${message}"/>
|
||||
fileName="${basedir}/adminlogs/sql.txt"
|
||||
archiveFileName="${basedir}/adminlogs/bak/sql/sql{###}.txt"
|
||||
archiveEvery="Day"
|
||||
archiveNumbering="DateAndSequence"
|
||||
archiveAboveSize="20000000"
|
||||
maxArchiveFiles="30"
|
||||
keepFileOpen="false"
|
||||
layout="${longdate} | ${uppercase:${level}} | ${aspnet-request-iP} | ${aspnet-request-headers:HeaderNames=userName} | ${aspnet-request-url} ${newline}${message}"/>
|
||||
|
||||
<!--写入彩色控制台-->
|
||||
<target name="consoleSql" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
|
||||
@@ -68,34 +67,8 @@
|
||||
<highlight-word regex="】" foregroundColor="Blue" />
|
||||
</target>
|
||||
|
||||
<!--日志打印到控制台-->
|
||||
<target name="console" xsi:type="ColoredConsole"
|
||||
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-url} ${newline} ${message}">
|
||||
<highlight-row condition="level == LogLevel.Debug" foregroundColor="DarkGray" />
|
||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Gray" />
|
||||
<highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
|
||||
<highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
|
||||
<highlight-row condition="level == LogLevel.Fatal" foregroundColor="Red" backgroundColor="White" />
|
||||
</target>
|
||||
|
||||
<!--写入黑洞-->
|
||||
<target name="blackhole" xsi:type="Null" />
|
||||
|
||||
<target name="ipRateLimitFile" xsi:type="File"
|
||||
fileName="${basedir}/adminlogs/ipratelimit.txt"
|
||||
archiveFileName="${basedir}/adminlogs/bak/ipratelimit/ipratelimit{###}.txt"
|
||||
archiveEvery="Day"
|
||||
archiveNumbering="DateAndSequence"
|
||||
archiveAboveSize="20000000"
|
||||
maxArchiveFiles="30"
|
||||
keepFileOpen="false"
|
||||
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-url} ${newline} ${message}"
|
||||
/>
|
||||
<!-- 速率限制日志写入控制台 -->
|
||||
<target name="consoleIpRateLimit" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="false"
|
||||
layout="${date:format=MM-dd HH\:mm\:ss} | ${aspnet-request-url} ${newline} ${message}">
|
||||
<highlight-row condition="level == LogLevel.Info" foregroundColor="Blue" />
|
||||
</target>
|
||||
</targets>
|
||||
|
||||
<rules>
|
||||
@@ -106,10 +79,10 @@
|
||||
<!--<logger name="System.*" writeTo="blackhole" final="true" />-->
|
||||
<!-- Quartz -->
|
||||
<logger name="Quartz*" minlevel="Trace" maxlevel="Info" final="true" />
|
||||
<logger name="*.SqlSugar.SqlSugarSetup" final="true" writeTo="consoleSql,sqlfile"/>
|
||||
<logger name="*" minLevel="Trace" writeTo="allfile,console" />
|
||||
<logger name="*.SqlSugar.SqlsugarSetup" final="true" writeTo="consoleSql,sqlfile"/>
|
||||
<logger name="*" minLevel="Trace" writeTo="allfile" />
|
||||
<logger name="*.GlobalExceptionMiddleware" final="true" writeTo="consoleSql,errorfile"/>
|
||||
<logger name="ZR.Admin.WebApi.Middleware.CustomIpRateLimitMiddleware" final="true" writeTo="consoleIpRateLimit,ipRateLimitFile" />
|
||||
|
||||
<!--Skip non-critical Microsoft logs and so log only own logs-->
|
||||
<logger name="Microsoft.*,Quartz.Core.QuartzSchedulerThread" maxlevel="Info" final="true" />
|
||||
</rules>
|
||||
|
||||
+17
-83
@@ -1,31 +1,16 @@
|
||||
using AspNetCoreRateLimit;
|
||||
using Infrastructure.Converter;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.RateLimiting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using Microsoft.Extensions.Caching.Redis;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NLog.Web;
|
||||
using SqlSugar;
|
||||
using System.Text.Json;
|
||||
using ZR.Admin.Grpc;
|
||||
using ZR.Admin.Grpc.Services;
|
||||
using ZR.Admin.WebApi.Extensions;
|
||||
using ZR.Infrastructure.Cache;
|
||||
using ZR.Common.Cache;
|
||||
using ZR.Infrastructure.WebExtensions;
|
||||
using ZR.ServiceCore.Services.IService;
|
||||
using ZR.ServiceCore.Signalr;
|
||||
using ZR.ServiceCore.SqlSugar;
|
||||
using IpRateLimitPolicy = AspNetCoreRateLimit.IpRateLimitPolicy;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
//load json config by ipRateLimit
|
||||
builder.Configuration.AddJsonFile("IpRateLimitConfig.json", true, true);
|
||||
|
||||
//load json config by loginVerify
|
||||
builder.Configuration.AddJsonFile("loginVerifyConf.json", true, true);
|
||||
|
||||
// NLog: Setup NLog for Dependency injection
|
||||
//builder.Logging.ClearProviders();
|
||||
builder.Host.UseNLog();
|
||||
@@ -39,8 +24,6 @@ builder.Services.AddSwaggerGen();
|
||||
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
// 跨域配置
|
||||
builder.Services.AddCors(builder.Configuration);
|
||||
// Grpc
|
||||
builder.Services.AddGrpc();
|
||||
// 显示logo
|
||||
builder.Services.AddLogo();
|
||||
//消除Error unprotecting the session cookie警告
|
||||
@@ -54,7 +37,8 @@ builder.Services.AddIPRate(builder.Configuration);
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
//绑定整个对象到Model上
|
||||
builder.Services.Configure<OptionsSetting>(builder.Configuration);
|
||||
|
||||
builder.Configuration.AddJsonFile("codeGen.json");
|
||||
builder.Configuration.AddJsonFile("iprate.json");
|
||||
//jwt 认证
|
||||
builder.Services.AddJwt();
|
||||
//配置文件
|
||||
@@ -63,21 +47,16 @@ builder.Services.AddSingleton(new AppSettings(builder.Configuration));
|
||||
builder.Services.AddAppService();
|
||||
//开启计划任务
|
||||
builder.Services.AddTaskSchedulers();
|
||||
//请求大小限制
|
||||
builder.Services.AddRequestLimit(builder.Configuration);
|
||||
|
||||
//注册REDIS 服务
|
||||
var openRedis = builder.Configuration["RedisServer:open"];
|
||||
if (openRedis == "1")
|
||||
{
|
||||
RedisServer.Initalize();
|
||||
builder.Services.AddSingleton<IDistributedCache>(new CSRedisCache(RedisHelper.Instance));
|
||||
}
|
||||
|
||||
builder.Services.AddRateLimiter(o => o
|
||||
.AddFixedWindowLimiter(policyName: "fixed", options =>
|
||||
{
|
||||
// configuration
|
||||
}));
|
||||
|
||||
builder.Services.AddMvc(options =>
|
||||
{
|
||||
options.Filters.Add(typeof(GlobalActionMonitor));//全局注册
|
||||
@@ -100,26 +79,6 @@ builder.Services.AddSignalR()
|
||||
options.PayloadSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||
});
|
||||
builder.Services.AddSwaggerConfig();
|
||||
//using var channel = GrpcChannel.ForAddress("https://localhost:7025");
|
||||
//var client = new Greeter.GreeterClient(channel);
|
||||
//var reply = await client.SayHelloAsync(new HelloRequest { Name = "GreeterClient" });
|
||||
//Console.WriteLine("Greeting: " + reply.Message);
|
||||
//
|
||||
// var blockClient = new Block.BlockClient(channel);
|
||||
// var blockReply = await blockClient.GetBlockAsync(new BlockRequest { In = "asads" });
|
||||
// Console.WriteLine("BlockReply: " + blockReply.Out);
|
||||
//builder.Services.AddGrpcServiceConfiguration(builder.Configuration);
|
||||
|
||||
// 配置 Kestrel 监听 HTTP/2 的非加密流量
|
||||
//builder.WebHost.ConfigureKestrel(options =>
|
||||
//{
|
||||
// // 如果你只想监听一个端口,只保留其中一个 Listen
|
||||
// options.ListenLocalhost(8888, o =>
|
||||
// {
|
||||
// o.Protocols = HttpProtocols.Http2; // 明确设置为 Http2
|
||||
// });
|
||||
|
||||
//});
|
||||
|
||||
var app = builder.Build();
|
||||
InternalApp.ServiceProvider = app.Services;
|
||||
@@ -127,7 +86,12 @@ InternalApp.Configuration = builder.Configuration;
|
||||
InternalApp.WebHostEnvironment = app.Environment;
|
||||
//初始化db
|
||||
builder.Services.AddDb(app.Environment);
|
||||
|
||||
var workId = builder.Configuration["workId"].ParseToInt();
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
workId += 1;
|
||||
}
|
||||
SnowFlakeSingle.WorkId = workId;
|
||||
//使用全局异常中间件
|
||||
app.UseMiddleware<GlobalExceptionMiddleware>();
|
||||
|
||||
@@ -153,7 +117,7 @@ app.UseStaticFiles();
|
||||
//开启路由访问
|
||||
app.UseRouting();
|
||||
app.UseCors("Policy");//要放在app.UseEndpoints前。
|
||||
app.UseHttpsRedirection();
|
||||
//app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
@@ -165,11 +129,13 @@ if (builder.Environment.IsProduction())
|
||||
//恢复/启动任务
|
||||
app.UseAddTaskSchedulers();
|
||||
}
|
||||
//初始化字典数据
|
||||
app.UseInit();
|
||||
|
||||
//使用swagger
|
||||
app.UseSwagger();
|
||||
//启用客户端IP限制速率
|
||||
// app.UseIpRateLimiting();
|
||||
app.UseMiddleware<CustomIpRateLimitMiddleware>();
|
||||
app.UseIpRateLimiting();
|
||||
app.UseRateLimiter();
|
||||
//设置socket连接
|
||||
app.MapHub<MessageHub>("/msgHub");
|
||||
@@ -179,36 +145,4 @@ app.MapControllerRoute(
|
||||
pattern: "{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
using (var serviceScope = app.Services.CreateScope())
|
||||
{
|
||||
var services = serviceScope.ServiceProvider;
|
||||
|
||||
// get the IpPolicyStore instance
|
||||
var ipPolicyStore = services.GetRequiredService<IIpPolicyStore>();
|
||||
|
||||
// seed IP data from appsettings
|
||||
ipPolicyStore.SeedAsync().GetAwaiter().GetResult();
|
||||
|
||||
var optionsAccessor = services.GetRequiredService<IOptions<IpRateLimitOptions>>();
|
||||
var ipRateLimitPolicyService = services.GetRequiredService<IIpRateLimitPolicyService>();
|
||||
var ipRateLimitPolicies = ipRateLimitPolicyService.Queryable()
|
||||
.Includes(it => it.Rules.Where(r => r.Flag == '1').ToList())
|
||||
.Where(it => it.Flag == '1')
|
||||
.ToListAsync().GetAwaiter().GetResult();
|
||||
var pol = await ipPolicyStore.GetAsync(optionsAccessor.Value.IpPolicyPrefix);
|
||||
pol.IpRules.AddRange(ipRateLimitPolicies.Adapt<List<IpRateLimitPolicy>>());
|
||||
await ipPolicyStore.SetAsync(optionsAccessor.Value.IpPolicyPrefix, pol);
|
||||
|
||||
//var greeterClient = services.GetRequiredService<Greeter.GreeterClient>();
|
||||
//var helloReply = await greeterClient.SayHelloAsync(new HelloRequest
|
||||
//{
|
||||
// Name = "gree"
|
||||
//});
|
||||
//Console.WriteLine(helloReply);
|
||||
}
|
||||
|
||||
app.MapGrpcService<GreeterService>();
|
||||
app.MapGrpcService<MyDiaryService>();
|
||||
|
||||
app.Run();
|
||||
@@ -10,13 +10,13 @@
|
||||
},
|
||||
"profiles": {
|
||||
"ZR.Admin.WebApi": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchUrl": "",
|
||||
"applicationUrl": "https://localhost:8888",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchUrl": "",
|
||||
"applicationUrl": "http://localhost:8888",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,26 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<NoWarn>1701;1702;1591,8603,8602,8604,8600,8618</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\ZR.Admin.Grpc\ZR.Admin.Grpc.csproj" />
|
||||
<ProjectReference Include="..\ZR.CodeGenerator\ZR.CodeGenerator.csproj" />
|
||||
<ProjectReference Include="..\ZR.Service\ZR.Service.csproj" />
|
||||
<ProjectReference Include="..\ZR.Tasks\ZR.Tasks.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.3" />
|
||||
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.7" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.3" />
|
||||
<PackageReference Include="Mapster" Version="7.3.0" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.5" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.12" />
|
||||
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" />
|
||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
||||
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -30,9 +28,6 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\.dockerignore">
|
||||
<Link>.dockerignore</Link>
|
||||
</Content>
|
||||
<None Update="ip2region.db">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
@@ -42,8 +37,5 @@
|
||||
<Content Update="wwwroot\export\**\*">
|
||||
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
|
||||
</Content>
|
||||
<Content Update="appsettings.Production.json">
|
||||
<DependentUpon>appsettings.json</DependentUpon>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"urls": "http://[*]:8888", //项目启动url,如果改动端口前端对应devServer也需要进行修改
|
||||
"dbConfigs": [
|
||||
{
|
||||
"Conn": "server=8.140.174.251;user=admin;pwd=admin123;database=ZrAdmin",
|
||||
"DbType": 0, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
"ConfigId": "0", //多租户唯一标识
|
||||
"IsAutoCloseConnection": true
|
||||
}
|
||||
//...下面添加更多的数据库源
|
||||
],
|
||||
//redis服务配置
|
||||
"RedisServer": {
|
||||
"open": 1, //是否启用redis
|
||||
"Cache": "8.140.174.251:6379,password=Wyd210213,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
|
||||
// "Cache": "127.0.0.1:6379,password=Wyd210213,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
|
||||
"Session": "8.140.174.251:6379,password=Wyd210213,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
|
||||
// "Session": "127.0.0.1:6379,password=Wyd210213,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
|
||||
},
|
||||
}
|
||||
+104
-123
@@ -1,126 +1,107 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"dbConfigs": [
|
||||
{
|
||||
"Conn": "server=127.0.0.1;user=admin;pwd=admin123;database=ZrAdmin;port=3306",
|
||||
"DbType": 0, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
"ConfigId": "0", //多租户唯一标识
|
||||
"IsAutoCloseConnection": true
|
||||
}
|
||||
//...下面添加更多的数据库源
|
||||
],
|
||||
//代码生成数据库配置
|
||||
"CodeGenDbConfig": {
|
||||
//代码生成连接字符串,注意{dbName}为固定格式,不要填写数据库名
|
||||
"Conn": "Data Source=127.0.0.1;user=admin;pwd=admin123;database=ZrAdmin;port=3306",
|
||||
"DbType": 0,
|
||||
"IsAutoCloseConnection": true,
|
||||
"DbName": "ZrAdmin" //代码生成默认连接数据库,Oracle库是实例的名称
|
||||
},
|
||||
"urls": "https://localhost:8888", //项目启动url,如果改动端口前端对应devServer也需要进行修改
|
||||
"corsUrls": [ "http://localhost:8887", "http://localhost:8886" ], //跨域地址(前端启动项目,前后端分离单独部署需要设置),多个用","隔开
|
||||
"JwtSettings": {
|
||||
"Issuer": "ZRAdmin.NET", //即token的签发者。
|
||||
"Audience": "ZRAdmin.NET", //指该token是服务于哪个群体的(群体范围)
|
||||
"SecretKey": "SecretKey-ZRADMIN.NET-20210101",
|
||||
"Expire": 1440, //jwt登录过期时间(分)
|
||||
"RefreshTokenTime": 5, //分钟
|
||||
"TokenType": "Bearer"
|
||||
},
|
||||
"InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks", "ZR.ServiceCore" ], //自动注入类
|
||||
"ShowDbLog": true, //是否打印db日志
|
||||
"InitDb": false, //是否初始化db
|
||||
"DemoMode": false, //是否演示模式
|
||||
"SingleLogin": false, //是否单点登录
|
||||
"Upload": {
|
||||
"uploadUrl": "http://localhost:8888", //本地存储资源访问路径
|
||||
"localSavePath": "", //本地上传默认文件存储目录 wwwroot
|
||||
"maxSize": 15, //上传文件大小限制 15M
|
||||
"notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ]
|
||||
},
|
||||
//阿里云存储配置
|
||||
"ALIYUN_OSS": {
|
||||
"REGIONID": "oss-cn-hangzhou.aliyuncs.com", //eg:cn-hangzhou
|
||||
"KEY": "LTAI5tBjDZatWWunAhxLAAFR",
|
||||
"SECRET": "Klcm77KdpkIROAl2ffPemK5I1yDshM",
|
||||
"bucketName": "markdownhexo",
|
||||
"domainUrl": "https://markdownhexo.oss-cn-hangzhou.aliyuncs.com", //访问资源域名
|
||||
"maxSize": 1000 //上传文件大小限制 1000M
|
||||
},
|
||||
//企业微信通知配置
|
||||
"WxCorp": {
|
||||
"AgentID": "",
|
||||
"CorpID": "",
|
||||
"CorpSecret": "",
|
||||
"SendUser": "@all"
|
||||
},
|
||||
//微信公众号设置
|
||||
"WxOpen": {
|
||||
"AppID": "",
|
||||
"AppSecret": ""
|
||||
},
|
||||
//代码生成配置
|
||||
"gen": {
|
||||
//是否显示移动端代码生成
|
||||
"showApp": false,
|
||||
//自动去除表前缀
|
||||
"autoPre": true,
|
||||
"author": "admin",
|
||||
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
|
||||
"vuePath": "", //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
|
||||
"csharpTypeArr": {
|
||||
"string": [ "varchar", "nvarchar", "text", "longtext" ],
|
||||
"int": [ "int", "integer", "smallint", "int4", "int8", "int2" ],
|
||||
"long": [ "bigint", "number" ],
|
||||
"float": [ "numeric", "real", "float" ],
|
||||
"decimal": [ "money", "decimal", "smallmoney" ],
|
||||
"dateTime": [ "date", "datetime", "datetime2", "smalldatetime", "timestamp" ],
|
||||
"byte": [ "tinyint" ],
|
||||
"bool": [ "bit" ]
|
||||
}
|
||||
},
|
||||
//邮箱配置信息
|
||||
"MailOptions": {
|
||||
//发件人名称
|
||||
"FromName": "文永达",
|
||||
//发送人邮箱
|
||||
"FromEmail": "1224169330@qq.com", //eg:xxxx@qq.com
|
||||
//发送人邮箱密码
|
||||
"Password": "wbctsfvdazchibdh",
|
||||
//协议
|
||||
"Smtp": "smtp.qq.com",
|
||||
"Port": 465,
|
||||
"Signature": "系统邮件,请勿回复!",
|
||||
"UseSsl": true
|
||||
},
|
||||
//redis服务配置
|
||||
"RedisServer": {
|
||||
"open": 1, //是否启用redis
|
||||
"Cache": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
|
||||
"Session": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
|
||||
},
|
||||
//验证码配置
|
||||
"CaptchaOptions": {
|
||||
"CaptchaType": 10,
|
||||
"IgnoreCase": true, // 比较时是否忽略大小写
|
||||
"ImageOption": {
|
||||
"FontSize": 36, // 字体大小
|
||||
"Animation": true, // 是否启用动画
|
||||
"TextBold": true, // 是否启用粗体
|
||||
"InterferenceLineCount": 4, // 干扰线数量
|
||||
"BubbleMinRadius": 5, // 气泡最小半径
|
||||
"BubbleMaxRadius": 10, // 气泡最大半径
|
||||
"BubbleCount": 3, // 气泡数量
|
||||
"BubbleThickness": 1.0 // 气泡边沿厚度
|
||||
}
|
||||
},
|
||||
"GrpcUrls": {
|
||||
"FindTeacher": "http://localhost:5212"
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"dbConfigs": [
|
||||
{
|
||||
"Conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog=ZrAdmin;",
|
||||
"DbType": 1, //数据库类型 MySql = 0, SqlServer = 1, Oracle = 3,PgSql = 4
|
||||
"ConfigId": "0", //多租户唯一标识
|
||||
"IsAutoCloseConnection": true
|
||||
}
|
||||
//...下面添加更多的数据库源
|
||||
],
|
||||
//代码生成数据库配置
|
||||
"CodeGenDbConfig": {
|
||||
//代码生成连接字符串,注意{dbName}为固定格式,不要填写数据库名
|
||||
"Conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog={dbName};",
|
||||
"DbType": 1,
|
||||
"IsAutoCloseConnection": true,
|
||||
"DbName": "ZrAdmin" //代码生成默认连接数据库,Oracle库是实例的名称
|
||||
},
|
||||
"urls": "http://localhost:8888", //项目启动url,如果改动端口前端对应devServer也需要进行修改
|
||||
"corsUrls": [ "http://localhost:8887", "http://localhost:8886" ], //跨域地址(前端启动项目,前后端分离单独部署需要设置),多个用","隔开
|
||||
"JwtSettings": {
|
||||
"Issuer": "ZRAdmin.NET", //即token的签发者。
|
||||
"Audience": "ZRAdmin.NET", //指该token是服务于哪个群体的(群体范围)
|
||||
"SecretKey": "SecretKey-ZRADMIN.NET-20210101",
|
||||
"Expire": 1440, //jwt登录过期时间(分)
|
||||
"RefreshTokenTime": 30, //分钟
|
||||
"TokenType": "Bearer"
|
||||
},
|
||||
"InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks", "ZR.ServiceCore" ], //自动注入类
|
||||
"ShowDbLog": true, //是否打印db日志
|
||||
"InitDb": false, //是否初始化db
|
||||
"DemoMode": false, //是否演示模式
|
||||
"SingleLogin": false, //是否允许多设备/浏览器登录
|
||||
"workId": 1, //雪花id唯一数字
|
||||
"sqlExecutionTime": 5, //Sql执行时间超过多少秒记录日志并警报
|
||||
"Upload": {
|
||||
"uploadUrl": "http://localhost:8888", //本地存储资源访问路径
|
||||
"localSavePath": "", //本地上传默认文件存储目录 wwwroot
|
||||
"maxSize": 15, //上传文件大小限制 15M
|
||||
"notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ],
|
||||
"requestLimitSize": 50//请求body大小限制
|
||||
},
|
||||
//阿里云存储配置
|
||||
"ALIYUN_OSS": {
|
||||
"REGIONID": "", //eg:cn-hangzhou
|
||||
"KEY": "XX",
|
||||
"SECRET": "XX",
|
||||
"bucketName": "bucketName",
|
||||
"domainUrl": "http://xxx.xxx.com", //访问资源域名
|
||||
"maxSize": 100 //上传文件大小限制 100M
|
||||
},
|
||||
//企业微信通知配置
|
||||
"WxCorp": {
|
||||
"AgentID": "",
|
||||
"CorpID": "",
|
||||
"CorpSecret": "",
|
||||
"SendUser": "@all"
|
||||
},
|
||||
//微信公众号设置
|
||||
"WxOpen": {
|
||||
"AppID": "",
|
||||
"AppSecret": ""
|
||||
},
|
||||
//邮箱配置信息
|
||||
"MailOptions": {
|
||||
//发件人名称
|
||||
"FromName": "system",
|
||||
//发送人邮箱
|
||||
"FromEmail": "", //eg:xxxx@qq.com
|
||||
//发送人邮箱密码
|
||||
"Password": "",
|
||||
//协议
|
||||
"Smtp": "smtp.qq.com",
|
||||
"Port": 587,
|
||||
"Signature": "系统邮件,请勿回复!",
|
||||
"UseSsl": true
|
||||
},
|
||||
//redis服务配置
|
||||
"RedisServer": {
|
||||
"open": 0, //是否启用redis
|
||||
"Cache": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
|
||||
"Session": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
|
||||
},
|
||||
//验证码配置
|
||||
"CaptchaOptions": {
|
||||
"IgnoreCase": true // 比较时是否忽略大小写
|
||||
},
|
||||
//代码生成配置
|
||||
"CodeGen": {
|
||||
//是否显示移动端代码生成
|
||||
"showApp": false,
|
||||
//自动去除表前缀
|
||||
"autoPre": true,
|
||||
//默认生成业务模块名
|
||||
"moduleName": "business",
|
||||
"author": "admin",
|
||||
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
|
||||
"vuePath": "" //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"CodeGen": {
|
||||
"csharpTypeArr": {
|
||||
"string": [ "varchar", "nvarchar", "text", "longtext" ],
|
||||
"int": [ "int", "integer", "smallint", "int4", "int8", "int2" ],
|
||||
"long": [ "bigint", "number" ],
|
||||
"float": [ "numeric", "real", "float" ],
|
||||
"decimal": [ "money", "decimal", "smallmoney" ],
|
||||
"dateTime": [ "date", "datetime", "datetime2", "smalldatetime", "timestamp" ],
|
||||
"byte": [ "tinyint" ],
|
||||
"bool": [ "bit" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,19 +6,12 @@
|
||||
"RealIpHeader": "X-Real-IP",
|
||||
"ClientIdHeader": "X-ClientId",
|
||||
"HttpStatusCode": 429,
|
||||
"EndpointWhitelist": [
|
||||
"post:/system/dict/data/types",
|
||||
"*:/msghub/negotiate",
|
||||
"*:/LogOut",
|
||||
"*:/common/uploadfile",
|
||||
"post:/aim/msg/list/sendmsg"
|
||||
],
|
||||
"EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
|
||||
"QuotaExceededResponse": {
|
||||
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
|
||||
"ContentType": "application/json",
|
||||
"StatusCode": 429
|
||||
},
|
||||
// "IpWhitelist": [ "127.0.0.1", "::1/10", "192.168.0.0/24" ],
|
||||
//通用规则,api规则,结尾一定要带*
|
||||
"GeneralRules": [
|
||||
{
|
||||
@@ -31,17 +24,7 @@
|
||||
"Endpoint": "((post)|(put)):*",
|
||||
"Period": "3s",
|
||||
"Limit": 1
|
||||
},
|
||||
{
|
||||
"Endpoint": "*:/aim/msg/list/SendMsg",
|
||||
"Period": "1s",
|
||||
"Limit": 0,
|
||||
}
|
||||
]
|
||||
},
|
||||
"IpRateLimitPolicies": {
|
||||
//ip规则
|
||||
"IpRules": [
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"RSA": {
|
||||
"PrivatePem": "-----BEGIN PRIVATE KEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCjvJHH6V8fHL9zuVkW1mcDcYF5D72fEG45xLP8jyXR0/klmxZUT6My2ajGcWtOAKyca4Mcw2lKV7FRzchVyylsLi1JaH+vgbL0qwjDS0hjSm6Uqw39WFX//t1qMxX8OD5F3lvAYaNauVY6nYQ9VgEcjrq5nc+kRB7cVsR1ouQlFMQ1vLCAZwajW2pSmpjkEMYC70iJfBl7iF0za6eIVLZEpxgOi8KIkTWUDvLLH0cRR30+FgyE8wu8gh09ZbYarGyLchmAbbmERHT6jfMgKCob/ZVuh0EzrklMsFj4qdjofejzRvS/arA4HtOS1W1ZBHovPxR36quWB4DO9lvkWakNAgMBAAECggEADiLHizTQq4T12m3UDS6xchColuUO/96RRZd/2nwZTcY5Kk/7W4gMlOVJtugv1WolfNOjXCZavrpXarKTayTBDL/n1QCalXJjGtBxTzr+ouPYLCmgaZDoy9MbFoIWkdHhPnL2BOPpEHoTwbe7pPf53JdN85x2Qr5G08sB5w4LGFBRPAkOoD2LgW4QK7Ut5k4GAHmcn7nqHlkMM8ksdNGkQEhSHfoQOh7FFgR1GHJMeO0JgXprJCIFjyhtyzzDj47r02LWqEaaTdokvkYPEqyzjSI/Gufvq6nvgIlf2mU9KA2NC3VwJrXtAQQezy7yB6blvBceygwXChVKAuUtEyOf2QKBgQDaKC76PlG+p61DIwfIJIcP6JgzWVXj7gJr82hpu8NIf0Wz354eYRl1gdW6dkgpkPhnDvZ/b23P5FsWG8OR0f0VMgPvKVDo+Z+cHLsoroqeCw7B1MEdv2d69gbAk343BTVkTui94152GeCu3O/C0QmaZyqOtumEbxDl8K+lsusEkwKBgQDAI7XzXx+EqKD1m2DKnj2YILEplB4pmJnTWaZi5qAKO+XxbUTGcSxRALBYxuMEvd2AIEk9VhQiLpJ9DoOzVg5LY/zeRvK1vE2tUj/cx8X8jekdY7QayP6KigWbe3juqBHm9eD97wwmQgbFRg+ZZrpKhENym4BVqCuJwc7nC02/3wKBgFIvCyuIqKDraBE/tCHI6PysQhIuGHZKZq0mQHJ8op/AGpEdr+J/7+hdphedkaffDkU81M3DO5oyy8GzaeSYOABxHBxP80QhLejQxg0YW+4X+lI5BRtgzOn8nySTK9wsYSXNuE44xpA1RXh6kPRSbYy2SskCzUvvz2zgVDtXAMRzAoGABItTrFPdnPeYBvcLzP79GfH7/q3AIN+5E6SVKNWnh1ZvU8xvyfm3QJsxkIfzqpMLABLDaK32f/B2CnsjZkRsxh+xRViMOPwhIi5F0GTxK833a3iGM/P5ATHOfCTpcUuMUNgT4C2dLfJ10oibqdciJM0IA1fmKyB1Fyb8S76asiUCgYEAu6ZQ5BfxtbhZCjZ7/hYKHuzDjRzyiaBkKjtN5ZvqLgkG6Zdfjrm2/RcFCMVtqZKXcgVcD9yxy561fmS+5gE3yTfKiFcYoYITT/N26MJ5G7Qeb/FPpmDRVQGjCaAw0o8dvaqe3pUEROdYX+JVQMxQ4WOPiV45FXazAZtFNr8Z+xA=-----END PRIVATE KEY-----"
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<location path="." inheritInChildApplications="false">
|
||||
<system.webServer>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="dotnet" arguments=".\ZR.Admin.WebApi.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess" />
|
||||
</system.webServer>
|
||||
</location>
|
||||
<system.webServer>
|
||||
<security>
|
||||
<requestFiltering>
|
||||
<requestLimits maxQueryString="2097151" maxAllowedContentLength="1073741824" />
|
||||
</requestFiltering>
|
||||
</security>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
@@ -80,7 +80,7 @@ $if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
|
||||
*/
|
||||
export function del${genTable.BusinessName}(pid) {
|
||||
return request({
|
||||
url: '${genTable.ModuleName}/${genTable.BusinessName}/' + pid,
|
||||
url: '${genTable.ModuleName}/${genTable.BusinessName}/delete/' + pid,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
你在期待什么...
|
||||
@@ -56,7 +56,7 @@ $if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
|
||||
*/
|
||||
export function del${genTable.BusinessName}(pid) {
|
||||
return request({
|
||||
url: '/${genTable.ModuleName}/${genTable.BusinessName}/' + pid,
|
||||
url: '/${genTable.ModuleName}/${genTable.BusinessName}/delete/' + pid,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
@@ -73,6 +73,6 @@ $end
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
// 导出${genTable.functionName}
|
||||
export async function export${genTable.BusinessName}(query) {
|
||||
await downFile('$/{genTable.ModuleName}/${genTable.BusinessName}/export', { ...query })
|
||||
await downFile('/${genTable.ModuleName}/${genTable.BusinessName}/export', { ...query })
|
||||
}
|
||||
$end
|
||||
@@ -12,7 +12,7 @@ $if(column.CsharpType == "int" || column.CsharpType == "long")
|
||||
$end
|
||||
|
||||
$if(column.IsPK || column.IsIncrement)
|
||||
$if(column.IsPK && column.IsIncrement == false)
|
||||
$if(column.IsPK && column.IsIncrement == false && replaceDto.useSnowflakeId == false)
|
||||
<u-form-item label="${labelName}" prop="${columnName}">
|
||||
<u--input type="number" v-model.number="form.${columnName}" placeholder="请输入${labelName}" :disabled="opertype != 1"></u--input>
|
||||
</u-form-item>
|
||||
@@ -83,7 +83,6 @@ $end
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import "@/static/scss/page.scss";
|
||||
import {
|
||||
get${genTable.BusinessName},
|
||||
$if(replaceDto.ShowBtnAdd)
|
||||
@@ -92,15 +91,9 @@ $end
|
||||
$if(replaceDto.ShowBtnEdit)
|
||||
update${genTable.BusinessName},
|
||||
$end
|
||||
}
|
||||
from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
|
||||
} from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
|
||||
|
||||
export default {
|
||||
$if(replaceDto.UploadFile == 1)
|
||||
components: {
|
||||
UploadImage
|
||||
},
|
||||
$end
|
||||
dicts: [
|
||||
$foreach(item in genTable.Columns)
|
||||
$if((item.HtmlType == "radio" || item.HtmlType.Contains("select") || item.HtmlType == "checkbox") && item.DictType != "")
|
||||
@@ -110,7 +103,15 @@ $end
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
form: {
|
||||
$foreach(item in genTable.Columns)
|
||||
$if(item.HtmlType == "checkbox")
|
||||
${item.CsharpFieldFl}Checked: [],
|
||||
$else
|
||||
$item.CsharpFieldFl: undefined,
|
||||
$end
|
||||
$end
|
||||
},
|
||||
rules: {
|
||||
$foreach(column in genTable.Columns)
|
||||
$if(column.IsRequired && column.IsIncrement == false)
|
||||
@@ -202,7 +203,8 @@ $end
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style lang="scss" scoped>
|
||||
@import "@/static/scss/page.scss";
|
||||
.btn-wrap {
|
||||
margin: 150rpx auto 0 auto;
|
||||
width: 80%
|
||||
|
||||
@@ -134,14 +134,12 @@ $end
|
||||
import {
|
||||
checkPermi
|
||||
} from '@/utils/permission.js'
|
||||
import "@/static/scss/page.scss";
|
||||
import {
|
||||
import {
|
||||
list${genTable.BusinessName},
|
||||
$if(replaceDto.ShowBtnDelete)
|
||||
del${genTable.BusinessName},
|
||||
$end
|
||||
}
|
||||
from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
|
||||
} from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
|
||||
|
||||
import {
|
||||
getDate
|
||||
@@ -285,4 +283,8 @@ $end
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/static/scss/page.scss";
|
||||
</style>
|
||||
+12
-15
@@ -66,7 +66,7 @@ $end
|
||||
{
|
||||
var response = _${replaceDto.ModelTypeName}Service.GetInfo(${replaceDto.PKName});
|
||||
|
||||
var info = response.Adapt<${replaceDto.ModelTypeName}>();
|
||||
var info = response.Adapt<${replaceDto.ModelTypeName}Dto>();
|
||||
return SUCCESS(info);
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ $if(replaceDto.ShowBtnAdd)
|
||||
|
||||
return SUCCESS(response);
|
||||
}
|
||||
$end
|
||||
|
||||
$end
|
||||
$if(replaceDto.ShowBtnEdit)
|
||||
/// <summary>
|
||||
/// 更新${genTable.FunctionName}
|
||||
@@ -103,27 +103,24 @@ $if(replaceDto.ShowBtnEdit)
|
||||
|
||||
return ToResponse(response);
|
||||
}
|
||||
$end
|
||||
|
||||
$end
|
||||
$if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
|
||||
/// <summary>
|
||||
/// 删除${genTable.FunctionName}
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{ids}")]
|
||||
[HttpDelete("delete/{ids}")]
|
||||
[ActionPermissionFilter(Permission = "${replaceDto.PermissionPrefix}:delete")]
|
||||
[Log(Title = "${genTable.FunctionName}", BusinessType = BusinessType.DELETE)]
|
||||
public IActionResult Delete${replaceDto.ModelTypeName}(string ids)
|
||||
public IActionResult Delete${replaceDto.ModelTypeName}([FromRoute]string ids)
|
||||
{
|
||||
int[] idsArr = Tools.SpitIntArrary(ids);
|
||||
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
|
||||
var idArr = Tools.SplitAndConvert<${replaceDto.PKType}>(ids);
|
||||
|
||||
var response = _${replaceDto.ModelTypeName}Service.Delete(idsArr);
|
||||
|
||||
return ToResponse(response);
|
||||
return ToResponse(_${replaceDto.ModelTypeName}Service.Delete(idArr$if(replaceDto.enableLog), "删除${genTable.FunctionName}"$end));
|
||||
}
|
||||
$end
|
||||
|
||||
$end
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
/// <summary>
|
||||
/// 导出${genTable.FunctionName}
|
||||
@@ -136,7 +133,7 @@ $if(replaceDto.ShowBtnExport)
|
||||
{
|
||||
parm.PageNum = 1;
|
||||
parm.PageSize = 100000;
|
||||
var list = _${replaceDto.ModelTypeName}Service.GetList(parm).Result;
|
||||
var list = _${replaceDto.ModelTypeName}Service.ExportList(parm).Result;
|
||||
if (list == null || list.Count <= 0)
|
||||
{
|
||||
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
|
||||
@@ -144,8 +141,8 @@ $if(replaceDto.ShowBtnExport)
|
||||
var result = ExportExcelMini(list, "${genTable.FunctionName}", "${genTable.FunctionName}");
|
||||
return ExportExcel(result.Item2, result.Item1);
|
||||
}
|
||||
$end
|
||||
|
||||
$end
|
||||
$if(replaceDto.ShowBtnTruncate)
|
||||
/// <summary>
|
||||
/// 清空${genTable.FunctionName}
|
||||
@@ -162,8 +159,8 @@ $if(replaceDto.ShowBtnTruncate)
|
||||
}
|
||||
return SUCCESS(_${replaceDto.ModelTypeName}Service.Truncate${replaceDto.ModelTypeName}());
|
||||
}
|
||||
$end
|
||||
|
||||
$end
|
||||
$if(replaceDto.ShowBtnImport)
|
||||
/// <summary>
|
||||
/// 导入
|
||||
@@ -196,8 +193,8 @@ $if(replaceDto.ShowBtnImport)
|
||||
var result = DownloadImportTemplate(new List<${replaceDto.ModelTypeName}Dto>() { }, "${replaceDto.ModelTypeName}");
|
||||
return ExportExcel(result.Item2, result.Item1);
|
||||
}
|
||||
$end
|
||||
|
||||
$end
|
||||
$if(showCustomInput)
|
||||
/// <summary>
|
||||
/// 保存排序
|
||||
+15
-7
@@ -1,7 +1,3 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
using MiniExcelLibs.Attributes;
|
||||
$end
|
||||
$if(null != genTable.SubTableName && "" != genTable.SubTableName)
|
||||
using ${subTableOptions.ModelsNamespace}.${subTableOptions.SubNamespace};
|
||||
$end
|
||||
@@ -33,18 +29,24 @@ $end
|
||||
public class ${replaceDto.ModelTypeName}Dto
|
||||
{
|
||||
$foreach(item in genTable.Columns)
|
||||
$set(labelName = "")
|
||||
$if(item.ColumnComment != "")
|
||||
$set(labelName = item.ColumnComment)
|
||||
$else
|
||||
$set(labelName = item.CsharpField)
|
||||
$end
|
||||
$if(item.IsRequired)
|
||||
[Required(ErrorMessage = "${item.ColumnComment}不能为空")]
|
||||
$end
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
$if(item.IsExport)
|
||||
[ExcelColumn(Name = "$if(item.ColumnComment == "")${item.CsharpField}${else}${item.ColumnComment}${end}"$if(item.CsharpType == "DateTime"), Format = "yyyy-MM-dd HH:mm:ss"$end)]
|
||||
[ExcelColumnName("$if(item.ColumnComment == "")${item.CsharpField}${else}${item.ColumnComment}${end}")]
|
||||
[ExcelColumn(Name = "$labelName"$if(item.CsharpType == "DateTime"), Format = "yyyy-MM-dd HH:mm:ss", Width = 20$end)]
|
||||
[ExcelColumnName("$labelName")]
|
||||
$else
|
||||
[ExcelIgnore]
|
||||
$end
|
||||
$end
|
||||
$if(item.CsharpType == "long")
|
||||
$if(item.CsharpType == "long" && replaceDto.useSnowflakeId == true && item.IsPk)
|
||||
[JsonConverter(typeof(ValueToStringConverter))]
|
||||
$end
|
||||
public $item.CsharpType$item.RequiredStr $item.CsharpField { get; set; }
|
||||
@@ -63,6 +65,12 @@ $if(replaceDto.ShowBtnExport)
|
||||
[ExcelIgnore]
|
||||
$end
|
||||
public List<${genTable.SubTable.ClassName}Dto> ${genTable.SubTable.ClassName}Nav { get; set; }
|
||||
$end
|
||||
$foreach(column in dicts)
|
||||
$if(column.IsExport)
|
||||
[ExcelColumn(Name = "$if(column.ColumnComment == "")${column.CsharpField}${else}${column.ColumnComment}${end}")]
|
||||
public string ${column.CsharpField}Label { get; set; }
|
||||
$end
|
||||
$end
|
||||
}
|
||||
}
|
||||
+6
-3
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using ${options.BaseNamespace}Model;
|
||||
using ${options.BaseNamespace}Model;
|
||||
using ${options.DtosNamespace};
|
||||
using ${options.ModelsNamespace}.${options.SubNamespace};
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNamespace}Service
|
||||
{
|
||||
@@ -18,6 +16,7 @@ namespace ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNam
|
||||
$if(genTable.TplCategory == "tree")
|
||||
List<${replaceDto.ModelTypeName}> GetTreeList(${replaceDto.ModelTypeName}QueryDto parm);
|
||||
$end
|
||||
|
||||
${replaceDto.ModelTypeName} Add${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm);
|
||||
|
||||
int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm);
|
||||
@@ -28,5 +27,9 @@ $end
|
||||
$if(replaceDto.ShowBtnImport)
|
||||
(string, object, object) Import${replaceDto.ModelTypeName}(List<${replaceDto.ModelTypeName}> list);
|
||||
$end
|
||||
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
PagedInfo<${replaceDto.ModelTypeName}Dto> ExportList(${replaceDto.ModelTypeName}QueryDto parm);
|
||||
$end
|
||||
}
|
||||
}
|
||||
+67
-35
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using SqlSugar;
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Attribute;
|
||||
using Infrastructure.Extensions;
|
||||
using ${options.BaseNamespace}Model;
|
||||
using ${options.DtosNamespace};
|
||||
@@ -27,28 +25,8 @@ namespace ${options.ServicesNamespace}.${options.SubNamespace}
|
||||
/// <returns></returns>
|
||||
public PagedInfo<${replaceDto.ModelTypeName}Dto> GetList(${replaceDto.ModelTypeName}QueryDto parm)
|
||||
{
|
||||
var predicate = Expressionable.Create<${replaceDto.ModelTypeName}>();
|
||||
var predicate = QueryExp(parm);
|
||||
|
||||
$foreach(column in genTable.Columns)
|
||||
$if(column.IsQuery)
|
||||
$if(column.HtmlType == "selectMulti")
|
||||
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => parm.${column.CsharpField}.Contains(it.${column.CsharpField}));
|
||||
$elseif(column.CsharpType == "string")
|
||||
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.${column.CsharpField}), ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
|
||||
$elseif(column.CsharpType == "DateTime")
|
||||
$if(column.HtmlType == "month")
|
||||
DateTime monthEnd = Convert.ToDateTime(parm.${column.CsharpField}).AddMonths(1);
|
||||
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.${column.CsharpField} && it.${column.CsharpField} < monthEnd);
|
||||
$else
|
||||
predicate = predicate.AndIF(parm.Begin${column.CsharpField} == null, it => it.${column.CsharpField} >= DateTime.Now.ToShortDateString().ParseToDateTime());
|
||||
predicate = predicate.AndIF(parm.Begin${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.Begin${column.CsharpField});
|
||||
predicate = predicate.AndIF(parm.End${column.CsharpField} != null, it => it.${column.CsharpField} <= parm.End${column.CsharpField});
|
||||
$end
|
||||
$elseif(column.CsharpType == "int" || column.CsharpType == "long")
|
||||
predicate = predicate.AndIF(parm.${column.CsharpField} != null, ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
|
||||
$end
|
||||
$end
|
||||
$end
|
||||
var response = Queryable()
|
||||
$if(null != genTable.SubTableName && "" != genTable.SubTableName)
|
||||
//.Includes(x => x.${genTable.SubTable.ClassName}Nav) //填充子对象
|
||||
@@ -117,7 +95,12 @@ $end
|
||||
$if(null != genTable.SubTableName && "" != genTable.SubTableName)
|
||||
return Context.InsertNav(model).Include(s1 => s1.${genTable.SubTable.ClassName}Nav).ExecuteReturnEntity();
|
||||
$else
|
||||
return Context.Insertable(model).ExecuteReturnEntity();
|
||||
$if(replaceDto.useSnowflakeId)
|
||||
Insertable(model).ExecuteReturnSnowflakeId();
|
||||
return model;
|
||||
$else
|
||||
return Insertable(model).ExecuteReturnEntity();
|
||||
$end
|
||||
$end
|
||||
}
|
||||
|
||||
@@ -128,19 +111,10 @@ $end
|
||||
/// <returns></returns>
|
||||
public int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} model)
|
||||
{
|
||||
//var response = Update(w => w.${replaceDto.PKName} == model.${replaceDto.PKName}, it => new ${replaceDto.ModelTypeName}()
|
||||
//{
|
||||
$foreach(item in genTable.Columns)
|
||||
$if((item.IsEdit))
|
||||
// $item.CsharpField = model.$item.CsharpField,
|
||||
$end
|
||||
${end}
|
||||
//});
|
||||
//return response;
|
||||
$if(null != genTable.SubTableName && "" != genTable.SubTableName)
|
||||
return Context.UpdateNav(model).Include(z1 => z1.${genTable.SubTable.ClassName}Nav).ExecuteCommand() ? 1 : 0;
|
||||
$else
|
||||
return Update(model, true);
|
||||
return Update(model, true$if(replaceDto.enableLog), "修改${genTable.FunctionName}"$end);
|
||||
$end
|
||||
}
|
||||
$if(replaceDto.ShowBtnTruncate)
|
||||
@@ -194,5 +168,63 @@ $end
|
||||
return (msg, x.ErrorList, x.IgnoreList);
|
||||
}
|
||||
$end
|
||||
|
||||
$if(replaceDto.ShowBtnExport)
|
||||
/// <summary>
|
||||
/// 导出${genTable.FunctionName}
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
public PagedInfo<${replaceDto.ModelTypeName}Dto> ExportList(${replaceDto.ModelTypeName}QueryDto parm)
|
||||
{
|
||||
var predicate = QueryExp(parm);
|
||||
|
||||
var response = Queryable()
|
||||
.Where(predicate.ToExpression())
|
||||
.Select((it) => new ${replaceDto.ModelTypeName}Dto()
|
||||
{
|
||||
$foreach(column in dicts)
|
||||
$if(column.DictType != "")
|
||||
${column.CsharpField}Label = it.${column.CsharpField}.GetConfigValue<Model.System.SysDictData>("${column.DictType}"),
|
||||
$end
|
||||
$end
|
||||
}, true)
|
||||
.ToPage(parm);
|
||||
|
||||
return response;
|
||||
}
|
||||
$end
|
||||
|
||||
/// <summary>
|
||||
/// 查询导出表达式
|
||||
/// </summary>
|
||||
/// <param name="parm"></param>
|
||||
/// <returns></returns>
|
||||
private static Expressionable<${replaceDto.ModelTypeName}> QueryExp(${replaceDto.ModelTypeName}QueryDto parm)
|
||||
{
|
||||
var predicate = Expressionable.Create<${replaceDto.ModelTypeName}>();
|
||||
|
||||
$foreach(column in genTable.Columns)
|
||||
$if(column.IsQuery)
|
||||
$if(column.HtmlType == "selectMulti")
|
||||
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => parm.${column.CsharpField}.Contains(it.${column.CsharpField}));
|
||||
$elseif(column.CsharpType == "string")
|
||||
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.${column.CsharpField}), ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
|
||||
$elseif(column.CsharpType == "DateTime")
|
||||
$if(column.HtmlType == "month")
|
||||
DateTime monthEnd = Convert.ToDateTime(parm.${column.CsharpField}).AddMonths(1);
|
||||
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.${column.CsharpField} && it.${column.CsharpField} < monthEnd);
|
||||
$else
|
||||
predicate = predicate.AndIF(parm.Begin${column.CsharpField} == null, it => it.${column.CsharpField} >= DateTime.Now.ToShortDateString().ParseToDateTime());
|
||||
predicate = predicate.AndIF(parm.Begin${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.Begin${column.CsharpField});
|
||||
predicate = predicate.AndIF(parm.End${column.CsharpField} != null, it => it.${column.CsharpField} <= parm.End${column.CsharpField});
|
||||
$end
|
||||
$elseif(column.CsharpType == "int" || column.CsharpType == "long")
|
||||
predicate = predicate.AndIF(parm.${column.CsharpField} != null, ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
|
||||
$end
|
||||
$end
|
||||
$end
|
||||
return predicate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ $end
|
||||
|
||||
$* 一对一/一对多列表显示详情 *$
|
||||
$if(sub)
|
||||
<el-drawer v-model="drawer" :with-header="false" direction="btt">
|
||||
<el-drawer v-model="drawer" size="50%" direction="rtl">
|
||||
<el-table :data="$tool.FirstLowerCase(genTable.SubTable.ClassName)List" header-row-class-name="text-navy">
|
||||
<el-table-column label="序号" type="index" width="80" />
|
||||
$foreach(column in genSubTable.Columns)
|
||||
@@ -267,7 +267,7 @@ $if(column.CsharpType == "int" || column.CsharpType == "long")
|
||||
$end
|
||||
|
||||
$if(column.IsPK || column.IsIncrement)
|
||||
$if(column.IsPK && column.IsIncrement == false)
|
||||
$if(column.IsPK && column.IsIncrement == false && replaceDto.useSnowflakeId == false)
|
||||
<el-col :lg="${options.ColNum}">
|
||||
<el-form-item label="${labelName}" prop="${columnName}">
|
||||
<el-input v-model${number}="form.${columnName}" placeholder="请输入${labelName}" :disabled="opertype != 1"/>
|
||||
@@ -392,7 +392,7 @@ $if(sub)
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table :data="${tool.FirstLowerCase(genTable.SubTable.ClassName)}List" :row-class-name="row${genTable.SubTable.ClassName}Index" @selection-change="handle${genTable.SubTable.ClassName}SelectionChange" ref="${genTable.SubTable.ClassName}Ref">
|
||||
<el-table-column type="selection" width="50" align="center" />
|
||||
<el-table-column type="selection" width="40" align="center" />
|
||||
<el-table-column label="序号" align="center" prop="index" width="50"/>
|
||||
$foreach(column in genTable.SubTable.Columns)
|
||||
$set(labelName = column.ColumnComment)
|
||||
@@ -435,6 +435,12 @@ $elseif(column.HtmlType == "switch")
|
||||
<el-switch v-model="scope.row.${columnName}" ${switchType} />
|
||||
</template>
|
||||
</el-table-column>
|
||||
$elseif(column.HtmlType == "imageUpload")
|
||||
<el-table-column label="${labelName}" prop="${columnName}">
|
||||
<template #default="scope">
|
||||
<UploadImage v-model="form.${columnName}" :isShowTip="false" :style="{ 'width': '50px' }" :data="{ uploadType: 1 }" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
$else
|
||||
<el-table-column label="${labelName}" align="center" prop="${columnName}">
|
||||
<template #default="scope">
|
||||
@@ -635,9 +641,11 @@ const state = reactive({
|
||||
form: {},
|
||||
rules: {
|
||||
$foreach(column in genTable.Columns)
|
||||
$if(column.IsRequired && column.IsIncrement == false)
|
||||
$if(column.IsRequired && column.IsPk && replaceDto.useSnowflakeId)
|
||||
${column.CsharpFieldFl}: [{ required: true, message: "${column.ColumnComment}不能为空", trigger: $if(column.htmlType == "select")"change"$else"blur"$end }],
|
||||
$elseif(column.IsRequired && column.IsIncrement == false)
|
||||
${column.CsharpFieldFl}: [{ required: true, message: "${column.ColumnComment}不能为空", trigger: $if(column.htmlType == "select")"change"$else"blur"$end
|
||||
$if(column.CsharpType == "int" || column.CsharpType == "long"), type: "number"$end }],
|
||||
$if(column.CsharpType == "int" || column.CsharpType == "long"), type: "number" $end }],
|
||||
$end
|
||||
$end
|
||||
},
|
||||
@@ -675,6 +683,37 @@ $if(sub)
|
||||
$end
|
||||
proxy.resetForm("formRef")
|
||||
}
|
||||
|
||||
$if(replaceDto.ShowBtnView)
|
||||
/**
|
||||
* 查看
|
||||
* @param {*} row
|
||||
*/
|
||||
function handlePreview(row) {
|
||||
reset()
|
||||
const id = row.${replaceDto.FistLowerPk}
|
||||
get${genTable.BusinessName}(id).then((res) => {
|
||||
const { code, data } = res
|
||||
if (code == 200) {
|
||||
open.value = true
|
||||
title.value = '查看'
|
||||
opertype.value = 3
|
||||
form.value = {
|
||||
...data,
|
||||
$foreach(item in genTable.Columns)
|
||||
$if(item.HtmlType == "checkbox" || item.HtmlType == "selectMulti")
|
||||
${item.CsharpFieldFl}Checked: data.${item.CsharpFieldFl} ? data.${item.CsharpFieldFl}.split(',') : [],
|
||||
$end
|
||||
$end
|
||||
}
|
||||
$if(sub)
|
||||
${tool.FirstLowerCase(genTable.SubTable.ClassName)}List.value = res.data.${tool.FirstLowerCase(genTable.SubTable.ClassName)}Nav
|
||||
$end
|
||||
}
|
||||
})
|
||||
}
|
||||
$end
|
||||
|
||||
$if(replaceDto.ShowBtnAdd)
|
||||
// 添加按钮操作
|
||||
function handleAdd() {
|
||||
@@ -782,20 +821,6 @@ function handleClear() {
|
||||
}
|
||||
$end
|
||||
|
||||
$if(replaceDto.ShowBtnView)
|
||||
/**
|
||||
* 查看
|
||||
* @param {*} row
|
||||
*/
|
||||
function handlePreview(row) {
|
||||
reset()
|
||||
open.value = true
|
||||
title.value = '查看'
|
||||
opertype.value = 3
|
||||
form.value = { ...row }
|
||||
}
|
||||
$end
|
||||
|
||||
$if(replaceDto.ShowBtnImport)
|
||||
// 导入数据成功处理
|
||||
const handleFileSuccess = (response) => {
|
||||
@@ -841,6 +866,7 @@ function row${genTable.SubTable.ClassName}Index({ row, rowIndex }) {
|
||||
/** ${genTable.SubTable.FunctionName}添加按钮操作 */
|
||||
function handleAdd${genTable.SubTable.ClassName}() {
|
||||
let obj = {};
|
||||
//下面的代码自己设置默认值
|
||||
$foreach(column in genTable.SubTable.Columns)
|
||||
$if(column.IsPK || column.CsharpField == genTable.SubTableFkName)
|
||||
$elseif(column.IsList == true && "" != column.CsharpField)
|
||||
|
||||
Binary file not shown.
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace ZR.CodeGenerator
|
||||
namespace ZR.CodeGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 代码生成模板
|
||||
|
||||
@@ -9,7 +9,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using ZR.CodeGenerator.Model;
|
||||
using ZR.ServiceCore.Model.Generate;
|
||||
using ZR.Model.System.Generate;
|
||||
|
||||
namespace ZR.CodeGenerator
|
||||
{
|
||||
@@ -27,8 +27,8 @@ namespace ZR.CodeGenerator
|
||||
/// <param name="dto"></param>
|
||||
public static void Generate(GenerateDto dto)
|
||||
{
|
||||
var genOptions = AppSettings.Get<Gen>("gen");
|
||||
dto.VueParentPath = dto.VueVersion == 3 ? "ZRAdmin-vue" : "ZR.Vue";
|
||||
var genOptions = AppSettings.Get<CodeGen>("codeGen");
|
||||
dto.VueParentPath = "Frontend";
|
||||
if (!genOptions.VuePath.IsEmpty())
|
||||
{
|
||||
dto.VueParentPath = genOptions.VuePath;
|
||||
@@ -38,6 +38,10 @@ namespace ZR.CodeGenerator
|
||||
{
|
||||
dto.SubTableOptions = GenerateOption(dto.GenTable.SubTable);
|
||||
}
|
||||
if (dto.GenTable.SubTableName.IsNotEmpty() && dto.GenTable.SubTable == null)
|
||||
{
|
||||
throw new CustomException($"{dto.GenTable.SubTableName}子表不存在");
|
||||
}
|
||||
|
||||
ReplaceDto replaceDto = new()
|
||||
{
|
||||
@@ -53,7 +57,9 @@ namespace ZR.CodeGenerator
|
||||
ShowBtnMultiDel = dto.GenTable.Options.CheckedBtn.Any(f => f == 7),
|
||||
ShowBtnImport = dto.GenTable.Options.CheckedBtn.Any(f => f == 8),
|
||||
ViewFileName = dto.GenTable.BusinessName.FirstUpperCase(),
|
||||
OperBtnStyle = dto.GenTable.Options.OperBtnStyle
|
||||
OperBtnStyle = dto.GenTable.Options.OperBtnStyle,
|
||||
UseSnowflakeId = dto.GenTable.Options.UseSnowflakeId,
|
||||
EnableLog = dto.GenTable.Options.EnableLog
|
||||
};
|
||||
var columns = dto.GenTable.Columns;
|
||||
|
||||
@@ -69,14 +75,18 @@ namespace ZR.CodeGenerator
|
||||
GenerateModels(replaceDto, dto);
|
||||
GenerateService(replaceDto, dto);
|
||||
GenerateControllers(replaceDto, dto);
|
||||
if (dto.VueVersion == 3)
|
||||
if (dto.GenTable.Options.FrontTpl == 2)
|
||||
{
|
||||
GenerateVue3Views(replaceDto, dto);
|
||||
}
|
||||
else
|
||||
else if (dto.GenTable.Options.FrontTpl == 1)
|
||||
{
|
||||
GenerateVueViews(replaceDto, dto);
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerateAntDesignViews(replaceDto, dto);
|
||||
}
|
||||
if (dto.GenTable.Options.GenerateRepo == 1)
|
||||
{
|
||||
GenerateRepository(replaceDto, dto);
|
||||
@@ -118,8 +128,9 @@ namespace ZR.CodeGenerator
|
||||
/// <param name="replaceDto">替换实体</param>
|
||||
private static void GenerateModels(ReplaceDto replaceDto, GenerateDto generateDto)
|
||||
{
|
||||
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplModel.txt");
|
||||
var tplDto = JnHelper.ReadTemplate(CodeTemplateDir, "TplDto.txt");
|
||||
var path = Path.Combine(CodeTemplateDir, "csharp");
|
||||
var tpl = JnHelper.ReadTemplate(path, "TplModel.txt");
|
||||
var tplDto = JnHelper.ReadTemplate(path, "TplDto.txt");
|
||||
|
||||
string fullPath = Path.Combine(generateDto.GenOptions.ModelsNamespace, "Models", generateDto.GenOptions.SubNamespace, replaceDto.ModelTypeName + ".cs");
|
||||
string fullPathDto = Path.Combine(generateDto.GenOptions.ModelsNamespace, "Dto", generateDto.GenOptions.SubNamespace, replaceDto.ModelTypeName + "Dto.cs");
|
||||
@@ -135,7 +146,7 @@ namespace ZR.CodeGenerator
|
||||
/// <param name="replaceDto">替换实体</param>
|
||||
private static void GenerateRepository(ReplaceDto replaceDto, GenerateDto generateDto)
|
||||
{
|
||||
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplRepository.txt");
|
||||
var tpl = JnHelper.ReadTemplate(Path.Combine(CodeTemplateDir, "csharp"), "TplRepository.txt");
|
||||
var result = tpl.Render();
|
||||
var fullPath = Path.Combine(generateDto.GenOptions.RepositoriesNamespace, generateDto.GenOptions.SubNamespace, $"{replaceDto.ModelTypeName}Repository.cs");
|
||||
|
||||
@@ -147,8 +158,9 @@ namespace ZR.CodeGenerator
|
||||
/// </summary>
|
||||
private static void GenerateService(ReplaceDto replaceDto, GenerateDto generateDto)
|
||||
{
|
||||
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplService.txt");
|
||||
var tpl2 = JnHelper.ReadTemplate(CodeTemplateDir, "TplIService.txt");
|
||||
var path = Path.Combine(CodeTemplateDir, "csharp");
|
||||
var tpl = JnHelper.ReadTemplate(path, "TplService.txt");
|
||||
var tpl2 = JnHelper.ReadTemplate(path, "TplIService.txt");
|
||||
|
||||
var fullPath = Path.Combine(generateDto.GenOptions.ServicesNamespace, generateDto.GenOptions.SubNamespace, $"{replaceDto.ModelTypeName}Service.cs");
|
||||
var fullPath2 = Path.Combine(generateDto.GenOptions.IServicsNamespace, generateDto.GenOptions.SubNamespace, $"I{generateDto.GenOptions.SubNamespace}Service", $"I{replaceDto.ModelTypeName}Service.cs");
|
||||
@@ -162,7 +174,7 @@ namespace ZR.CodeGenerator
|
||||
/// </summary>
|
||||
private static void GenerateControllers(ReplaceDto replaceDto, GenerateDto generateDto)
|
||||
{
|
||||
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplControllers.txt");
|
||||
var tpl = JnHelper.ReadTemplate(Path.Combine(CodeTemplateDir, "csharp"), "TplControllers.txt");
|
||||
tpl.Set("QueryCondition", replaceDto.QueryCondition);
|
||||
var result = tpl.Render();
|
||||
|
||||
@@ -180,9 +192,11 @@ namespace ZR.CodeGenerator
|
||||
"select" => "TplVueSelect.txt",
|
||||
_ => "TplVue.txt",
|
||||
};
|
||||
replaceDto.VueViewListHtml = GenerateVueTableList();
|
||||
replaceDto.VueQueryFormHtml = GenerateVueQueryForm();
|
||||
replaceDto.VueViewFormHtml = GenerateCurdForm();
|
||||
var path = Path.Combine(CodeTemplateDir, "vue2");
|
||||
fileName = Path.Combine("vue2", fileName);
|
||||
replaceDto.VueViewListHtml = JnHelper.ReadTemplate(path, "TableList.txt").Render();
|
||||
replaceDto.VueQueryFormHtml = JnHelper.ReadTemplate(path, "QueryForm.txt").Render();
|
||||
replaceDto.VueViewFormHtml = JnHelper.ReadTemplate(path, "CurdForm.txt").Render();
|
||||
|
||||
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName);
|
||||
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue");
|
||||
@@ -213,6 +227,29 @@ namespace ZR.CodeGenerator
|
||||
generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AntDesign
|
||||
/// </summary>
|
||||
/// <param name="generateDto"></param>
|
||||
private static void GenerateAntDesignViews(ReplaceDto replaceDto, GenerateDto generateDto)
|
||||
{
|
||||
string fileName = generateDto.GenTable.TplCategory switch
|
||||
{
|
||||
"tree" => "TreeVue.txt",
|
||||
_ => "Vue2.txt",
|
||||
};
|
||||
fileName = Path.Combine("antDesign", fileName);
|
||||
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName);
|
||||
tpl.Set("treeCode", generateDto.GenTable?.Options?.TreeCode?.FirstLowerCase());
|
||||
tpl.Set("treeName", generateDto.GenTable?.Options?.TreeName?.FirstLowerCase());
|
||||
tpl.Set("treeParentCode", generateDto.GenTable?.Options?.TreeParentCode?.FirstLowerCase());
|
||||
tpl.Set("options", generateDto.GenTable?.Options);
|
||||
|
||||
var result = tpl.Render();
|
||||
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue");
|
||||
generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成vue页面api
|
||||
/// </summary>
|
||||
@@ -255,35 +292,9 @@ namespace ZR.CodeGenerator
|
||||
var result = tpl.Render();
|
||||
string fullPath = Path.Combine(generateDto.GenCodePath, "sql", generateDto.GenTable.BusinessName + ".sql");
|
||||
|
||||
generateDto.GenCodes.Add(new GenCode(8, "sql", fullPath, result));
|
||||
generateDto.GenCodes.Add(new GenCode(8, "sql菜单", fullPath, result));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成vue页面查询form
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GenerateVueQueryForm()
|
||||
{
|
||||
return JnHelper.ReadTemplate(CodeTemplateDir, "QueryForm.txt").Render();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成vue页面table
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GenerateVueTableList()
|
||||
{
|
||||
return JnHelper.ReadTemplate(CodeTemplateDir, "TableList.txt").Render();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成vue表单
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GenerateCurdForm()
|
||||
{
|
||||
return JnHelper.ReadTemplate(CodeTemplateDir, "CurdForm.txt").Render();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region app页面
|
||||
@@ -340,11 +351,8 @@ namespace ZR.CodeGenerator
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetClassName(string tableName)
|
||||
public static string GetClassName(string tableName, bool autoRemovePre, string tablePrefix)
|
||||
{
|
||||
bool autoRemovePre = AppSettings.GetAppConfig(GenConstants.Gen_autoPre, false);
|
||||
string tablePrefix = AppSettings.GetAppConfig<string>(GenConstants.Gen_tablePrefix);
|
||||
|
||||
if (!string.IsNullOrEmpty(tablePrefix) && autoRemovePre)
|
||||
{
|
||||
string[] prefixList = tablePrefix.Split(",", StringSplitOptions.RemoveEmptyEntries);
|
||||
@@ -421,32 +429,32 @@ namespace ZR.CodeGenerator
|
||||
/// <summary>
|
||||
/// 初始化表信息
|
||||
/// </summary>
|
||||
/// <param name="dbName"></param>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="tableName"></param>
|
||||
/// <param name="desc"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <returns></returns>
|
||||
public static GenTable InitTable(string dbName, string userName, string tableName, string desc)
|
||||
public static GenTable InitTable(InitTableDto dto)
|
||||
{
|
||||
var className = GetClassName(dto.TableName, dto.CodeGen.AutoPre, dto.CodeGen.TablePrefix);
|
||||
|
||||
GenTable genTable = new()
|
||||
{
|
||||
DbName = dbName,
|
||||
DbName = dto.DbName,
|
||||
BaseNameSpace = "ZR.",//导入默认命名空间前缀
|
||||
ModuleName = "business",//导入默认模块名
|
||||
ClassName = GetClassName(tableName),
|
||||
BusinessName = GetClassName(tableName),
|
||||
FunctionAuthor = AppSettings.GetConfig(GenConstants.Gen_author),
|
||||
TableName = tableName,
|
||||
TableComment = desc,
|
||||
FunctionName = desc,
|
||||
Create_name = userName,
|
||||
Options = new Options()
|
||||
ModuleName = dto.CodeGen.ModuleName,//导入默认模块名
|
||||
ClassName = className,
|
||||
BusinessName = className,
|
||||
FunctionAuthor = dto.CodeGen.Author,
|
||||
TableName = dto.TableName,
|
||||
TableComment = dto.Desc,
|
||||
FunctionName = dto.Desc,
|
||||
Create_by = dto.UserName,
|
||||
Options = new CodeOptions()
|
||||
{
|
||||
SortType = "asc",
|
||||
CheckedBtn = new int[] { 1, 2, 3 }
|
||||
CheckedBtn = new int[] { 1, 2, 3 },
|
||||
PermissionPrefix = className.ToLower(),
|
||||
FrontTpl = dto.FrontTpl
|
||||
}
|
||||
};
|
||||
genTable.Options.PermissionPrefix = $"{genTable.ModuleName.ToLower()}:{genTable.ClassName.ToLower()}";//权限
|
||||
|
||||
return genTable;
|
||||
}
|
||||
@@ -457,16 +465,16 @@ namespace ZR.CodeGenerator
|
||||
/// <param name="genTable"></param>
|
||||
/// <param name="dbColumnInfos"></param>
|
||||
/// <param name="seqs"></param>
|
||||
public static List<GenTableColumn> InitGenTableColumn(GenTable genTable, List<DbColumnInfo> dbColumnInfos, List<OracleSeq> seqs = null)
|
||||
/// <param name="codeGen"></param>
|
||||
public static List<GenTableColumn> InitGenTableColumn(GenTable genTable, List<DbColumnInfo> dbColumnInfos, List<OracleSeq> seqs = null, CodeGen codeGen = null)
|
||||
{
|
||||
OptionsSetting optionsSetting = new();
|
||||
|
||||
var gen = AppSettings.Get<Gen>("gen");
|
||||
var dbConfig = AppSettings.Get<DbConfigs>("CodeGenDbConfig");
|
||||
var dbConfig = AppSettings.Get<DbConfigs>(nameof(GenConstants.CodeGenDbConfig));
|
||||
|
||||
optionsSetting.CodeGenDbConfig = dbConfig ?? throw new CustomException("代码生成节点数据配置异常"); ;
|
||||
optionsSetting.CodeGen = codeGen ?? throw new CustomException("代码生成节点配置异常");
|
||||
|
||||
optionsSetting.CodeGenDbConfig = dbConfig;
|
||||
optionsSetting.Gen = gen ?? throw new CustomException("代码生成节点配置异常");
|
||||
optionsSetting.Gen.GenDbConfig = dbConfig ?? throw new CustomException("代码生成节点数据配置异常");
|
||||
List<GenTableColumn> genTableColumns = new();
|
||||
foreach (var column in dbColumnInfos)
|
||||
{
|
||||
@@ -486,7 +494,7 @@ namespace ZR.CodeGenerator
|
||||
private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column, List<OracleSeq> seqs, OptionsSetting optionsSetting)
|
||||
{
|
||||
var dataType = column.DataType;
|
||||
if (optionsSetting.Gen.GenDbConfig.DbType == 3)
|
||||
if (optionsSetting.CodeGenDbConfig.DbType == 3)
|
||||
{
|
||||
dataType = column.OracleDataType;
|
||||
var seqName = $"SEQ_{genTable.TableName}_{column.DbColumnName}";
|
||||
@@ -501,7 +509,7 @@ namespace ZR.CodeGenerator
|
||||
ColumnType = dataType,
|
||||
TableId = genTable.TableId,
|
||||
TableName = genTable.TableName,
|
||||
CsharpType = GetCSharpDatatype(dataType, optionsSetting.Gen.CsharpTypeArr).ToString(),
|
||||
CsharpType = GetCSharpDatatype(dataType, optionsSetting.CodeGen.CsharpTypeArr).ToString(),
|
||||
CsharpField = column.DbColumnName.ConvertToPascal("_"),
|
||||
IsRequired = !column.IsNullable,
|
||||
IsIncrement = column.IsIdentity,
|
||||
@@ -604,7 +612,7 @@ namespace ZR.CodeGenerator
|
||||
options.Data.Set("showCustomInput", showCustomInput);
|
||||
options.Data.Set("tool", new CodeGeneratorTool());
|
||||
options.Data.Set("codeTool", new CodeGenerateTemplate());
|
||||
options.Data.Set("dicts", dicts);
|
||||
options.Data.Set("dicts", dicts.DistinctBy(x => x.DictType));
|
||||
options.Data.Set("sub", dto.GenTable.SubTable != null && dto.GenTable.SubTableName.IsNotEmpty());
|
||||
options.EnableCache = true;
|
||||
//...其它数据
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user