Merge branch 'net7.0' of https://gitee.com/wenyongda/ZrAdminNetCore into net7.0

# Conflicts:
#	ZR.Admin.WebApi/appsettings.json
This commit is contained in:
YUN-PC5\user 2023-07-17 09:59:48 +08:00
commit cead939fe4
116 changed files with 2004 additions and 971 deletions

View File

@ -45,17 +45,26 @@ namespace Infrastructure
public static List<T> App<T>(params string[] sections)
{
List<T> list = new();
// 引用 Microsoft.Extensions.Configuration.Binder 包
Configuration.Bind(string.Join(":", sections), list);
try
{
if (Configuration != null && sections.Any())
{
Configuration.Bind(string.Join(":", sections), list);
}
}
catch
{
return list;
}
return list;
}
public static T Bind<T>(string key, T t)
{
Configuration.Bind(key, t);
return t;
}
public static T GetAppConfig<T>(string key, T defaultValue = default)
{
T setting = (T)Convert.ChangeType(Configuration[key], typeof(T));
@ -74,5 +83,16 @@ namespace Infrastructure
{
return Configuration[key];
}
/// <summary>
/// 获取配置节点并转换成指定类型
/// </summary>
/// <typeparam name="T">节点类型</typeparam>
/// <param name="key">节点路径</param>
/// <returns>节点类型实例</returns>
public static T Get<T>(string key)
{
return Configuration.GetSection(key).Get<T>();
}
}
}

View File

@ -7,7 +7,7 @@ namespace Infrastructure
[Description("success")]
SUCCESS = 200,
[Description("no data")]
[Description("没有更多数据")]
NO_DATA = 210,
[Description("参数错误")]

View File

@ -1,11 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
//using Newtonsoft.Json;
namespace Infrastructure.Extensions
{

View File

@ -0,0 +1,375 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml.XPath;
namespace Infrastructure.Helper
{
public class XmlCommentHelper
{
private static Regex RefTagPattern = new Regex(@"<(see|paramref) (name|cref)=""([TPF]{1}:)?(?<display>.+?)"" ?/>");
private static Regex CodeTagPattern = new Regex(@"<c>(?<display>.+?)</c>");
private static Regex ParaTagPattern = new Regex(@"<para>(?<display>.+?)</para>", RegexOptions.Singleline);
List<XPathNavigator> navigators = new List<XPathNavigator>();
/// <summary>
/// 从当前dll文件中加载所有的xml文件
/// </summary>
public void LoadAll()
{
var files = Directory.GetFiles(Directory.GetCurrentDirectory());
foreach (var file in files)
{
if (string.Equals(Path.GetExtension(file), ".xml", StringComparison.OrdinalIgnoreCase))
{
Load(file);
}
}
}
/// <summary>
/// 从xml中加载
/// </summary>
/// <param name="xmls"></param>
public void LoadXml(params string[] xmls)
{
foreach (var xml in xmls)
{
Load(new MemoryStream(Encoding.UTF8.GetBytes(xml)));
}
}
/// <summary>
/// 从文件中加载
/// </summary>
/// <param name="xmlFiles"></param>
public void Load(params string[] xmlFiles)
{
foreach (var xmlFile in xmlFiles)
{
var doc = new XPathDocument(xmlFile);
navigators.Add(doc.CreateNavigator());
//Console.WriteLine("加载xml文件=" + xmlFile);
}
}
/// <summary>
/// 从流中加载
/// </summary>
/// <param name="streams"></param>
public void Load(params Stream[] streams)
{
foreach (var stream in streams)
{
var doc = new XPathDocument(stream);
navigators.Add(doc.CreateNavigator());
}
}
/// <summary>
/// 读取类型中的注释
/// </summary>
/// <param name="type">类型</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetTypeComment(Type type, string xPath = "summary", bool humanize = true)
{
var typeMemberName = GetMemberNameForType(type);
return GetComment(typeMemberName, xPath, humanize);
}
/// <summary>
/// 读取字段或者属性的注释
/// </summary>
/// <param name="fieldOrPropertyInfo">字段或者属性</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetFieldOrPropertyComment(MemberInfo fieldOrPropertyInfo, string xPath = "summary", bool humanize = true)
{
var fieldOrPropertyMemberName = GetMemberNameForFieldOrProperty(fieldOrPropertyInfo);
return GetComment(fieldOrPropertyMemberName, xPath, humanize);
}
/// <summary>
/// 读取方法中的注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetMethodComment(MethodInfo methodInfo, string xPath = "summary", bool humanize = true)
{
var methodMemberName = GetMemberNameForMethod(methodInfo);
return GetComment(methodMemberName, xPath, humanize);
}
/// <summary>
/// 读取方法中的返回值注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetMethodReturnComment(MethodInfo methodInfo, bool humanize = true)
{
return GetMethodComment(methodInfo, "returns", humanize);
}
/// <summary>
/// 读取参数的注释
/// </summary>
/// <param name="parameterInfo">参数</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetParameterComment(ParameterInfo parameterInfo, bool humanize = true)
{
if (!(parameterInfo.Member is MethodInfo methodInfo)) return string.Empty;
var methodMemberName = GetMemberNameForMethod(methodInfo);
return GetComment(methodMemberName, $"param[@name='{parameterInfo.Name}']", humanize);
}
/// <summary>
/// 读取方法的所有参数的注释
/// </summary>
/// <param name="methodInfo">方法</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public Dictionary<string, string> GetParameterComments(MethodInfo methodInfo, bool humanize = true)
{
var parameterInfos = methodInfo.GetParameters();
Dictionary<string, string> dict = new Dictionary<string, string>();
foreach (var parameterInfo in parameterInfos)
{
dict[parameterInfo.Name] = GetParameterComment(parameterInfo, humanize);
}
return dict;
}
/// <summary>
/// 读取指定名称节点的注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="xPath">注释路径</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetComment(string name, string xPath, bool humanize = true)
{
foreach (var _xmlNavigator in navigators)
{
var typeSummaryNode = _xmlNavigator.SelectSingleNode($"/doc/members/member[@name='{name}']/{xPath.Trim('/', '\\')}");
if (typeSummaryNode != null)
{
return humanize ? Humanize(typeSummaryNode.InnerXml) : typeSummaryNode.InnerXml;
}
}
return string.Empty;
}
/// <summary>
/// 读取指定节点的summary注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetSummary(string name, bool humanize = true)
{
return GetComment(name, "summary", humanize);
}
/// <summary>
/// 读取指定节点的example注释
/// </summary>
/// <param name="name">节点名称</param>
/// <param name="humanize">可读性优化(比如去掉xml标记)</param>
/// <returns></returns>
public string GetExample(string name, bool humanize = true)
{
return GetComment(name, "example", humanize);
}
/// <summary>
/// 获取方法的节点名称
/// </summary>
/// <param name="method"></param>
/// <returns></returns>
public string GetMemberNameForMethod(MethodInfo method)
{
var builder = new StringBuilder("M:");
builder.Append(QualifiedNameFor(method.DeclaringType));
builder.Append($".{method.Name}");
var parameters = method.GetParameters();
if (parameters.Any())
{
var parametersNames = parameters.Select(p =>
{
return p.ParameterType.IsGenericParameter
? $"`{p.ParameterType.GenericParameterPosition}"
: QualifiedNameFor(p.ParameterType, expandGenericArgs: true);
});
builder.Append($"({string.Join(",", parametersNames)})");
}
return builder.ToString();
}
/// <summary>
/// 获取类型的节点名称
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public string GetMemberNameForType(Type type)
{
var builder = new StringBuilder("T:");
builder.Append(QualifiedNameFor(type));
return builder.ToString();
}
/// <summary>
/// 获取字段或者属性的节点名称
/// </summary>
/// <param name="fieldOrPropertyInfo"></param>
/// <returns></returns>
public string GetMemberNameForFieldOrProperty(MemberInfo fieldOrPropertyInfo)
{
var builder = new StringBuilder(((fieldOrPropertyInfo.MemberType & MemberTypes.Field) != 0) ? "F:" : "P:");
builder.Append(QualifiedNameFor(fieldOrPropertyInfo.DeclaringType));
builder.Append($".{fieldOrPropertyInfo.Name}");
return builder.ToString();
}
private string QualifiedNameFor(Type type, bool expandGenericArgs = false)
{
if (type.IsArray)
return $"{QualifiedNameFor(type.GetElementType(), expandGenericArgs)}[]";
var builder = new StringBuilder();
if (!string.IsNullOrEmpty(type.Namespace))
builder.Append($"{type.Namespace}.");
if (type.IsNested)
{
builder.Append($"{string.Join(".", GetNestedTypeNames(type))}.");
}
if (type.IsConstructedGenericType && expandGenericArgs)
{
var nameSansGenericArgs = type.Name.Split('`').First();
builder.Append(nameSansGenericArgs);
var genericArgsNames = type.GetGenericArguments().Select(t =>
{
return t.IsGenericParameter
? $"`{t.GenericParameterPosition}"
: QualifiedNameFor(t, true);
});
builder.Append($"{{{string.Join(",", genericArgsNames)}}}");
}
else
{
builder.Append(type.Name);
}
return builder.ToString();
}
private IEnumerable<string> GetNestedTypeNames(Type type)
{
if (!type.IsNested || type.DeclaringType == null) yield break;
foreach (var nestedTypeName in GetNestedTypeNames(type.DeclaringType))
{
yield return nestedTypeName;
}
yield return type.DeclaringType.Name;
}
private string Humanize(string text)
{
if (text == null)
throw new ArgumentNullException("text");
//Call DecodeXml at last to avoid entities like &lt and &gt to break valid xml
text = NormalizeIndentation(text);
text = HumanizeRefTags(text);
text = HumanizeCodeTags(text);
text = HumanizeParaTags(text);
text = DecodeXml(text);
return text;
}
private string NormalizeIndentation(string text)
{
string[] lines = text.Split('\n');
string padding = GetCommonLeadingWhitespace(lines);
int padLen = padding == null ? 0 : padding.Length;
// remove leading padding from each line
for (int i = 0, l = lines.Length; i < l; ++i)
{
string line = lines[i].TrimEnd('\r'); // remove trailing '\r'
if (padLen != 0 && line.Length >= padLen && line.Substring(0, padLen) == padding)
line = line.Substring(padLen);
lines[i] = line;
}
// remove leading empty lines, but not all leading padding
// remove all trailing whitespace, regardless
return string.Join("\r\n", lines.SkipWhile(x => string.IsNullOrWhiteSpace(x))).TrimEnd();
}
private string GetCommonLeadingWhitespace(string[] lines)
{
if (null == lines)
throw new ArgumentException("lines");
if (lines.Length == 0)
return null;
string[] nonEmptyLines = lines
.Where(x => !string.IsNullOrWhiteSpace(x))
.ToArray();
if (nonEmptyLines.Length < 1)
return null;
int padLen = 0;
// use the first line as a seed, and see what is shared over all nonEmptyLines
string seed = nonEmptyLines[0];
for (int i = 0, l = seed.Length; i < l; ++i)
{
if (!char.IsWhiteSpace(seed, i))
break;
if (nonEmptyLines.Any(line => line[i] != seed[i]))
break;
++padLen;
}
if (padLen > 0)
return seed.Substring(0, padLen);
return null;
}
private string HumanizeRefTags(string text)
{
return RefTagPattern.Replace(text, (match) => match.Groups["display"].Value);
}
private string HumanizeCodeTags(string text)
{
return CodeTagPattern.Replace(text, (match) => "{" + match.Groups["display"].Value + "}");
}
private string HumanizeParaTags(string text)
{
return ParaTagPattern.Replace(text, (match) => "<br>" + match.Groups["display"].Value);
}
private string DecodeXml(string text)
{
return System.Net.WebUtility.HtmlDecode(text);
}
}
}

View File

@ -57,12 +57,12 @@ namespace Infrastructure.Model
return this;
}
/// <summary>
/// 返回成功消息
/// </summary>
/// <param name="data">数据对象</param>
/// <returns>成功消息</returns>
public static ApiResult Success(object data) { return new ApiResult(HttpStatus.SUCCESS, "success", data); }
///// <summary>
///// 返回成功消息
///// </summary>
///// <param name = "data" > 数据对象 </ param >
///// < returns > 成功消息 </ returns >
//public static ApiResult Success(object data) { return new ApiResult(HttpStatus.SUCCESS, "success", data); }
/// <summary>
/// 返回成功消息
@ -82,7 +82,6 @@ namespace Infrastructure.Model
/// <summary>
/// 访问被拒
/// </summary>
/// <param name="apiResult"></param>
/// <returns></returns>
public ApiResult On401()
{

View File

@ -1,4 +1,6 @@

using System.Collections.Generic;
namespace Infrastructure
{
/// <summary>
@ -15,16 +17,19 @@ namespace Infrastructure
public ALIYUN_OSS ALIYUN_OSS { get; set; }
public JwtSettings JwtSettings { get; set; }
public Gen Gen { get; set; }
public List<DbConfigs> DbConfigs { get; set; }
}
/// <summary>
/// 发送邮件数据配置
/// </summary>
public class MailOptions
{
public string From { get; set; }
public string FromName { get; set; }
public string FromEmail { get; set; }
public string Password { get; set; }
public string Smtp { get; set; }
public int Port { get; set; }
public bool UseSsl { get; set; }
public string Signature { get; set; }
}
/// <summary>
@ -75,10 +80,19 @@ namespace Infrastructure
public class Gen
{
public string Conn { get; set; }
public int DbType { get; set; }
public string Database { get; set; }
}
public class DbConfigs
{
public string Conn { get; set; }
public int DbType { get; set; }
public string ConfigId { get; set; }
public bool IsAutoCloseConnection { get; set; }
/// <summary>
/// 是否代码生成使用库
/// </summary>
public bool IsGenerateDb { get; set; }
public string DbName { get; set; }
}
}

View File

@ -1,5 +1,5 @@
<h2 align="center"> ZR.Admin.NET后台管理系统</h2>
<h4 align="center">基于.NET5/.Net7 + vue2.x/vue3.x前后端分离的.net快速开发框架</h4>
<h4 align="center">基于.NET5/.Net7 + vue2.x/vue3.x/uniapp前后端分离的.net快速开发框架</h4>
<p align="center">
<a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a>
@ -146,6 +146,24 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x、vuex、vue-router 、vue-cli
</tr>
</table>
## 移动端演示图
<table>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a1.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a2.png"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a8.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a4.png"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a5.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a6.png"/></td>
</tr>
</table>
## 🎉 优势
1. 前台系统不用编写登录、授权、认证模块;只负责编写业务模块即可

View File

@ -1,4 +1,5 @@
using Infrastructure;
using Infrastructure.Extensions;
using Infrastructure.Model;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
@ -12,7 +13,7 @@ namespace ZR.Admin.WebApi.Controllers
public class BaseController : ControllerBase
{
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
/// <summary>
/// 返回成功封装
/// </summary>
@ -29,11 +30,10 @@ namespace ZR.Admin.WebApi.Controllers
/// json输出带时间格式的
/// </summary>
/// <param name="apiResult"></param>
/// <param name="timeFormatStr"></param>
/// <returns></returns>
protected IActionResult ToResponse(ApiResult apiResult, string timeFormatStr = "yyyy-MM-dd HH:mm:ss")
protected IActionResult ToResponse(ApiResult apiResult)
{
string jsonStr = GetJsonStr(apiResult, timeFormatStr);
string jsonStr = GetJsonStr(apiResult, TIME_FORMAT_FULL);
return Content(jsonStr, "application/json");
}
@ -47,7 +47,7 @@ namespace ZR.Admin.WebApi.Controllers
protected IActionResult ToResponse(ResultCode resultCode, string msg = "")
{
return ToResponse(GetApiResult(resultCode, msg));
return ToResponse(new ApiResult((int)resultCode, msg));
}
/// <summary>
@ -62,24 +62,24 @@ namespace ZR.Admin.WebApi.Controllers
//string fileDir = Path.Combine(webHostEnvironment.WebRootPath, path, fileName);
var stream = Io.File.OpenRead(path); //创建文件流
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
}
#region
/// <summary>
/// 响应返回结果
/// </summary>
/// <param name="rows">受影响行数</param>
/// <param name="data"></param>
/// <returns></returns>
protected ApiResult ToJson(long rows)
protected ApiResult ToJson(long rows, object? data = null)
{
return rows > 0 ? GetApiResult(ResultCode.SUCCESS) : GetApiResult(ResultCode.FAIL);
}
protected ApiResult ToJson(long rows, object data)
{
return rows > 0 ? GetApiResult(ResultCode.SUCCESS, data) : GetApiResult(ResultCode.FAIL);
return rows > 0 ? ApiResult.Success("success", data) : GetApiResult(ResultCode.FAIL);
}
/// <summary>
/// 全局Code使用
/// </summary>
@ -88,17 +88,17 @@ namespace ZR.Admin.WebApi.Controllers
/// <returns></returns>
protected ApiResult GetApiResult(ResultCode resultCode, object? data = null)
{
var apiResult = new ApiResult((int)resultCode, resultCode.ToString())
{
Data = data
};
var msg = resultCode.GetDescription();
return apiResult;
}
protected ApiResult GetApiResult(ResultCode resultCode, string msg)
{
return new ApiResult((int)resultCode, msg);
return new ApiResult((int)resultCode, msg, data);
}
/// <summary>
///
/// </summary>
/// <param name="apiResult"></param>
/// <param name="timeFormatStr"></param>
/// <returns></returns>
private static string GetJsonStr(ApiResult apiResult, string timeFormatStr)
{
if (string.IsNullOrEmpty(timeFormatStr))
@ -128,12 +128,20 @@ namespace ZR.Admin.WebApi.Controllers
return ExportExcelMini(list, sheetName, fileName).Item1;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="sheetName"></param>
/// <param name="fileName"></param>
/// <returns></returns>
protected (string, string) ExportExcelMini<T>(List<T> list, string sheetName, string fileName)
{
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
string sFileName = $"{fileName}{DateTime.Now:MM-dd-HHmmss}.xlsx";
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName);
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
MiniExcel.SaveAs(fullPath, list, sheetName: sheetName);
@ -171,7 +179,7 @@ namespace ZR.Admin.WebApi.Controllers
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
string sFileName = $"{fileName}模板.xlsx";
string newFileName = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", sFileName);
if (!Directory.Exists(newFileName))
{
Directory.CreateDirectory(Path.GetDirectoryName(newFileName));

View File

@ -5,7 +5,6 @@ using Infrastructure.Extensions;
using Infrastructure.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using MiniExcelLibs;
using Newtonsoft.Json;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
@ -70,15 +69,15 @@ namespace ZR.Admin.WebApi.Controllers
/// <param name="sendEmailVo">请求参数接收实体</param>
/// <returns></returns>
[ActionPermissionFilter(Permission = "tool:email:send")]
[Log(Title = "发送邮件", IsSaveRequestData = false)]
[Log(Title = "发送邮件")]
[HttpPost]
public IActionResult SendEmail([FromBody] SendEmailDto sendEmailVo)
{
if (sendEmailVo == null || string.IsNullOrEmpty(sendEmailVo.Subject) || string.IsNullOrEmpty(sendEmailVo.ToUser))
if (sendEmailVo == null)
{
return ToResponse(ApiResult.Error($"请求参数不完整"));
}
if (string.IsNullOrEmpty(OptionsSetting.MailOptions.From) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password))
if (string.IsNullOrEmpty(OptionsSetting.MailOptions.FromEmail) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password))
{
return ToResponse(ApiResult.Error($"请配置邮箱信息"));
}
@ -90,11 +89,11 @@ namespace ZR.Admin.WebApi.Controllers
{
toUsers.Append(mailHelper.FromEmail);
}
mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent);
string result = mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent);
logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}");
logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}, 结果{result}");
return SUCCESS(true);
return SUCCESS(result);
}
#region
@ -179,85 +178,29 @@ namespace ZR.Admin.WebApi.Controllers
/// <summary>
/// 初始化种子数据
/// </summary>
/// <param name="clean">是否清空数据</param>
/// <returns></returns>
[HttpGet]
[ApiExplorerSettings(IgnoreApi = true)]
[ActionPermissionFilter(Permission = "common")]
[Log(BusinessType = BusinessType.INSERT, Title = "初始化数据")]
public IActionResult InitSeedData()
public IActionResult InitSeedData(bool clean = false)
{
if (!WebHostEnvironment.IsDevelopment())
{
return ToResponse(ResultCode.FAIL, "导入数据失败");
return ToResponse(ResultCode.CUSTOM_ERROR, "导入数据失败");
}
var path = Path.Combine(WebHostEnvironment.WebRootPath, "data.xlsx");
//var sheetNames = MiniExcel.GetSheetNames(path);
SeedDataService seedDataService = new();
var sysUser = MiniExcel.Query<SysUser>(path, sheetName: "user").ToList();
var result1 = seedDataService.InitUserData(sysUser);
var sysPost = MiniExcel.Query<SysPost>(path, sheetName: "post").ToList();
var result2 = seedDataService.InitPostData(sysPost);
var sysRole = MiniExcel.Query<SysRole>(path, sheetName: "role").ToList();
var result3 = seedDataService.InitRoleData(sysRole);
var sysUserRole = MiniExcel.Query<SysUserRole>(path, sheetName: "user_role").ToList();
var result4 = seedDataService.InitUserRoleData(sysUserRole);
var sysMenu = MiniExcel.Query<SysMenu>(path, sheetName: "menu").ToList();
var result5 = seedDataService.InitMenuData(sysMenu);
var sysConfig = MiniExcel.Query<SysConfig>(path, sheetName: "config").ToList();
var result6 = seedDataService.InitConfigData(sysConfig);
var sysRoleMenu = MiniExcel.Query<SysRoleMenu>(path, sheetName: "role_menu").ToList();
var result7 = seedDataService.InitRoleMenuData(sysRoleMenu);
var sysDict = MiniExcel.Query<SysDictType>(path, sheetName: "dict_type").ToList();
var result8 = seedDataService.InitDictType(sysDict);
var sysDictData = MiniExcel.Query<SysDictData>(path, sheetName: "dict_data").ToList();
var result9 = seedDataService.InitDictData(sysDictData);
var sysDept = MiniExcel.Query<SysDept>(path, sheetName: "dept").ToList();
var result10 = seedDataService.InitDeptData(sysDept);
var sysArticleCategory = MiniExcel.Query<ArticleCategory>(path, sheetName: "article_category").ToList();
var result11 = seedDataService.InitArticleCategoryData(sysArticleCategory);
var sysTask = MiniExcel.Query<SysTasks>(path, sheetName: "task").ToList();
var result12 = seedDataService.InitTaskData(sysTask);
var result = seedDataService.InitSeedData(path, clean);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(result1.Item1);
Console.WriteLine(result2.Item1);
Console.WriteLine(result3.Item1);
Console.WriteLine(result4.Item1);
Console.WriteLine(result5.Item1);
Console.WriteLine(result6.Item1);
Console.WriteLine(result7.Item1);
Console.WriteLine(result8.Item1);
Console.WriteLine(result9.Item1);
Console.WriteLine(result10.Item1);
Console.WriteLine(result11.Item1);
Console.WriteLine(result12.Item1);
foreach (var item in result)
{
Console.WriteLine(item);
}
Console.ForegroundColor = ConsoleColor.White;
return SUCCESS(new
{
result1 = result1.Item1,
result2 = result2.Item1,
result3 = result3.Item1,
result4 = result4.Item1,
result5 = result5.Item1,
result6 = result6.Item1,
result7 = result7.Item1,
result8 = result8.Item1,
result9 = result9.Item1,
result10 = result10.Item1,
result11 = result11.Item1,
result12 = result12.Item1
result
});
}
}

View File

@ -2,6 +2,7 @@
using Infrastructure.Attribute;
using Infrastructure.Enums;
using Infrastructure.Extensions;
using IP2Region.Ex.Models;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
@ -12,6 +13,7 @@ using ZR.CodeGenerator.Model;
using ZR.CodeGenerator.Service;
using ZR.Common;
using ZR.Model;
using ZR.Model.System;
using ZR.Model.System.Dto;
using ZR.Model.System.Generate;
using ZR.Service.System.IService;
@ -28,16 +30,18 @@ namespace ZR.Admin.WebApi.Controllers
private readonly CodeGeneraterService _CodeGeneraterService = new CodeGeneraterService();
private readonly IGenTableService GenTableService;
private readonly IGenTableColumnService GenTableColumnService;
private readonly ISysMenuService SysMenuService;
private readonly IWebHostEnvironment WebHostEnvironment;
public CodeGeneratorController(
IGenTableService genTableService,
IGenTableColumnService genTableColumnService,
IWebHostEnvironment webHostEnvironment)
IWebHostEnvironment webHostEnvironment,
ISysMenuService sysMenuService)
{
GenTableService = genTableService;
GenTableColumnService = genTableColumnService;
WebHostEnvironment = webHostEnvironment;
SysMenuService = sysMenuService;
}
/// <summary>
@ -149,6 +153,7 @@ namespace ZR.Admin.WebApi.Controllers
{
throw new CustomException("表不能为空");
}
var dbConfig = AppSettings.Get<List<DbConfigs>>("dbConfigs").FirstOrDefault(f => f.IsGenerateDb);
string[] tableNames = tables.Split(',', StringSplitOptions.RemoveEmptyEntries);
int result = 0;
foreach (var tableName in tableNames)
@ -156,15 +161,18 @@ namespace ZR.Admin.WebApi.Controllers
var tabInfo = _CodeGeneraterService.GetTableInfo(dbName, tableName);
if (tabInfo != null)
{
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);
List<GenTableColumn> genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos, seqs);
GenTableColumnService.DeleteGenTableColumnByTableName(tableName);
GenTableColumnService.InsertGenTableColumn(genTableColumns);
genTable.Columns = genTableColumns;
@ -227,8 +235,9 @@ namespace ZR.Admin.WebApi.Controllers
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
}
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
var dbConfig = AppSettings.Get<List<DbConfigs>>("dbConfigs").FirstOrDefault(f => f.IsGenerateDb);
dto.DbType = AppSettings.GetAppConfig("gen:dbType", 0);
dto.DbType = dbConfig.DbType;
dto.GenTable = genTableInfo;
dto.IsPreview = true;
//生成代码
@ -252,16 +261,18 @@ namespace ZR.Admin.WebApi.Controllers
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
}
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
var dbConfig = AppSettings.Get<List<DbConfigs>>("dbConfigs").FirstOrDefault(f => f.IsGenerateDb);
dto.DbType = AppSettings.GetAppConfig("gen:dbType", 0);
dto.DbType = dbConfig.DbType;
dto.GenTable = genTableInfo;
//自定义路径
if (genTableInfo.GenType == "1")
{
{
var genPath = genTableInfo.GenPath;
string tempPath = WebHostEnvironment.ContentRootPath;
var parentPath = tempPath[..tempPath.LastIndexOf(@"\")];
//代码生成文件夹路径
dto.GenCodePath = genTableInfo.GenPath.IsEmpty() ? parentPath : genTableInfo.GenPath;
dto.GenCodePath = (genPath.IsEmpty() || genPath.Equals("/")) ? parentPath : genTableInfo.GenPath;
}
else
{
@ -275,7 +286,10 @@ namespace ZR.Admin.WebApi.Controllers
CodeGeneratorTool.Generate(dto);
//下载文件
FileUtil.ZipGenCode(dto.ZipPath, dto.GenCodePath, zipReturnFileName);
if (genTableInfo.Options.GenerateMenu)
{
SysMenuService.AddSysMenu(genTableInfo, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport);
}
return SUCCESS(new { path = "/Generatecode/" + zipReturnFileName, fileName = dto.ZipFileName });
}

View File

@ -3,6 +3,7 @@ using Infrastructure.Attribute;
using Infrastructure.Enums;
using Microsoft.AspNetCore.Mvc;
using System.Collections;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Common;
using ZR.Model.System;
@ -114,10 +115,10 @@ namespace ZR.Admin.WebApi.Controllers.System
{
if (UserConstants.NOT_UNIQUE.Equals(DeptService.CheckDeptNameUnique(dept)))
{
return ToResponse(GetApiResult(ResultCode.CUSTOM_ERROR, $"新增部门{dept.DeptName}失败,部门名称已存在"));
return ToResponse(ResultCode.CUSTOM_ERROR, $"新增部门{dept.DeptName}失败,部门名称已存在");
}
dept.Create_by = User.Identity.Name;
return ToResponse(ToJson(DeptService.InsertDept(dept)));
dept.Create_by = HttpContext.GetName();
return ToResponse(DeptService.InsertDept(dept));
}
/// <summary>
@ -132,14 +133,14 @@ namespace ZR.Admin.WebApi.Controllers.System
{
if (UserConstants.NOT_UNIQUE.Equals(DeptService.CheckDeptNameUnique(dept)))
{
return ToResponse(GetApiResult(ResultCode.CUSTOM_ERROR, $"修改部门{dept.DeptName}失败,部门名称已存在"));
return ToResponse(ResultCode.CUSTOM_ERROR, $"修改部门{dept.DeptName}失败,部门名称已存在");
}
else if (dept.ParentId.Equals(dept.DeptId))
{
return ToResponse(GetApiResult(ResultCode.CUSTOM_ERROR, $"修改部门{dept.DeptName}失败,上级部门不能是自己"));
return ToResponse(ResultCode.CUSTOM_ERROR, $"修改部门{dept.DeptName}失败,上级部门不能是自己");
}
dept.Update_by = User.Identity.Name;
return ToResponse(ToJson(DeptService.UpdateDept(dept)));
dept.Update_by = HttpContext.GetName();
return ToResponse(DeptService.UpdateDept(dept));
}
/// <summary>
@ -153,11 +154,11 @@ namespace ZR.Admin.WebApi.Controllers.System
{
if (DeptService.Queryable().Count(it => it.ParentId == deptId && it.DelFlag == "0") > 0)
{
return ToResponse(GetApiResult(ResultCode.CUSTOM_ERROR, $"存在下级部门,不允许删除"));
return ToResponse(ResultCode.CUSTOM_ERROR, $"存在下级部门,不允许删除");
}
if (UserService.Queryable().Count(it => it.DeptId == deptId && it.DelFlag == 0) > 0)
{
return ToResponse(GetApiResult(ResultCode.CUSTOM_ERROR, $"部门存在用户,不允许删除"));
return ToResponse(ResultCode.CUSTOM_ERROR, $"部门存在用户,不允许删除");
}
return SUCCESS(DeptService.Delete(deptId));

View File

@ -38,6 +38,14 @@ namespace ZR.Admin.WebApi.Controllers.System
public IActionResult List([FromQuery] SysDictData dictData, [FromQuery] PagerInfo pagerInfo)
{
var list = SysDictDataService.SelectDictDataList(dictData, pagerInfo);
if (dictData.DictType.StartsWith("sql_"))
{
var result = SysDictService.SelectDictDataByCustomSql(dictData.DictType);
list.Result.AddRange(result);
list.TotalNum += result.Count;
}
return SUCCESS(list);
}
@ -75,7 +83,7 @@ namespace ZR.Admin.WebApi.Controllers.System
};
if (dic.DictType.StartsWith("cus_") || dic.DictType.StartsWith("sql_"))
{
vo.List = SysDictService.SelectDictDataByCustomSql(dic.DictType);
vo.List.AddRange(SysDictService.SelectDictDataByCustomSql(dic.DictType));
}
dataVos.Add(vo);
}

View File

@ -144,7 +144,7 @@ namespace ZR.Admin.WebApi.Controllers.System
long uid = HttpContext.GetUId();
var menus = sysMenuService.SelectMenuTreeByUserId(uid);
return ToResponse(ToJson(1, sysMenuService.BuildMenus(menus)));
return SUCCESS(sysMenuService.BuildMenus(menus));
}
/// <summary>
@ -152,7 +152,7 @@ namespace ZR.Admin.WebApi.Controllers.System
/// </summary>
/// <returns></returns>
[HttpGet("captchaImage")]
public ApiResult CaptchaImage()
public IActionResult CaptchaImage()
{
string uuid = Guid.NewGuid().ToString().Replace("-", "");
@ -161,7 +161,7 @@ namespace ZR.Admin.WebApi.Controllers.System
var info = SecurityCodeHelper.Generate(uuid, 60);
var obj = new { captchaOff, uuid, img = info.Base64 };// File(stream, "image/png")
return ToJson(1, obj);
return SUCCESS(obj);
}
/// <summary>

View File

@ -119,7 +119,7 @@ namespace ZR.Admin.WebApi.Controllers.System
return ToResponse(ApiResult.Error($"修改菜单'{modal.MenuName}'失败,上级菜单不能选择自己"));
}
modal.Update_by = HttpContext.GetName();
int result = sysMenuService.EditMenu(modal);
long result = sysMenuService.EditMenu(modal);
return ToResponse(result);
}
@ -151,7 +151,7 @@ namespace ZR.Admin.WebApi.Controllers.System
}
menu.Create_by = HttpContext.GetName();
int result = sysMenuService.AddMenu(menu);
long result = sysMenuService.AddMenu(menu);
return ToResponse(result);
}

View File

@ -45,7 +45,7 @@ namespace ZR.Admin.WebApi.Controllers.System
{
var predicate = Expressionable.Create<SysNotice>();
predicate = predicate.And(m => m.Status == "0");
predicate = predicate.And(m => m.Status == 0);
var response = _SysNoticeService.GetPages(predicate.ToExpression(), parm);
return SUCCESS(response);
}
@ -61,9 +61,9 @@ namespace ZR.Admin.WebApi.Controllers.System
var predicate = Expressionable.Create<SysNotice>();
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.NoticeTitle), m => m.NoticeTitle.Contains(parm.NoticeTitle));
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.NoticeType), m => m.NoticeType == parm.NoticeType);
predicate = predicate.AndIF(parm.NoticeType != null, m => m.NoticeType == parm.NoticeType);
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.CreateBy), m => m.Create_by.Contains(parm.CreateBy) || m.Update_by.Contains(parm.CreateBy));
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.Status), m => m.Status == parm.Status);
predicate = predicate.AndIF(parm.Status != null, m => m.Status == parm.Status);
var response = _SysNoticeService.GetPages(predicate.ToExpression(), parm);
return SUCCESS(response);
}
@ -88,14 +88,9 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "system:notice:add")]
[Log(Title = "知公", BusinessType = BusinessType.INSERT)]
[Log(Title = "发布通告", BusinessType = BusinessType.INSERT)]
public IActionResult AddSysNotice([FromBody] SysNoticeDto parm)
{
if (parm == null)
{
throw new CustomException("请求参数错误");
}
//从 Dto 映射到 实体
var modal = parm.Adapt<SysNotice>().ToCreate(HttpContext);
modal.Create_by = HttpContext.GetName();
modal.Create_time = DateTime.Now;
@ -120,19 +115,13 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "system:notice:update")]
[Log(Title = "通知公告表", BusinessType = BusinessType.UPDATE)]
[Log(Title = "修改公告", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateSysNotice([FromBody] SysNoticeDto parm)
{
if (parm == null)
{
throw new CustomException("请求实体不能为空");
}
//从 Dto 映射到 实体
var model = parm.Adapt<SysNotice>().ToUpdate(HttpContext);
model.Update_by = HttpContext.GetName();
var response = _SysNoticeService.Update(w => w.NoticeId == model.NoticeId, it => new SysNotice()
{
//Update 字段映射
NoticeTitle = model.NoticeTitle,
NoticeType = model.NoticeType,
NoticeContent = model.NoticeContent,
@ -150,7 +139,7 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns>
[HttpPut("send/{NoticeId}")]
[ActionPermissionFilter(Permission = "system:notice:update")]
[Log(Title = "通知公告", BusinessType = BusinessType.OTHER)]
[Log(Title = "发送通知公告", BusinessType = BusinessType.OTHER)]
public IActionResult SendNotice(int NoticeId = 0)
{
if (NoticeId <= 0)
@ -158,7 +147,7 @@ namespace ZR.Admin.WebApi.Controllers.System
throw new CustomException("请求实体不能为空");
}
var response = _SysNoticeService.GetFirst(x => x.NoticeId == NoticeId);
if (response != null && response.Status == "0")
if (response != null && response.Status == 0)
{
_hubContext.Clients.All.SendAsync(HubsConstant.ReceiveNotice, response.NoticeTitle, response.NoticeContent);
}
@ -171,7 +160,7 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns>
[HttpDelete("{ids}")]
[ActionPermissionFilter(Permission = "system:notice:delete")]
[Log(Title = "通知公告", BusinessType = BusinessType.DELETE)]
[Log(Title = "通知公告", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteSysNotice(string ids)
{
int[] idsArr = Tools.SpitIntArrary(ids);
@ -181,20 +170,5 @@ namespace ZR.Admin.WebApi.Controllers.System
return SUCCESS(response);
}
/// <summary>
/// 通知公告表导出
/// </summary>
/// <returns></returns>
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "通知公告表")]
[HttpGet("export")]
[ActionPermissionFilter(Permission = "system:notice:export")]
public IActionResult Export()
{
var list = _SysNoticeService.GetAll();
string sFileName = ExportExcel(list, "SysNotice", "通知公告表");
return SUCCESS(new { path = "/export/" + sFileName, fileName = sFileName });
}
}
}

View File

@ -73,7 +73,7 @@ namespace ZR.Admin.WebApi.Controllers.System
}
post.Create_by = HttpContext.GetName();
return ToResponse(ToJson(PostService.Add(post)));
return ToResponse(PostService.Add(post));
}
/// <summary>
@ -109,7 +109,7 @@ namespace ZR.Admin.WebApi.Controllers.System
public IActionResult Delete(string id)
{
int[] ids = Tools.SpitIntArrary(id);
return ToResponse(ToJson(PostService.Delete(ids)));
return ToResponse(PostService.Delete(ids));
}
/// <summary>

View File

@ -3,12 +3,7 @@ using Infrastructure.Attribute;
using Infrastructure.Enums;
using Infrastructure.Model;
using Mapster;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System;
using System.Threading.Tasks;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Model.System;

View File

@ -11,6 +11,11 @@ using ZR.Service.System.IService;
using ZR.Admin.WebApi.Extensions;
using ZR.Model.System.Dto;
using Mapster;
using ZR.Service;
using Microsoft.AspNetCore.Authorization;
using Aliyun.OSS;
using MiniExcelLibs.OpenXml;
using MiniExcelLibs;
namespace ZR.Admin.WebApi.Controllers.System
{
@ -22,11 +27,14 @@ namespace ZR.Admin.WebApi.Controllers.System
public class SysRoleController : BaseController
{
private readonly ISysRoleService sysRoleService;
private readonly ISysMenuService sysMenuService;
public SysRoleController(
ISysRoleService sysRoleService)
ISysRoleService sysRoleService,
ISysMenuService sysMenuService)
{
this.sysRoleService = sysRoleService;
this.sysMenuService = sysMenuService;
}
/// <summary>
@ -58,16 +66,16 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <summary>
/// 添加角色
/// </summary>
/// <param name="sysRoleDto"></param>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "system:role:add")]
[Log(Title = "角色管理", BusinessType = BusinessType.INSERT)]
[Route("edit")]
public IActionResult RoleAdd([FromBody] SysRole sysRoleDto)
public IActionResult RoleAdd([FromBody] SysRoleDto dto)
{
if (sysRoleDto == null) return ToResponse(ApiResult.Error(101, "请求参数错误"));
if (dto == null) return ToResponse(ApiResult.Error(101, "请求参数错误"));
SysRole sysRoleDto = dto.Adapt<SysRole>();
if (UserConstants.NOT_UNIQUE.Equals(sysRoleService.CheckRoleKeyUnique(sysRoleDto)))
{
return ToResponse(ApiResult.Error((int)ResultCode.CUSTOM_ERROR, $"新增角色'{sysRoleDto.RoleName}'失败,角色权限已存在"));
@ -76,24 +84,25 @@ namespace ZR.Admin.WebApi.Controllers.System
sysRoleDto.Create_by = HttpContext.GetName();
long roleId = sysRoleService.InsertRole(sysRoleDto);
return ToResponse(ToJson(roleId));
return ToResponse(roleId);
}
/// <summary>
/// 修改角色
/// </summary>
/// <param name="sysRoleDto"></param>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "system:role:edit")]
[Log(Title = "角色管理", BusinessType = BusinessType.UPDATE)]
[Route("edit")]
public IActionResult RoleEdit([FromBody] SysRole sysRoleDto)
public IActionResult RoleEdit([FromBody] SysRoleDto dto)
{
if (sysRoleDto == null || sysRoleDto.RoleId <= 0 || string.IsNullOrEmpty(sysRoleDto.RoleKey))
if (dto == null || dto.RoleId <= 0 || string.IsNullOrEmpty(dto.RoleKey))
{
return ToResponse(ApiResult.Error(101, "请求参数错误"));
}
SysRole sysRoleDto = dto.Adapt<SysRole>();
sysRoleService.CheckRoleAllowed(sysRoleDto);
var info = sysRoleService.SelectRoleById(sysRoleDto.RoleId);
if (info != null && info.RoleKey != sysRoleDto.RoleKey)
@ -145,7 +154,7 @@ namespace ZR.Admin.WebApi.Controllers.System
long[] roleIds = Tools.SpitLongArrary(roleId);
int result = sysRoleService.DeleteRoleByRoleId(roleIds);
return ToResponse(ToJson(result));
return ToResponse(result);
}
/// <summary>
@ -161,7 +170,7 @@ namespace ZR.Admin.WebApi.Controllers.System
sysRoleService.CheckRoleAllowed(roleDto);
int result = sysRoleService.UpdateRoleStatus(roleDto);
return ToResponse(ToJson(result));
return ToResponse(result);
}
/// <summary>
@ -178,5 +187,23 @@ namespace ZR.Admin.WebApi.Controllers.System
string sFileName = ExportExcel(list, "sysrole", "角色");
return SUCCESS(new { path = "/export/" + sFileName, fileName = sFileName });
}
/// <summary>
/// 导出角色菜单
/// </summary>
/// <param name="roleId"></param>
/// <returns></returns>
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色菜单导出")]
[HttpGet("exportRoleMenu")]
[AllowAnonymous]
public IActionResult ExportRoleMenu(int roleId)
{
MenuQueryDto dto = new() { Status = "0", MenuTypeIds = "M,C,F" };
var list = sysMenuService.SelectRoleMenuListByRole(dto, roleId);
var result = ExportExcelMini(list, roleId.ToString(), "角色菜单");
return ExportExcel(result.Item2, result.Item1);
}
}
}

View File

@ -9,6 +9,7 @@ using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Model;
using ZR.Model.System;
using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System
@ -44,7 +45,7 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns>
[ActionPermissionFilter(Permission = "system:user:list")]
[HttpGet("list")]
public IActionResult List([FromQuery] SysUser user, PagerInfo pager)
public IActionResult List([FromQuery] SysUserQueryDto user, PagerInfo pager)
{
var list = UserService.SelectUserList(user, pager);
@ -76,7 +77,7 @@ namespace ZR.Admin.WebApi.Controllers.System
dic.Add("roleIds", sysUser.RoleIds);
}
return ToResponse(ApiResult.Success(dic));
return SUCCESS(dic);
}
/// <summary>
@ -132,7 +133,7 @@ namespace ZR.Admin.WebApi.Controllers.System
if (user == null) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
int result = UserService.ChangeUserStatus(user);
return ToResponse(ToJson(result));
return ToResponse(result);
}
/// <summary>
@ -149,7 +150,7 @@ namespace ZR.Admin.WebApi.Controllers.System
if (userid == 1) return ToResponse(Infrastructure.ResultCode.FAIL, "不能删除管理员账号");
int result = UserService.DeleteUser(userid);
return ToResponse(ToJson(result));
return ToResponse(result);
}
/// <summary>
@ -165,7 +166,7 @@ namespace ZR.Admin.WebApi.Controllers.System
sysUser.Password = NETCore.Encrypt.EncryptProvider.Md5(sysUser.Password);
int result = UserService.ResetPwd(sysUser.UserId, sysUser.Password);
return ToResponse(ToJson(result));
return ToResponse(result);
}
/// <summary>
@ -181,7 +182,7 @@ namespace ZR.Admin.WebApi.Controllers.System
List<SysUser> users = new();
using (var stream = formFile.OpenReadStream())
{
users = stream.Query<SysUser>().ToList();
users = stream.Query<SysUser>(startCell: "A2").ToList();
}
return SUCCESS(UserService.ImportUsers(users));
@ -208,7 +209,7 @@ namespace ZR.Admin.WebApi.Controllers.System
[HttpGet("export")]
[Log(Title = "用户导出", BusinessType = BusinessType.EXPORT)]
[ActionPermissionFilter(Permission = "system:user:export")]
public IActionResult UserExport([FromQuery] SysUser user)
public IActionResult UserExport([FromQuery] SysUserQueryDto user)
{
var list = UserService.SelectUserList(user, new PagerInfo(1, 10000));

View File

@ -64,7 +64,7 @@ namespace ZR.Admin.WebApi.Controllers.System
int result = tasksLogService.Delete(jobIdArr);
return ToResponse(ToJson(result, result));
return ToResponse(result);
}
/// <summary>

View File

@ -30,9 +30,9 @@ namespace ZR.Admin.WebApi.Controllers.monitor
/// </summary>
/// <returns></returns>
[HttpGet("monitor/cache")]
public ApiResult GetCache()
public IActionResult GetCache()
{
return ToJson(1);
return SUCCESS(1);
}
/// <summary>

View File

@ -65,15 +65,15 @@ namespace ZR.Admin.WebApi.Controllers.monitor
[Log(Title = "清空操作日志", BusinessType = BusinessType.CLEAN)]
[ActionPermissionFilter(Permission = "monitor:operlog:delete")]
[HttpDelete("clean")]
public ApiResult ClearOperLog()
public IActionResult ClearOperLog()
{
if (!HttpContextExtension.IsAdmin(HttpContext))
{
return ApiResult.Error("操作失败");
return ToResponse(Infrastructure.ResultCode.CUSTOM_ERROR,"操作失败");
}
sysOperLogService.CleanOperLog();
return ToJson(1);
return SUCCESS(1);
}
/// <summary>

View File

@ -1,6 +1,5 @@
using Infrastructure.Attribute;
using Microsoft.Extensions.DependencyInjection;
using System.Linq;
using Infrastructure;
using Infrastructure.Attribute;
using System.Reflection;
namespace ZR.Admin.WebApi.Extensions
@ -16,7 +15,11 @@ namespace ZR.Admin.WebApi.Extensions
/// <param name="services"></param>
public static void AddAppService(this IServiceCollection services)
{
string[] cls = new string[] { "ZR.Repository", "ZR.Service", "ZR.Tasks" };
var cls = AppSettings.Get<string[]>("InjectClass");
if (cls == null || cls.Length <= 0)
{
throw new Exception("请更新appsettings类");
}
foreach (var item in cls)
{
Register(services, item);

View File

@ -0,0 +1,27 @@
namespace ZR.Admin.WebApi.Extensions
{
public static class CorsExtension
{
/// <summary>
/// 跨域配置
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddCors(this IServiceCollection services, IConfiguration configuration)
{
var corsUrls = configuration["corsUrls"]?.Split(',', StringSplitOptions.RemoveEmptyEntries);
//配置跨域
services.AddCors(c =>
{
c.AddPolicy("Policy", policy =>
{
policy.WithOrigins(corsUrls ?? Array.Empty<string>())
.AllowAnyHeader()//允许任意头
.AllowCredentials()//允许cookie
.AllowAnyMethod();//允许任意方法
});
});
}
}
}

View File

@ -1,13 +1,16 @@
using Infrastructure;
using Infrastructure.Helper;
using Infrastructure.Extensions;
using SqlSugar;
using SqlSugar.IOC;
using System.Reflection;
using ZR.Admin.WebApi.Framework;
using ZR.Model;
using ZR.Model.System;
namespace ZR.Admin.WebApi.Extensions
{
/// <summary>
/// sqlsugar 数据处理
/// </summary>
public static class DbExtension
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
@ -22,42 +25,60 @@ namespace ZR.Admin.WebApi.Extensions
//仅本人数据权限
public static long DATA_SCOPE_SELF = 5;
public static void AddDb(IConfiguration Configuration)
/// <summary>
/// 初始化db
/// </summary>
/// <param name="services"></param>
/// <param name="Configuration"></param>
/// <param name="environment"></param>
public static void AddDb(this IServiceCollection services, IConfiguration Configuration, IWebHostEnvironment environment)
{
string connStr = Configuration.GetConnectionString("conn_db");
int dbType = Convert.ToInt32(Configuration.GetConnectionString("conn_db_type"));
List<DbConfigs> dbConfigs = Configuration.GetSection("DbConfigs").Get<List<DbConfigs>>();
var iocList = new List<IocConfig>() {
new IocConfig() {
ConfigId = "0",//默认db
ConnectionString = connStr,
DbType = (IocDbType)dbType,
IsAutoCloseConnection = true
},
new IocConfig() {
ConfigId = "1",
ConnectionString = connStr,
DbType = (IocDbType)dbType,
IsAutoCloseConnection = true
}
};
var iocList = new List<IocConfig>();
foreach (var item in dbConfigs.FindAll(f => !f.IsGenerateDb))
{
iocList.Add(new IocConfig()
{
ConfigId = item.ConfigId,
ConnectionString = item.Conn,
DbType = (IocDbType)item.DbType,
IsAutoCloseConnection = item.IsAutoCloseConnection
});
}
SugarIocServices.AddSqlSugar(iocList);
ICacheService cache = new SqlSugarCache();
SugarIocServices.ConfigurationSugar(db =>
{
//db0数据过滤
FilterData(0);
var u = App.User;
if (u != null)
{
FilterData(0);
//ConfigId = 1的数据权限过滤
//FilterData1(1);
}
iocList.ForEach(iocConfig =>
{
SetSugarAop(db, iocConfig, cache);
});
});
if (Configuration["InitDb"].ParseToBool() == true && environment.IsDevelopment())
{
InitTable.InitDb();
}
}
/// <summary>
/// 数据库Aop设置
/// </summary>
/// <param name="db"></param>
/// <param name="iocConfig"></param>
/// <param name="cache"></param>
private static void SetSugarAop(SqlSugarClient db, IocConfig iocConfig, ICacheService cache)
{
var config = db.GetConnection(iocConfig.ConfigId).CurrentConnectionConfig;
var config = db.GetConnectionScope(iocConfig.ConfigId).CurrentConnectionConfig;
string configId = config.ConfigId;
db.GetConnectionScope(configId).Aop.OnLogExecuting = (sql, pars) =>
@ -81,7 +102,6 @@ namespace ZR.Admin.WebApi.Extensions
logger.Info(log);
}
};
db.GetConnectionScope(configId).Aop.OnError = (ex) =>
{
var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
@ -89,6 +109,9 @@ namespace ZR.Admin.WebApi.Extensions
string sql = "【错误SQL】" + UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n";
logger.Error(ex, $"{sql}\r\n{ex.Message}\r\n{ex.StackTrace}");
};
db.GetConnectionScope(configId).Aop.DataExecuting = (oldValue, entiyInfo) =>
{
};
db.GetConnectionScope(configId).CurrentConnectionConfig.MoreSettings = new ConnMoreSettings()
{
@ -99,29 +122,58 @@ namespace ZR.Admin.WebApi.Extensions
DataInfoCacheService = cache,
EntityService = (c, p) =>
{
if (db.GetConnectionScope(configId).CurrentConnectionConfig.DbType == DbType.PostgreSQL && p.DataType != null && p.DataType.Contains("nvarchar"))
if (p.IsPrimarykey == true)//主键不能为null
{
p.DataType = "text";
p.IsNullable = false;
}
else if (p.ExtendedAttribute?.ToString() == ProteryConstant.NOTNULL.ToString())
{
p.IsNullable = false;
}
else//则否默认为null
{
p.IsNullable = true;
}
if (config.DbType == DbType.PostgreSQL)
{
if (c.Name == nameof(SysMenu.IsCache) || c.Name == nameof(SysMenu.IsFrame))
{
p.DataType = "char(1)";
}
}
#region Oracle
if (config.DbType == DbType.Oracle)
{
if (p.IsIdentity == true)
{
if (p.EntityName == nameof(SysUser))
{
p.OracleSequenceName = "SEQ_SYS_USER_USERID";
}
else if (p.EntityName == nameof(SysRole))
{
p.OracleSequenceName = "SEQ_SYS_ROLE_ROLEID";
}
else if (p.EntityName == nameof(SysDept))
{
p.OracleSequenceName = "SEQ_SYS_DEPT_DEPTID";
}
else if (p.EntityName == nameof(SysMenu))
{
p.OracleSequenceName = "SEQ_SYS_MENU_MENUID";
}
else
{
p.OracleSequenceName = "SEQ_ID";
}
}
}
#endregion
}
};
}
/// <summary>
/// 初始化db
/// </summary>
/// <param name="service"></param>
public static void InitDb(this IServiceProvider service)
{
var db = DbScoped.SugarScope;
//建库:如果不存在创建数据库存在不会重复创建
db.DbMaintenance.CreateDatabase();// 注意 Oracle和个别国产库需不支持该方法需要手动建库
var baseType = typeof(SysBase);
var entityes = AssemblyUtils.GetAllTypes().Where(p => !p.IsAbstract && p != baseType && /*p.IsAssignableTo(baseType) && */p.GetCustomAttribute<SugarTable>() != null).ToArray();
db.CodeFirst.SetStringDefaultLength(200).InitTables(entityes);
}
private static object GetParsValue(SugarParameter x)
{
if (x.DbType == System.Data.DbType.String || x.DbType == System.Data.DbType.DateTime || x.DbType == System.Data.DbType.String)
@ -137,8 +189,6 @@ namespace ZR.Admin.WebApi.Extensions
/// <param name="configId">多库id</param>
private static void FilterData(int configId)
{
var u = App.User;
if (u == null) return;
//获取当前用户的信息
var user = JwtUtil.GetLoginUser(App.HttpContext);
if (user == null) return;
@ -159,7 +209,7 @@ namespace ZR.Admin.WebApi.Extensions
else if (DATA_SCOPE_CUSTOM.Equals(dataScope))//自定数据权限
{
//" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
expUser.Or(it => SqlFunc.Subqueryable<SysRoleDept>().Where(f => f.DeptId == it.DeptId && f.RoleId == role.RoleId).Any());
}
else if (DATA_SCOPE_DEPT.Equals(dataScope))//本部门数据
@ -184,5 +234,35 @@ namespace ZR.Admin.WebApi.Extensions
db.QueryFilter.AddTableFilter(expLoginlog.ToExpression());
}
}
private static void FilterData1(int configId)
{
//获取当前用户的信息
var user = JwtUtil.GetLoginUser(App.HttpContext);
if (user == null) return;
var db = DbScoped.SugarScope.GetConnectionScope(configId);
foreach (var role in user.Roles.OrderBy(f => f.DataScope))
{
long dataScope = role.DataScope;
if (DATA_SCOPE_ALL.Equals(dataScope))//所有权限
{
break;
}
else if (DATA_SCOPE_CUSTOM.Equals(dataScope))//自定数据权限
{
}
else if (DATA_SCOPE_DEPT.Equals(dataScope))//本部门数据
{
}
else if (DATA_SCOPE_DEPT_AND_CHILD.Equals(dataScope))//本部门及以下数据
{
}
else if (DATA_SCOPE_SELF.Equals(dataScope))//仅本人数据
{
}
}
}
}
}

View File

@ -0,0 +1,53 @@
using SqlSugar.IOC;
using ZR.Model.Models;
using ZR.Model.System;
using ZR.Model.System.Generate;
namespace ZR.Admin.WebApi.Extensions
{
/// <summary>
/// 初始化表
/// </summary>
public class InitTable
{
/// <summary>
/// 创建db、表
/// </summary>
public static void InitDb()
{
var db = DbScoped.SugarScope;
//建库:如果不存在创建数据库存在不会重复创建
db.DbMaintenance.CreateDatabase();// 注意 Oracle和个别国产库需不支持该方法需要手动建库
//var baseType = typeof(SysBase);
//var entityes = AssemblyUtils.GetAllTypes().Where(p => !p.IsAbstract && p != baseType && p.GetCustomAttribute<SugarTable>() != null).ToArray();
//db.CodeFirst.InitTables(entityes);
//23个表,建议先使用下面方法初始化表,方便排查问题
db.CodeFirst.InitTables(typeof(SysUser));
db.CodeFirst.InitTables(typeof(SysRole));
db.CodeFirst.InitTables(typeof(SysDept));
db.CodeFirst.InitTables(typeof(SysPost));
db.CodeFirst.InitTables(typeof(SysFile));
db.CodeFirst.InitTables(typeof(SysConfig));
db.CodeFirst.InitTables(typeof(SysNotice));
db.CodeFirst.InitTables(typeof(SysLogininfor));
db.CodeFirst.InitTables(typeof(SysOperLog));
db.CodeFirst.InitTables(typeof(SysMenu));
db.CodeFirst.InitTables(typeof(SysRoleMenu));
db.CodeFirst.InitTables(typeof(SysRoleDept));
db.CodeFirst.InitTables(typeof(SysUserRole));
db.CodeFirst.InitTables(typeof(SysUserPost));
db.CodeFirst.InitTables(typeof(SysTasks));
db.CodeFirst.InitTables(typeof(SysTasksLog));
db.CodeFirst.InitTables(typeof(CommonLang));
db.CodeFirst.InitTables(typeof(GenTable));
db.CodeFirst.InitTables(typeof(GenTableColumn));
db.CodeFirst.InitTables(typeof(Article));
db.CodeFirst.InitTables(typeof(ArticleCategory));
db.CodeFirst.InitTables(typeof(SysDictData));
db.CodeFirst.InitTables(typeof(SysDictType));
}
}
}

View File

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using System.Reflection;
namespace ZR.Admin.WebApi.Extensions
{
@ -38,7 +39,7 @@ namespace ZR.Admin.WebApi.Extensions
public static void AddSwaggerConfig(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));
//IWebHostEnvironment hostEnvironment = App.GetRequiredService<IWebHostEnvironment>();
//IWebHostEnvironment hostEnvironment = services.BuildServiceProvider().GetRequiredService<IWebHostEnvironment>();
services.AddSwaggerGen(c =>
{
@ -50,11 +51,14 @@ namespace ZR.Admin.WebApi.Extensions
});
try
{
var tempPath = "";// hostEnvironment.ContentRootPath;
//var tempPath = hostEnvironment.ContentRootPath;
//添加文档注释
c.IncludeXmlComments(Path.Combine(tempPath, "ZRAdmin.xml"), true);
c.IncludeXmlComments(Path.Combine(tempPath, "ZRModel.xml"), true);
//c.IncludeXmlComments(Path.Combine(Directory.GetParent(tempPath).FullName, "ZR.Model", "ZRModel.xml"), true);
var baseDir = AppContext.BaseDirectory;
c.IncludeXmlComments(Path.Combine(baseDir, "ZR.Model.xml"), true);
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(baseDir, xmlFile);
c.IncludeXmlComments(xmlPath);
}
catch (Exception ex)
{

View File

@ -1,8 +1,6 @@
using Infrastructure;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Quartz.Spi;
using System;
using Quartz.Spi;
using SqlSugar.IOC;
using ZR.Model.System;
using ZR.Tasks;
namespace ZR.Admin.WebApi.Extensions
@ -12,6 +10,11 @@ namespace ZR.Admin.WebApi.Extensions
/// </summary>
public static class TasksExtension
{
/// <summary>
/// 注册任务
/// </summary>
/// <param name="services"></param>
/// <exception cref="ArgumentNullException"></exception>
public static void AddTaskSchedulers(this IServiceCollection services)
{
if (services == null) throw new ArgumentNullException(nameof(services));
@ -30,11 +33,11 @@ namespace ZR.Admin.WebApi.Extensions
{
ITaskSchedulerServer _schedulerServer = app.ApplicationServices.GetRequiredService<ITaskSchedulerServer>();
var tasks = SqlSugar.IOC.DbScoped.SugarScope.Queryable<Model.System.SysTasks>()
.Where(m => m.IsStart == 1).ToList();
var tasks = DbScoped.SugarScope.Queryable<SysTasks>()
.Where(m => m.IsStart == 1).ToListAsync();
//程序启动后注册所有定时任务
foreach (var task in tasks)
foreach (var task in tasks.Result)
{
var result = _schedulerServer.AddTaskScheduleAsync(task);
if (result.Result.Code == 200)

View File

@ -2,7 +2,7 @@
using Infrastructure.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using ZR.Model.System;
using ZR.Model.System.Dto;
namespace ZR.Admin.WebApi.Filters
{

View File

@ -9,7 +9,7 @@ using System;
using System.Linq;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Framework;
using ZR.Model.System;
using ZR.Model.System.Dto;
namespace ZR.Admin.WebApi.Filters
{

View File

@ -6,7 +6,7 @@ using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using ZR.Admin.WebApi.Extensions;
using ZR.Model.System;
using ZR.Model.System.Dto;
using ZR.Service.System;
namespace ZR.Admin.WebApi.Framework

View File

@ -119,7 +119,8 @@ namespace ZR.Admin.WebApi.Middleware
context.Response.ContentType = "text/json;charset=utf-8";
await context.Response.WriteAsync(responseResult, System.Text.Encoding.UTF8);
string errorMsg = $"> 操作人:{sysOperLog.OperName} {sysOperLog.OperLocation}" +
string errorMsg = $"> 操作人:{sysOperLog.OperName}" +
$"\n> 操作地区:{sysOperLog.OperIp}({sysOperLog.OperLocation})" +
$"\n> 操作模块:{sysOperLog.Title}" +
$"\n> 操作地址:{sysOperLog.OperUrl}" +
$"\n> 错误信息:{msg}\n\n> {error}";

View File

@ -1,14 +1,14 @@
using AspNetCoreRateLimit;
using Infrastructure;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.DataProtection;
using ZR.Admin.WebApi.Framework;
using Infrastructure.Extensions;
using Microsoft.IdentityModel.Tokens;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Admin.WebApi.Middleware;
using ZR.Admin.WebApi.Framework;
using ZR.Admin.WebApi.Hubs;
using ZR.Admin.WebApi.Middleware;
using ZR.Common.Cache;
using AspNetCoreRateLimit;
var builder = WebApplication.CreateBuilder(args);
@ -20,19 +20,8 @@ builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//注入HttpContextAccessor
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var corsUrls = builder.Configuration["corsUrls"]?.Split(',', StringSplitOptions.RemoveEmptyEntries);
//配置跨域
builder.Services.AddCors(c =>
{
c.AddPolicy("Policy", policy =>
{
policy.WithOrigins(corsUrls ?? Array.Empty<string>())
.AllowAnyHeader()//允许任意头
.AllowCredentials()//允许cookie
.AllowAnyMethod();//允许任意方法
});
});
// 跨域配置
builder.Services.AddCors(builder.Configuration);
// 显示logo
builder.Services.AddLogo();
//注入SignalR实时通讯默认用json传输
@ -58,15 +47,26 @@ builder.Services.AddAuthentication(options =>
.AddJwtBearer(o =>
{
o.TokenValidationParameters = JwtUtil.ValidParameters();
o.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{
// 如果过期,把过期信息添加到头部
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
//InternalApp.InternalServices = builder.Services;
builder.Services.AddAppService();
builder.Services.AddSingleton(new AppSettings(builder.Configuration));
builder.Services.AddAppService();
//开启计划任务
builder.Services.AddTaskSchedulers();
//初始化db
DbExtension.AddDb(builder.Configuration);
//注册REDIS 服务
var openRedis = builder.Configuration["RedisServer:open"];
@ -89,12 +89,11 @@ builder.Services.AddSwaggerConfig();
var app = builder.Build();
InternalApp.ServiceProvider = app.Services;
if (builder.Configuration["InitDb"].ParseToBool() == true && app.Environment.IsDevelopment())
{
app.Services.InitDb();
}
//初始化db
builder.Services.AddDb(builder.Configuration, app.Environment);
app.UseSwagger();
//使用全局异常中间件
app.UseMiddleware<GlobalExceptionMiddleware>();
//使可以多次多去body内容
app.Use((context, next) =>
@ -120,8 +119,8 @@ app.UseAuthorization();
app.UseResponseCaching();
//恢复/启动任务
app.UseAddTaskSchedulers();
//使用全局异常中间件
app.UseMiddleware<GlobalExceptionMiddleware>();
//使用swagger
app.UseSwagger();
//启用客户端IP限制速率
app.UseIpRateLimiting();
app.UseRateLimiter();

View File

@ -3,10 +3,9 @@
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>ZRAdmin.xml</DocumentationFile>
<NoWarn>1701;1702;1591,8603,8602,8604,8600</NoWarn>
</PropertyGroup>

View File

@ -6,23 +6,38 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
"ConnectionStrings": {
"conn_db": "server=8.140.174.251;user=admin;pwd=admin123;database=ZrAdmin", //
"conn_db_type": "0" // MySql = 0, SqlServer = 1, Oracle = 3PgSql = 4
},
"dbConfigs": [
{
"Conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog=ZrAdmin;",
"DbType": 1, // MySql = 0, SqlServer = 1, Oracle = 3PgSql = 4
"ConfigId": "0", //
"IsAutoCloseConnection": true
},
{
//{dbName}
"Conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog={dbName};",
"DbType": 1,
"ConfigId": "0",
"IsAutoCloseConnection": true,
"DbName": "ZrAdmin", //
"IsGenerateDb": true //使
}
//...
],
"urls": "http://localhost:8888", //urldevServer
"corsUrls": "http://localhost:8887", //","
"JwtSettings": {
"Issuer": "ZRAdmin.NET",
"Audience": "ZRAdmin.NET",
"Issuer": "ZRAdmin.NET", //token
"Audience": "ZRAdmin.NET", //token
"SecretKey": "SecretKey-ZRADMIN.NET-20210101",
"Expire": 1440 //jwt
},
"InitDb": false,//db
"InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks" ], //
"InitDb": false, //db
"DemoMode": false, //
"Upload": {
"uploadUrl": "http://localhost:8888", //访
"localSavePath": "uploads", // wwwroot/uploads
"localSavePath": "uploads", // wwwroot/uploads, saveType= 2 使, /home/resource)
"maxSize": 15, // 15M
"notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ]
},
@ -42,19 +57,19 @@
"CorpSecret": "",
"SendUser": "@all"
},
//
"gen": {
"conn": "Data Source=LAPTOP-STKF2M8H\\SQLEXPRESS;User ID=admin;Password=admin123;Initial Catalog=ZrAdmin;",
"dbType": 1, //MySql = 0, SqlServer = 1
"autoPre": true, //
"author": "admin",
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
"vuePath": "", //egD:\Work\ZRAdmin-Vue3
"oracle_db": ""
"vuePath": "" //egD:\Work\ZRAdmin-Vue3
},
//
"MailOptions": {
//
"FromName": "system",
//
"From": "", //egxxxx@qq.com
"FromEmail": "", //egxxxx@qq.com
//
"Password": "123456",
//

View File

@ -70,7 +70,8 @@ $end
{
var response = _${replaceDto.ModelTypeName}Service.GetFirst(x => x.${replaceDto.PKName} == ${replaceDto.PKName});
return SUCCESS(response);
var info = response.Adapt<${replaceDto.ModelTypeName}>();
return SUCCESS(info);
}
$if(replaceDto.ShowBtnAdd)

View File

@ -1,6 +1,7 @@
using System;
using SqlSugar;
using Infrastructure.Attribute;
using Infrastructure.Extensions;
using ${options.BaseNamespace}Model;
using ${options.DtosNamespace};
using ${options.ModelsNamespace}.${options.SubNamespace};

View File

@ -0,0 +1 @@
请勾选 添加菜单 ,将会自动导入菜单到数据库中

View File

@ -120,9 +120,7 @@ $if(column.HtmlType == "customInput" && column.IsPk == false)
$elseif(column.HtmlType == "imageUpload")
<el-table-column prop="${columnName}" label="${labelName}" align="center">
<template #default="scope">
<el-image preview-teleported :hide-on-click-modal="true" lazy class="table-td-thumb" fit="contain" :src="scope.row.${columnName}" :preview-src-list="[scope.row.${columnName}]">
<div><el-icon :size="15"><document /></el-icon></div>
</el-image>
<ImagePreview :src="scope.row.${columnName}"></ImagePreview>
</template>
</el-table-column>
$elseif(column.HtmlType == "checkbox" || column.HtmlType == "select" || column.HtmlType == "radio")

View File

@ -179,18 +179,7 @@ $if(column.HtmlType == "customInput" && column.IsPk == false)
$elseif(column.HtmlType == "imageUpload")
<el-table-column prop="${columnName}" label="${labelName}" align="center" v-if="columns.showColumn('${columnName}')">
<template #default="scope">
<el-image
preview-teleported
:hide-on-click-modal="true"
lazy
class="table-td-thumb"
fit="contain"
:src="scope.row.${columnName}"
:preview-src-list="[scope.row.${columnName}]">
<div>
<el-icon :size="15"><document /></el-icon>
</div>
</el-image>
<ImagePreview :src="scope.row.${columnName}"></ImagePreview>
</template>
</el-table-column>
$elseif(column.HtmlType == "checkbox" || column.HtmlType.Contains("select") || column.HtmlType == "radio")

Binary file not shown.

View File

@ -50,6 +50,7 @@ namespace ZR.CodeGenerator
ShowBtnView = dto.GenTable.Options.CheckedBtn.Any(f => f == 5),
ShowBtnTruncate = dto.GenTable.Options.CheckedBtn.Any(f => f == 6),
ShowBtnMultiDel = dto.GenTable.Options.CheckedBtn.Any(f => f == 7),
ViewFileName = dto.GenTable.BusinessName.FirstUpperCase()
};
var columns = dto.GenTable.Columns;
@ -67,7 +68,7 @@ namespace ZR.CodeGenerator
GenerateControllers(replaceDto, dto);
if (dto.VueVersion == 3)
{
GenerateVue3Views(dto);
GenerateVue3Views(replaceDto, dto);
}
else
{
@ -79,7 +80,7 @@ namespace ZR.CodeGenerator
}
GenerateVueJs(dto);
GenerateSql(dto);
dto.ReplaceDto = replaceDto;
if (dto.IsPreview) return;
foreach (var item in dto.GenCodes)
@ -182,7 +183,7 @@ namespace ZR.CodeGenerator
replaceDto.VueViewFormHtml = GenerateCurdForm();
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName);
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{generateDto.GenTable.BusinessName.FirstUpperCase()}.vue");
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue");
generateDto.GenCodes.Add(new GenCode(6, "index.vue", fullPath, tpl.Render()));
}
@ -191,7 +192,7 @@ namespace ZR.CodeGenerator
/// vue3
/// </summary>
/// <param name="generateDto"></param>
private static void GenerateVue3Views(GenerateDto generateDto)
private static void GenerateVue3Views(ReplaceDto replaceDto, GenerateDto generateDto)
{
string fileName = generateDto.GenTable.TplCategory switch
{
@ -206,7 +207,7 @@ namespace ZR.CodeGenerator
tpl.Set("options", generateDto.GenTable?.Options);
var result = tpl.Render();
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{generateDto.GenTable.BusinessName.FirstUpperCase()}.vue");
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));
}
@ -240,21 +241,13 @@ namespace ZR.CodeGenerator
/// <param name="generateDto"></param>
public static void GenerateSql(GenerateDto generateDto)
{
var tempName = "";
switch (generateDto.DbType)
string tempName = generateDto.DbType switch
{
case 0:
tempName = "MySqlTemplate";
break;
case 1:
tempName = "SqlTemplate";
break;
case 4:
tempName = "PgSql";
break;
default:
break;
}
0 => "MySqlTemplate",
1 => "SqlTemplate",
4 => "PgSql",
_ => "Other",
};
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, Path.Combine("sql", $"{tempName}.txt"));
tpl.Set("parentId", generateDto.GenTable?.Options?.ParentMenuId ?? 0);
var result = tpl.Render();
@ -315,18 +308,8 @@ namespace ZR.CodeGenerator
}
}
}
return tableName.UnderScoreToCamelCase();
}
/// <summary>
/// 获取前端标签名
/// </summary>
/// <param name="columnDescription"></param>
/// <param name="columnName"></param>
/// <returns></returns>
public static string GetLabelName(string columnDescription, string columnName)
{
return string.IsNullOrEmpty(columnDescription) ? columnName : columnDescription;
//return tableName.UnderScoreToCamelCase();
return tableName.ConvertToPascal("_");
}
/// <summary>
@ -343,7 +326,7 @@ namespace ZR.CodeGenerator
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return "";
return str;
}
}
@ -357,8 +340,8 @@ namespace ZR.CodeGenerator
sDatatype = sDatatype.ToLower();
string sTempDatatype = sDatatype switch
{
"int" or "number" or "integer" or "smallint" or "int4" or "int8" or "int2" => "int",
"bigint" => "long",
"int" or "integer" or "smallint" or "int4" or "int8" or "int2" => "int",
"bigint" or "number" => "long",
"tinyint" => "byte",
"numeric" or "real" or "float" => "float",
"decimal" or "numer(8,2)" or "numeric" => "decimal",
@ -389,8 +372,8 @@ namespace ZR.CodeGenerator
DbName = dbName,
BaseNameSpace = "ZR.",//导入默认命名空间前缀
ModuleName = "business",//导入默认模块名
ClassName = GetClassName(tableName).FirstUpperCase(),
BusinessName = tableName.UnderScoreToCamelCase().FirstUpperCase(),
ClassName = GetClassName(tableName),
BusinessName = GetClassName(tableName),
FunctionAuthor = AppSettings.GetConfig(GenConstants.Gen_author),
TableName = tableName,
TableComment = desc,
@ -412,12 +395,13 @@ namespace ZR.CodeGenerator
/// </summary>
/// <param name="genTable"></param>
/// <param name="dbColumnInfos"></param>
public static List<GenTableColumn> InitGenTableColumn(GenTable genTable, List<DbColumnInfo> dbColumnInfos)
/// <param name="seqs"></param>
public static List<GenTableColumn> InitGenTableColumn(GenTable genTable, List<DbColumnInfo> dbColumnInfos, List<OracleSeq> seqs = null)
{
List<GenTableColumn> genTableColumns = new();
foreach (var column in dbColumnInfos)
{
genTableColumns.Add(InitColumnField(genTable, column));
genTableColumns.Add(InitColumnField(genTable, column, seqs));
}
return genTableColumns;
}
@ -428,17 +412,26 @@ namespace ZR.CodeGenerator
/// <param name="genTable"></param>
/// <param name="column"></param>
/// <returns></returns>
private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column)
private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column, List<OracleSeq> seqs)
{
var dbConfig = AppSettings.Get<List<DbConfigs>>("dbConfigs").FirstOrDefault(f => f.IsGenerateDb);
var dataType = column.DataType;
if (dbConfig.DbType == 3)
{
dataType = column.OracleDataType;
var seqName = $"SEQ_{genTable.TableName}_{column.DbColumnName}";
var isIdentity = seqs.Any(f => seqName.Equals(f.SEQUENCE_NAME, StringComparison.CurrentCultureIgnoreCase));
column.IsIdentity = isIdentity;
}
GenTableColumn genTableColumn = new()
{
ColumnName = column.DbColumnName.FirstLowerCase(),
ColumnComment = column.ColumnDescription,
IsPk = column.IsPrimarykey,
ColumnType = column.DataType,
ColumnType = dataType,
TableId = genTable.TableId,
TableName = genTable.TableName,
CsharpType = GetCSharpDatatype(column.DataType),
CsharpType = GetCSharpDatatype(dataType),
CsharpField = column.DbColumnName.ConvertToPascal("_"),
IsRequired = !column.IsNullable,
IsIncrement = column.IsIdentity,

View File

@ -1,5 +1,4 @@
using Infrastructure;
using Infrastructure.Extensions;
using SqlSugar;
using System;
using System.Collections.Generic;
@ -21,27 +20,22 @@ namespace ZR.CodeGenerator
/// <returns></returns>
public SqlSugarClient GetSugarDbContext(string dbName = "")
{
Gen options = new();
AppSettings.Bind("gen", options);
string connStr = options.Conn;
List<DbConfigs> dbConfigs = AppSettings.Get<List<DbConfigs>>("dbConfigs");
DbConfigs configs = dbConfigs.Find(f => f.IsGenerateDb == true);
string connStr = configs.Conn;
if (!string.IsNullOrEmpty(dbName))
{
string replaceStr = GetValue(options.Conn, "Database=", ";");
string replaceStr2 = GetValue(options.Conn, "Initial Catalog=", ";");
if (replaceStr.IsNotEmpty())
{
connStr = options.Conn.Replace(replaceStr, dbName, StringComparison.OrdinalIgnoreCase);
}
if (replaceStr2.IsNotEmpty())
{
connStr = options.Conn.Replace(replaceStr2, dbName, StringComparison.OrdinalIgnoreCase);
}
configs.DbName = dbName;
}
connStr = connStr.Replace("{dbName}", configs.DbName, StringComparison.OrdinalIgnoreCase);
var db = new SqlSugarClient(new List<ConnectionConfig>()
{
new ConnectionConfig(){
ConnectionString = connStr,
DbType = (DbType)options.DbType,
DbType = (DbType)configs.DbType,
IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样
InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
},

View File

@ -7,17 +7,14 @@ namespace ZR.CodeGenerator
/// </summary>
public class GenConstants
{
public static string Gen_conn = "gen:conn";
public static string Gen_conn_dbType = "gen:dbType";
public static string Gen_author = "gen:author";
public static string Gen_autoPre = "gen:autoPre";
public static string Gen_tablePrefix = "gen:tablePrefix";
public static string Gen_oracle_db = "gen:oracle_db";
/// <summary>
/// InputDto输入实体是不包含字段
/// </summary>
public static readonly string[] inputDtoNoField = new string[] { "createTime", "updateTime", "addtime", "create_time", "update_time" };
public static readonly string[] inputDtoNoField = new string[] { "createTime", "updateTime", "addtime", "create_time", "update_time", "create_by", "update_by" };
/// <summary>
/// 图片字段
/// </summary>
@ -29,7 +26,7 @@ namespace ZR.CodeGenerator
/// <summary>
/// 单选按钮字段
/// </summary>
public static readonly string[] radioFiled = new string[] { "status", "state", "is"};
public static readonly string[] radioFiled = new string[] { "status", "state", "is" };
/// <summary>

View File

@ -58,6 +58,7 @@ namespace ZR.CodeGenerator.Model
/// </summary>
public string VueParentPath { get; set; }
#endregion
public ReplaceDto ReplaceDto { get; set; }
}
public class GenCode

View File

@ -0,0 +1,11 @@
namespace ZR.CodeGenerator.Model
{
/// <summary>
/// Oracle库序列
/// </summary>
public class OracleSeq
{
public string SEQUENCE_NAME { get; set; }
public long LAST_NUMBER { get; set; }
}
}

View File

@ -65,5 +65,9 @@ namespace ZR.CodeGenerator.Model
/// 是否有编辑器
/// </summary>
public int ShowEditor { get; set; }
/// <summary>
/// vue页面文件名
/// </summary>
public string ViewFileName { get; set; }
}
}

View File

@ -2,6 +2,7 @@
using SqlSugar;
using System.Collections.Generic;
using System.Linq;
using ZR.CodeGenerator.Model;
using ZR.Model;
namespace ZR.CodeGenerator.Service
@ -16,15 +17,15 @@ namespace ZR.CodeGenerator.Service
{
var db = GetSugarDbContext();
//Oracle库特殊处理
var dbType = AppSettings.GetAppConfig(GenConstants.Gen_conn_dbType, 0);
if (dbType == 3)
List<DbConfigs> dbConfigs = AppSettings.Get<List<DbConfigs>>("dbConfigs");
DbConfigs configs = dbConfigs.Find(f => f.IsGenerateDb == true);
if (configs.DbType == 3)
{
var defaultDb = AppSettings.GetAppConfig(GenConstants.Gen_oracle_db, string.Empty);
return new List<string>() { defaultDb };
return new List<string>() { configs?.DbName };
}
var templist = db.DbMaintenance.GetDataBaseList(db);
return templist;
return templist.FindAll(f => !f.Contains("schema"));
}
/// <summary>
@ -72,5 +73,18 @@ namespace ZR.CodeGenerator.Service
{
return GetSugarDbContext(dbName).DbMaintenance.GetColumnInfosByTableName(tableName, true);
}
/// <summary>
/// 获取Oracle所有序列
/// </summary>
/// <param name="dbName"></param>
/// <returns></returns>
public List<OracleSeq> GetAllOracleSeqs(string dbName)
{
string sql = "SELECT * FROM USER_SEQUENCES";
var seqs = GetSugarDbContext(dbName).Ado.SqlQuery<OracleSeq>(sql);
return seqs.ToList();
}
}
}

View File

@ -12,6 +12,6 @@
<ItemGroup>
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.73" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.84-preview10" />
</ItemGroup>
</Project>

View File

@ -14,50 +14,18 @@ namespace ZR.Common
/// 发送人邮箱
/// </summary>
public string FromEmail { get; set; } = "";
/// <summary>
/// 发送人密码
/// </summary>
public string FromPwd { get; set; } = "";
/// <summary>
/// 发送协议
/// </summary>
public string Smtp { get; set; } = "smtp.qq.com";
/// <summary>
/// 协议端口
/// </summary>
public int Port { get; set; } = 587;
/// <summary>
/// 邮件签名
/// </summary>
public string Signature { get; set; }
/// <summary>
/// 是否使用SSL协议
/// </summary>
public bool UseSsl { get; set; } = false;
private readonly MailOptions mailOptions = new();
public MailHelper()
{
AppSettings.Bind("MailOptions", mailOptions);
FromEmail = mailOptions.From;
Smtp = mailOptions.Smtp;
FromPwd = mailOptions.Password;
Port = mailOptions.Port;
FromEmail= mailOptions.FromEmail;
}
public MailHelper(string fromEmail, string smtp, int port, string fromPwd)
public MailHelper(MailOptions _mailOptions)
{
FromEmail = fromEmail;
Smtp = smtp;
FromPwd = fromPwd;
Port = port;
this.mailOptions = _mailOptions;
FromEmail = _mailOptions.FromEmail;
}
public MailHelper(string fromEmail, string fromPwd)
{
FromEmail = fromEmail;
FromPwd = fromPwd;
}
/// <summary>
/// 发送一个
/// </summary>
@ -65,13 +33,13 @@ namespace ZR.Common
/// <param name="subject"></param>
/// <param name="text"></param>
/// <param name="path"></param>
public void SendMail(string toAddress, string subject, string text, string path = "", string html = "")
public string SendMail(string toAddress, string subject, string text, string path = "", string html = "")
{
IEnumerable<MailboxAddress> mailboxes = new List<MailboxAddress>() {
new MailboxAddress(toAddress, toAddress)
};
SendMail(mailboxes, subject, text, path, html);
return SendMail(mailboxes, subject, text, path, html);
}
/// <summary>
@ -81,7 +49,7 @@ namespace ZR.Common
/// <param name="subject"></param>
/// <param name="text"></param>
/// <param name="path"></param>
public void SendMail(string[] toAddress, string subject, string text, string path = "", string html = "")
public string SendMail(string[] toAddress, string subject, string text, string path = "", string html = "")
{
IList<MailboxAddress> mailboxes = new List<MailboxAddress>() { };
foreach (var item in toAddress)
@ -89,7 +57,7 @@ namespace ZR.Common
mailboxes.Add(new MailboxAddress(item, item));
}
SendMail(mailboxes, subject, text, path, html);
return SendMail(mailboxes, subject, text, path, html);
}
/// <summary>
@ -100,16 +68,16 @@ namespace ZR.Common
/// <param name="text"></param>
/// <param name="path">附件url地址</param>
/// <param name="html">网页HTML内容</param>
private void SendMail(IEnumerable<MailboxAddress> toAddress, string subject, string text, string path = "", string html = "")
private string SendMail(IEnumerable<MailboxAddress> toAddress, string subject, string text, string path = "", string html = "")
{
MimeMessage message = new MimeMessage();
//发件人
message.From.Add(new MailboxAddress(FromEmail, FromEmail));
message.From.Add(new MailboxAddress(mailOptions.FromName, mailOptions.FromEmail));
//收件人
message.To.AddRange(toAddress);
message.Subject = subject;
message.Date = DateTime.Now;
//创建附件Multipart
Multipart multipart = new Multipart("mixed");
var alternative = new MultipartAlternative();
@ -157,18 +125,18 @@ namespace ZR.Common
//开始发送
using var client = new SmtpClient();
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
//client.CheckCertificateRevocation = false;
client.Connect(mailOptions.Smtp, mailOptions.Port, mailOptions.UseSsl);
//Smtp服务器
//client.Connect("smtp.qq.com", 587, false);
client.Connect(Smtp, Port, true);
//登录,发送
//特别说明对于服务器端的中文相应Exception中有编码问题显示乱码了
client.Authenticate(FromEmail, FromPwd);
client.Authenticate(System.Text.Encoding.UTF8, mailOptions.FromEmail, mailOptions.Password);
client.Send(message);
var result = client.Send(message);
//断开
client.Disconnect(true);
Console.WriteLine($"发送邮件成功{DateTime.Now}");
Console.WriteLine($"【{DateTime.Now}】发送邮件结果{result}");
return result;
}
}
}

View File

@ -0,0 +1,9 @@
using System;
namespace ZR.Model
{
public enum ProteryConstant
{
NOTNULL = 0
}
}

View File

@ -6,7 +6,7 @@ namespace ZR.Model.System
/// <summary>
/// 文章表
/// </summary>
[SugarTable("article")]
[SugarTable("article", "文章管理")]
[Tenant("0")]
public class Article
{
@ -18,54 +18,64 @@ namespace ZR.Model.System
/// <summary>
/// 文章标题
/// </summary>
[SugarColumn(ColumnDescription = "文章标题", Length = 254, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string Title { get; set; }
/// <summary>
/// 发布时间
/// </summary>
[SugarColumn(ColumnDescription = "发布时间")]
public DateTime? CreateTime { get; set; }
/// <summary>
/// 更新时间
/// </summary>
[SugarColumn(IsOnlyIgnoreInsert = true)]
[SugarColumn(IsOnlyIgnoreInsert = true, ColumnDescription = "更新时间")]
public DateTime? UpdateTime { get; set; }
/// <summary>
/// 文章内容
/// </summary>
[SugarColumn(ColumnDescription = "文章内容", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string Content { get; set; }
/// <summary>
/// 作者名
/// </summary>
[SugarColumn(ColumnDescription = "作者名", Length = 20, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string AuthorName { get; set; }
/// <summary>
/// 发布者用户id
/// </summary>
[SugarColumn(ColumnDescription = "发布者用户id", ExtendedAttribute = ProteryConstant.NOTNULL)]
public long UserId { get; set; }
/// <summary>
/// 文章状态 1、发布 2、草稿
/// </summary>
[SugarColumn(ColumnDescription = "文章状态 1、发布 2、草稿", Length = 20)]
public string Status { get; set; }
/// <summary>
/// 编辑器类型 markdown,html
/// </summary>
[SugarColumn(ColumnName = "fmt_type")]
[SugarColumn(ColumnDescription = "编辑器类型markdown,html", ColumnName = "fmt_type", Length = 20, IsNullable = true)]
public string FmtType { get; set; }
/// <summary>
/// 文章标签egNet5,java
/// </summary>
[SugarColumn(ColumnDescription = "文章标签", Length = 20)]
public string Tags { get; set; }
/// <summary>
/// 点击量
/// </summary>
[SugarColumn(ColumnDescription = "点击量", DefaultValue = "0")]
public int Hits { get; set; }
[SugarColumn(ColumnName = "category_Id")]
[SugarColumn(ColumnDescription = "目录id", ColumnName = "category_Id")]
public int CategoryId { get; set; }
/// <summary>
/// 封面地址
/// </summary>
[SugarColumn(ColumnDescription = "封面地址", Length = 255)]
public string CoverUrl { get; set; }
/// <summary>
/// 是否公开 1、公开 0、不公开
/// </summary>
[SugarColumn(ColumnDescription = "是否公开 1、公开 0、不公开", DefaultValue = "0")]
public int IsPublic { get; set; }
[Navigate(NavigateType.OneToOne, nameof(CategoryId), nameof(ArticleCategory.CategoryId))] //自定义关系映射

View File

@ -8,18 +8,20 @@ namespace ZR.Model.System
/// <summary>
/// 文章目录
/// </summary>
[SugarTable("articleCategory")]
[SugarTable("articleCategory", "文章目录")]
[Tenant("0")]
public class ArticleCategory
{
/// <summary>
/// 目录id
/// </summary>
[SugarColumn(IsPrimaryKey = true, ColumnName = "Category_id")]
[SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "category_id")]
public int CategoryId { get; set; }
[SugarColumn(ColumnDescription = "目录名", Length = 20, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string Name { get; set; }
public int ParentId { get; set; }
[SugarColumn(ColumnName = "create_time", IsNullable = true)]
public int? ParentId { get; set; }
[SugarColumn(ColumnDescription = "创建时间", ColumnName = "create_time")]
public DateTime? CreateTime { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]

View File

@ -9,7 +9,7 @@ namespace ZR.Model.Models
/// 多语言配置,数据实体对象
/// </summary>
[Tenant("0")]
[SugarTable("sys_common_lang")]
[SugarTable("sys_common_lang", "多语言配置表")]
public class CommonLang
{
/// <summary>
@ -23,21 +23,21 @@ namespace ZR.Model.Models
/// 语言code
/// </summary>
[DisplayName("语言code")]
[SugarColumn(ColumnName = "lang_code", IsNullable = false)]
[SugarColumn(ColumnName = "lang_code", Length = 10, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string LangCode { get; set; }
/// <summary>
/// 语言key
/// </summary>
[DisplayName("语言key")]
[SugarColumn(ColumnName = "lang_key")]
[SugarColumn(ColumnName = "lang_key", Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string LangKey { get; set; }
/// <summary>
/// 名称
/// </summary>
[DisplayName("名称")]
[SugarColumn(ColumnName = "lang_name", IsNullable = false)]
[SugarColumn(ColumnName = "lang_name", Length = 2000, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string LangName { get; set; }
/// <summary>

View File

@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Linq;
namespace ZR.Model.System
namespace ZR.Model.System.Dto
{
/// <summary>
/// 登录用户信息存储

View File

@ -1,4 +1,6 @@
using System;
using MiniExcelLibs.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace ZR.Model.System.Dto
@ -7,7 +9,9 @@ namespace ZR.Model.System.Dto
{
//{"parentId":0,"menuName":"aaa","icon":"documentation","menuType":"M","orderNum":999,"visible":0,"status":0,"path":"aaa"}
[Required(ErrorMessage = "菜单id不能为空")]
[ExcelColumn(Name = "菜单id")]
public int MenuId { get; set; }
[ExcelColumn(Name = "菜单名")]
public string MenuName { get; set; }
/// <summary>
/// 父菜单ID
@ -22,22 +26,25 @@ namespace ZR.Model.System.Dto
/// <summary>
/// 路由地址
/// </summary>
[ExcelColumn(Name = "路由地址")]
public string Path { get; set; } = "#";
/// <summary>
/// 组件路径
/// </summary>
[ExcelColumn(Name = "组件地址")]
public string Component { get; set; }
/// <summary>
/// 是否缓存1缓存 0不缓存
/// </summary>
[Required(ErrorMessage = "是否缓存不能为空")]
public string IsCache { get; set; }
[ExcelColumn(Name = "是否缓存")]
public int IsCache { get; set; }
/// <summary>
/// 是否外链 1、是 0、否
/// </summary>
public string IsFrame { get; set; }
public int IsFrame { get; set; }
/// <summary>
/// 类型M目录 C菜单 F按钮 L链接
@ -60,6 +67,7 @@ namespace ZR.Model.System.Dto
/// <summary>
/// 权限字符串
/// </summary>
[ExcelColumn(Name = "权限字符串")]
public string Perms { get; set; }
/// <summary>
@ -70,6 +78,7 @@ namespace ZR.Model.System.Dto
/// 翻译key
/// </summary>
public string MenuNameKey { get; set; }
public List<MenuDto> Children { get; set; } = new List<MenuDto>();
}
public class MenuQueryDto

View File

@ -0,0 +1,30 @@
using MiniExcelLibs.Attributes;
using SqlSugar.DbConvert;
using ZR.Model.System.Enums;
namespace ZR.Model.System.Dto
{
public class RoleMenuExportDto
{
/// <summary>
/// 一级目录名
/// </summary>
[ExcelColumn(Name = "菜单", Width = 50)]
public string MenuName { get; set; }
//[ExcelColumn(Name = "菜单名", Width = 20)]
//public string MenuName1 { get; set; }
//[ExcelColumn(Name = "权限按钮", Width = 20)]
//public string MenuName2 { get; set; }
[ExcelColumn(Name = "路径", Width = 20)]
public string Path { get; set; }
[ExcelColumn(Name = "组件名", Width = 20)]
public string Component { get; set; }
[ExcelColumn(Name = "权限字符", Width = 20)]
public string Perms { get; set; }
//[ExcelColumn(Name = "菜单类型")]
//[SqlSugar.SugarColumn(SqlParameterDbType = typeof(EnumToStringConvert))]
//public MenuType MenuType { get; set; }
//[ExcelColumn(Name = "菜单状态")]
//public MenuStatus Status { get; set; }
}
}

View File

@ -1,3 +1,5 @@
using System.ComponentModel.DataAnnotations;
namespace ZR.Model.System.Dto
{
/// <summary>
@ -6,10 +8,11 @@ namespace ZR.Model.System.Dto
public class SysNoticeDto
{
public int NoticeId { get; set; }
[Required]
public string NoticeTitle { get; set; }
public string NoticeType { get; set; }
public int NoticeType { get; set; }
public string NoticeContent { get; set; }
public string Status { get; set; }
public int Status { get; set; }
public string Remark { get; set; }
}
@ -19,8 +22,8 @@ namespace ZR.Model.System.Dto
public class SysNoticeQueryDto : PagerInfo
{
public string NoticeTitle { get; set; }
public string NoticeType { get; set; }
public int? NoticeType { get; set; }
public string CreateBy { get; set; }
public string Status { get; set; }
public int? Status { get; set; }
}
}

View File

@ -12,10 +12,15 @@ namespace ZR.Model.System.Dto
public string RoleName { get; set; }
public string RoleKey { get; set; }
public int RoleSort { get; set; }
public string Status { get; set; }
public int Status { get; set; }
public int DataScope { get; set; }
public int[] DeptIds { get; set; }
/// <summary>
/// 减少菜单集合
/// </summary>
public List<long> DelMenuIds { get; set; } = new List<long>();
public bool MenuCheckStrictly { get; set; }
public bool DeptCheckStrictly { get; set; }
}
}

View File

@ -1,4 +1,6 @@
namespace ZR.Model.System.Dto
using System;
namespace ZR.Model.System.Dto
{
public class SysUserDto
{
@ -13,4 +15,22 @@
/// </summary>
public int Sex { get; set; }
}
public class SysUserQueryDto
{
public long UserId { get; set; }
public string UserName { get; set; }
public string NickName { get; set; }
public string Email { get; set; }
public string Remark { get; set; }
public string Phonenumber { get; set; }
/// <summary>
/// 用户性别0男 1女 2未知
/// </summary>
public int Sex { get; set; }
public DateTime? BeginTime { get; set; }
public DateTime? EndTime { get; set; }
public int Status { get; set; }
public long DeptId { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System.ComponentModel;
namespace ZR.Model.System.Enums
{
/// <summary>
/// 菜单状态0正常 1停用
/// </summary>
public enum MenuStatus
{
[Description("正常")]
= 0,
[Description("停用")]
= 1,
}
}

View File

@ -0,0 +1,19 @@
using System.ComponentModel;
namespace ZR.Model.System.Enums
{
/// <summary>
/// M目录 C菜单 F按钮 L链接
/// </summary>
public enum MenuType
{
[Description("目录")]
M,
[Description("菜单")]
C,
[Description("按钮")]
F,
[Description("链接")]
L
}
}

View File

@ -1,38 +1,44 @@
using System.Collections.Generic;
using SqlSugar;
using System.Collections.Generic;
namespace ZR.Model.System.Generate
{
/// <summary>
/// 代码生成表
/// </summary>
[SqlSugar.SugarTable("gen_table")]
[SqlSugar.Tenant("0")]
[SugarTable("gen_table", "代码生成表")]
[Tenant("0")]
public class GenTable : SysBase
{
/// <summary>
/// 表id
/// </summary>
[SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int TableId { get; set; }
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public long TableId { get; set; }
/// <summary>
/// 数据库名
/// </summary>
[SugarColumn(Length = 50)]
public string DbName { get; set; }
/// <summary>
/// 表名
/// </summary>
[SugarColumn(Length = 150)]
public string TableName { get; set; }
/// <summary>
/// 表描述
/// </summary>
[SugarColumn(Length = 150)]
public string TableComment { get; set; }
/// <summary>
/// 关联父表的表名
/// </summary>
[SugarColumn(Length = 150)]
public string SubTableName { get; set; }
/// <summary>
/// 本表关联父表的外键名
/// </summary>
[SugarColumn(Length = 150)]
public string SubTableFkName { get; set; }
/// <summary>
/// csharp类名
@ -41,18 +47,22 @@ namespace ZR.Model.System.Generate
/// <summary>
/// 使用的模板crud单表操作 tree树表操作 sub主子表操作
/// </summary>
[SugarColumn(Length = 50, DefaultValue = "crud")]
public string TplCategory { get; set; }
/// <summary>
/// 基本命名空间前缀
/// </summary>
[SugarColumn(Length = 100)]
public string BaseNameSpace { get; set; }
/// <summary>
/// 生成模块名
/// </summary>
[SugarColumn(Length = 50)]
public string ModuleName { get; set; }
/// <summary>
/// 生成业务名
/// </summary>
[SugarColumn(Length = 50)]
public string BusinessName { get; set; }
/// <summary>
/// 生成功能名
@ -65,23 +75,30 @@ namespace ZR.Model.System.Generate
/// <summary>
/// 生成代码方式0zip压缩包 1自定义路径
/// </summary>
[SugarColumn(Length = 1, DefaultValue = "0")]
public string GenType { get; set; }
/// <summary>
/// 代码生成保存路径
/// </summary>
[SugarColumn(Length = 200, DefaultValue = "/")]
public string GenPath { get; set; }
/// <summary>
/// 其他生成选项
/// </summary>
[SqlSugar.SugarColumn(IsJson = true, ColumnDataType = "nvarchar(4000)")]
[SugarColumn(IsJson = true)]
public Options Options { get; set; }
#region
/** 表列信息 */
[SqlSugar.SugarColumn(IsIgnore = true)]
/// <summary>
/// 表列信息
/// </summary>
[SugarColumn(IsIgnore = true)]
public List<GenTableColumn> Columns { get; set; }
/// <summary>
/// 字表信息
/// </summary>
[SqlSugar.SugarColumn(IsIgnore = true)]
[SugarColumn(IsIgnore = true)]
public GenTable SubTable { get; set; }
#endregion
}
@ -107,5 +124,9 @@ namespace ZR.Model.System.Generate
/// 是否生成仓储层
/// </summary>
public int GenerateRepo { get; set; }
/// <summary>
/// 自动生成菜单
/// </summary>
public bool GenerateMenu { get; set; }
}
}

View File

@ -7,18 +7,21 @@ namespace ZR.Model.System.Generate
/// <summary>
/// 代码生成表字段
/// </summary>
[SugarTable("gen_table_column")]
[SugarTable("gen_table_column", "代码生成表字段")]
[Tenant("0")]
public class GenTableColumn : SysBase
{
/// <summary>
/// 列id
/// </summary>
[SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
public int ColumnId { get; set; }
public long ColumnId { get; set; }
/// <summary>
/// 导入代码生成表列名 首字母转了小写
/// </summary>
public string ColumnName { get; set; }
[SugarColumn(IsOnlyIgnoreUpdate = true)]
public int TableId { get; set; }
public long TableId { get; set; }
[SugarColumn(IsOnlyIgnoreUpdate = true)]
public string TableName { get; set; }
@ -96,6 +99,7 @@ namespace ZR.Model.System.Generate
/// <summary>
/// 查询类型(等于、不等于、大于、小于、范围)
/// </summary>
[SugarColumn(DefaultValue = "EQ")]
public string QueryType { get; set; } = "EQ";
public int Sort { get; set; }
/// <summary>

View File

@ -8,22 +8,34 @@ namespace ZR.Model.System
//[EpplusTable(PrintHeaders = true, AutofitColumns = true, AutoCalculate = true, ShowTotal = true)]
public class SysBase
{
/// <summary>
/// 创建人
/// </summary>
[SugarColumn(IsOnlyIgnoreUpdate = true, Length = 64, IsNullable = true)]
[JsonProperty(propertyName: "CreateBy")]
[ExcelIgnore]
public string Create_by { get; set; }
/// <summary>
/// 创建时间
/// </summary>
[SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true)]
[JsonProperty(propertyName: "CreateTime")]
[ExcelColumn(Format = "yyyy-MM-dd HH:mm:ss")]
public DateTime Create_time { get; set; } = DateTime.Now;
/// <summary>
/// 更新人
/// </summary>
[JsonIgnore]
[JsonProperty(propertyName: "UpdateBy")]
[SugarColumn(IsOnlyIgnoreInsert = true, Length = 64, IsNullable = true)]
[ExcelIgnore]
public string Update_by { get; set; }
/// <summary>
/// 更新时间
/// </summary>
//[JsonIgnore]
[SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true)]
[JsonProperty(propertyName: "UpdateTime")]
@ -31,13 +43,5 @@ namespace ZR.Model.System
public DateTime? Update_time { get; set; }
[SugarColumn(Length = 500)]
public string Remark { get; set; }
[SugarColumn(IsIgnore = true, IsNullable = true)]
[JsonIgnore]
[ExcelIgnore]
public DateTime? BeginTime { get; set; }
[SugarColumn(IsIgnore = true, IsNullable = true)]
[JsonIgnore]
[ExcelIgnore]
public DateTime? EndTime { get; set; }
}
}

View File

@ -8,7 +8,7 @@ namespace ZR.Model.System
/// @author mr.zhao
/// @date 2021-09-29
/// </summary>
[SugarTable("sys_config")]
[SugarTable("sys_config", "配置表")]
[Tenant("0")]
public class SysConfig : SysBase
{
@ -20,18 +20,22 @@ namespace ZR.Model.System
/// <summary>
/// 参数名称
/// </summary>
[SugarColumn(Length = 100)]
public string ConfigName { get; set; }
/// <summary>
/// 参数键名
/// </summary>
[SugarColumn(Length = 100)]
public string ConfigKey { get; set; }
/// <summary>
/// 参数键值
/// </summary>
[SugarColumn(Length = 500)]
public string ConfigValue { get; set; }
/// <summary>
/// 系统内置Y是 N否
/// </summary>
[SugarColumn(Length = 1)]
public string ConfigType { get; set; }
}

View File

@ -6,9 +6,9 @@ namespace ZR.Model.System
/// <summary>
/// 部门表
/// </summary>
[SugarTable("sys_dept")]
[SugarTable("sys_dept", "部门配置表")]
[Tenant("0")]
public class SysDept: SysBase
public class SysDept : SysBase
{
/// <summary>
/// 部门ID
@ -29,6 +29,7 @@ namespace ZR.Model.System
/// <summary>
/// 部门名称
/// </summary>
[SugarColumn(Length = 30, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string DeptName { get; set; }
/// <summary>
@ -39,32 +40,36 @@ namespace ZR.Model.System
/// <summary>
/// 负责人
/// </summary>
[SugarColumn(Length = 30)]
public string Leader { get; set; }
/// <summary>
/// 联系电话
/// </summary>
[SugarColumn(Length = 11)]
public string Phone { get; set; }
/// <summary>
/// 邮箱
/// </summary>
[SugarColumn(Length = 50)]
public string Email { get; set; }
/// <summary>
/// 部门状态:0正常,1停用
/// </summary>
[SugarColumn(Length = 1, DefaultValue = "0")]
public string Status { get; set; }
/// <summary>
/// 删除标志0代表存在 2代表删除
/// </summary>
[SugarColumn(IsOnlyIgnoreInsert = true)]
[SugarColumn(Length = 1, DefaultValue = "0")]
public string DelFlag { get; set; }
/// <summary>
/// 子菜单
/// </summary>
public List<SysDept> children = new List<SysDept>();
public List<SysDept> children = new();
}
}

View File

@ -6,7 +6,7 @@ namespace ZR.Model.System
/// 字典数据表
/// </summary>
[Tenant("0")]
[SugarTable("sys_dict_data")]
[SugarTable("sys_dict_data", "字典数据表")]
public class SysDictData : SysBase
{
/// <summary>
@ -21,30 +21,37 @@ namespace ZR.Model.System
/// <summary>
/// 字典标签
/// </summary>
[SugarColumn(Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string DictLabel { get; set; }
/// <summary>
/// 字典键值
/// </summary>
[SugarColumn(Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string DictValue { get; set; }
/// <summary>
/// 字典类型
/// </summary>
[SugarColumn(Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string DictType { get; set; }
/// <summary>
/// 样式属性(其他样式扩展)
/// </summary>
[SugarColumn(Length = 100)]
public string CssClass { get; set; } = string.Empty;
/// <summary>
/// 表格回显样式
/// </summary>
[SugarColumn(Length = 100)]
public string ListClass { get; set; } = string.Empty;
/// <summary>
/// 是否默认Y是 N否
/// </summary>
[SugarColumn(Length = 1, DefaultValue = "N")]
public string IsDefault { get; set; }
/// <summary>
/// 状态0正常 1停用
/// </summary>
[SugarColumn(Length = 1)]
public string Status { get; set; }
}
}

View File

@ -5,7 +5,8 @@ namespace ZR.Model.System
/// <summary>
/// 字典类型表
/// </summary>
[SugarTable("sys_dict_type")]
[SugarTable("sys_dict_type", "字典类型表")]
[SugarIndex("index_dict_type", nameof(DictType), OrderByType.Asc, true)]
[Tenant("0")]
public class SysDictType : SysBase
{
@ -17,18 +18,22 @@ namespace ZR.Model.System
/// <summary>
/// 字典名称
/// </summary>
[SugarColumn(Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string DictName { get; set; }
/// <summary>
/// 字典类型
/// </summary>
[SugarColumn(Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string DictType { get; set; }
/// <summary>
/// 状态 0、正常 1、停用
/// </summary>
[SugarColumn(Length = 1, DefaultValue = "0")]
public string Status { get; set; }
/// <summary>
/// 系统内置 Y是 N否
/// </summary>
[SugarColumn(Length = 1, DefaultValue = "N")]
public string Type { get; set; }
/// <summary>
/// 自定义sql

View File

@ -5,7 +5,7 @@ using System;
namespace ZR.Model.System
{
[Tenant("0")]
[SugarTable("sys_file")]
[SugarTable("sys_file", "文件存储表")]
public class SysFile
{
/// <summary>

View File

@ -6,7 +6,7 @@ namespace ZR.Model.System
/// <summary>
/// sys_logininfor 表
/// </summary>
[SugarTable("sys_logininfor")]
[SugarTable("sys_logininfor", "登录日志表")]
[Tenant("0")]
public class SysLogininfor
{
@ -21,32 +21,33 @@ namespace ZR.Model.System
/// <summary>
/// 登录状态 0成功 1失败
/// </summary>
[SugarColumn(Length = 1, DefaultValue = "0")]
public string Status { get; set; }
/// <summary>
/// 登录IP地址
/// </summary>
public string Ipaddr { get; set; }
public string Ipaddr { get; set; } = string.Empty;
/// <summary>
/// 登录地点
/// </summary>
public string LoginLocation { get; set; }
public string LoginLocation { get; set; } = string.Empty;
/// <summary>
/// 浏览器类型
/// </summary>
public string Browser { get; set; }
public string Browser { get; set; } = string.Empty;
/// <summary>
/// 操作系统
/// </summary>
public string Os { get; set; }
public string Os { get; set; } = string.Empty;
/// <summary>
/// 提示消息
/// </summary>
public string Msg { get; set; }
public string Msg { get; set; } = string.Empty;
/// <summary>
/// 访问时间

View File

@ -6,7 +6,7 @@ namespace ZR.Model.System
/// <summary>
/// Sys_menu表
/// </summary>
[SugarTable("sys_menu")]
[SugarTable("sys_menu", "系统菜单表")]
[Tenant("0")]
public class SysMenu : SysBase
{
@ -18,22 +18,25 @@ namespace ZR.Model.System
/// <summary>
/// 菜单名称
/// </summary>
[SugarColumn(Length = 50, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string MenuName { get; set; }
/// <summary>
/// 父菜单ID
/// </summary>
[SugarColumn(DefaultValue = "0")]
public long ParentId { get; set; }
/// <summary>
/// 显示顺序
/// </summary>
[SugarColumn(DefaultValue = "0")]
public int OrderNum { get; set; }
/// <summary>
/// 路由地址
/// </summary>
public string Path { get; set; } = "#";
public string Path { get; set; } = "";
/// <summary>
/// 组件路径
@ -43,35 +46,42 @@ namespace ZR.Model.System
/// <summary>
/// 是否缓存1缓存 0不缓存
/// </summary>
[SugarColumn(DefaultValue = "0", ColumnDataType = "int")]
public string IsCache { get; set; }
/// <summary>
/// 是否外链 1、是 0、否
/// </summary>
public string IsFrame { get; set; }
[SugarColumn(DefaultValue = "0", ColumnDataType = "int")]
public string IsFrame { get; set; } = "0";
/// <summary>
/// 类型M目录 C菜单 F按钮 L链接
/// </summary>
public string MenuType { get; set; }
[SugarColumn(Length = 1)]
public string MenuType { get; set; } = string.Empty;
/// <summary>
/// 显示状态0显示 1隐藏
/// </summary>
[SugarColumn(DefaultValue = "0", Length = 1)]
public string Visible { get; set; }
/// <summary>
/// 菜单状态0正常 1停用
/// </summary>
[SugarColumn(DefaultValue = "0", Length = 1)]
public string Status { get; set; }
/// <summary>
/// 权限字符串
/// </summary>
[SugarColumn(Length = 100)]
public string Perms { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
[SugarColumn(DefaultValue = "#")]
public string Icon { get; set; } = string.Empty;
/// <summary>
/// 菜单名key

View File

@ -3,12 +3,12 @@ using SqlSugar;
namespace ZR.Model.System
{
/// <summary>
/// 通知公告表,数据实体对象
/// 通知公告表
///
/// @author zr
/// @date 2021-12-15
/// </summary>
[SugarTable("sys_notice")]
[SugarTable("sys_notice", "通知公告表")]
[Tenant(0)]
public class SysNotice : SysBase
{
@ -20,21 +20,22 @@ namespace ZR.Model.System
/// <summary>
/// 公告标题
/// </summary>
[SugarColumn(ColumnName = "notice_title")]
[SugarColumn(ColumnName = "notice_title", ExtendedAttribute = ProteryConstant.NOTNULL)]
public string NoticeTitle { get; set; }
/// <summary>
/// 公告类型 (1通知 2公告)
/// </summary>
[SugarColumn(ColumnName = "notice_type")]
public string NoticeType { get; set; }
[SugarColumn(ColumnName = "notice_type", ExtendedAttribute = ProteryConstant.NOTNULL)]
public int NoticeType { get; set; }
/// <summary>
/// 公告内容
/// </summary>
[SugarColumn(ColumnName = "notice_content")]
[SugarColumn(ColumnName = "notice_content", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string NoticeContent { get; set; }
/// <summary>
/// 公告状态 (0正常 1关闭)
/// </summary>
public string Status { get; set; }
[SugarColumn(DefaultValue = "0", ExtendedAttribute = ProteryConstant.NOTNULL)]
public int Status { get; set; }
}
}

View File

@ -5,22 +5,24 @@ using System.ComponentModel;
namespace ZR.Model.System
{
[SugarTable("sys_oper_log")]
[SugarTable("sys_oper_log", "操作日志表")]
[Tenant("0")]
public class SysOperLog
{
/// <summary>
/// 操作id
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public long OperId { get; set; }
/// <summary>
/// 操作模块
/// </summary>
[DisplayName("操作模块")]
public string Title { get; set; }
/// <summary>
/// 业务类型0其它 1新增 2修改 3删除 4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据)
/// </summary>
[DisplayName("业务类型")]
[SugarColumn(DefaultValue = "0")]
public int BusinessType { get; set; }
/// <summary>
@ -33,79 +35,71 @@ namespace ZR.Model.System
/// <summary>
/// 请求方法
/// </summary>
[DisplayName("请求方法")]
public string Method { get; set; }
/// <summary>
/// 请求方式
/// </summary>
[DisplayName("请求方式")]
public string RequestMethod { get; set; }
/// <summary>
/// 操作类别0其它 1后台用户 2手机端用户
/// </summary>
//@Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
[DisplayName("操作类别")]
[SugarColumn(DefaultValue = "0")]
public int OperatorType { get; set; }
/// <summary>
/// 操作人员
/// </summary>
[DisplayName("操作人员")]
public string OperName { get; set; }
/// <summary>
/// 请求url
/// </summary>
[DisplayName("请求地址")]
public string OperUrl { get; set; }
/// <summary>
/// 操作地址
/// </summary>
[DisplayName("操作地址")]
public string OperIp { get; set; }
/// <summary>
/// 操作地点
/// </summary>
[DisplayName("操作地点")]
public string OperLocation { get; set; }
/// <summary>
/// 请求参数
/// </summary>
[DisplayName("请求参数")]
[SugarColumn(Length = 4000)]
public string OperParam { get; set; }
/// <summary>
/// 返回参数
/// </summary>
[DisplayName("返回结果")]
[SugarColumn(ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string JsonResult { get; set; }
/// <summary>
/// 操作状态0正常 1异常
/// </summary>
[DisplayName("状态")]
[SugarColumn(DefaultValue = "0")]
public int Status { get; set; }
/// <summary>
/// 错误消息
/// </summary>
[DisplayName("错误消息")]
public string ErrorMsg { get; set; }
/// <summary>
/// 操作时间
/// </summary>
[DisplayName("操作时间")]
public DateTime? OperTime { get; set; }
/// <summary>
/// 操作用时
/// </summary>
[DisplayName("操作用时")]
public long Elapsed { get; set; }
public string DeptName { get; set; }
}
}

View File

@ -2,7 +2,7 @@
namespace ZR.Model.System
{
[SugarTable("sys_post")]
[SugarTable("sys_post", "岗位表")]
[Tenant("0")]
public class SysPost : SysBase
{
@ -11,9 +11,13 @@ namespace ZR.Model.System
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public long PostId { get; set; }
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string PostCode { get; set; }
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string PostName { get; set; }
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public int PostSort { get; set; }
[SugarColumn(Length = 1)]
public string Status { get; set; }
}
}

View File

@ -5,7 +5,7 @@ namespace ZR.Model.System
/// <summary>
/// 角色表 sys_role
/// </summary>
[SugarTable("sys_role")]
[SugarTable("sys_role", "角色表")]
[Tenant("0")]
public class SysRole : SysBase
{
@ -18,41 +18,47 @@ namespace ZR.Model.System
/// <summary>
/// 角色名称
/// </summary>
[SugarColumn(Length = 30, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string RoleName { get; set; }
/// <summary>
/// 角色权限
/// </summary>
[SugarColumn(Length = 100, ExtendedAttribute = ProteryConstant.NOTNULL)]
public string RoleKey { get; set; }
/// <summary>
/// 角色排序
/// </summary>
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public int RoleSort { get; set; }
/// <summary>
/// 帐号状态0正常 1停用
/// </summary>
[SugarColumn(DefaultValue = "0")]
public int Status { get; set; }
/// <summary>
/// 删除标志0代表存在 2代表删除
/// </summary>
[SugarColumn(DefaultValue = "0")]
public int DelFlag { get; set; }
/// <summary>
/// 数据范围1全部数据权限 2自定数据权限 3本部门数据权限 4本部门及以下数据权限
/// </summary>
[SugarColumn(DefaultValue = "1")]
public int DataScope { get; set; }
/// <summary>
/// 菜单树选择项是否关联显示
/// </summary>
[SugarColumn(ColumnName = "menu_check_strictly")]
public bool MenuCheckStrictly { get; set; }
public bool MenuCheckStrictly { get; set; } = true;
/// <summary>
/// 部门树选择项是否关联显示
/// </summary>
[SugarColumn(ColumnName = "dept_check_strictly")]
public bool DeptCheckStrictly { get; set; }
public bool DeptCheckStrictly { get; set; } = true;
/// <summary>
/// 菜单组
/// </summary>

View File

@ -1,10 +1,15 @@
namespace ZR.Model.System
using SqlSugar;
namespace ZR.Model.System
{
[SqlSugar.SugarTable("sys_role_dept")]
[SqlSugar.Tenant(0)]
[SugarTable("sys_role_dept", "角色部门")]
[Tenant(0)]
public class SysRoleDept
{
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL, IsPrimaryKey = true)]
public long RoleId { get; set; }
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL, IsPrimaryKey = true)]
public long DeptId { get; set; }
}
}

View File

@ -1,23 +1,20 @@
using Newtonsoft.Json;
using SqlSugar;
using System;
namespace ZR.Model.System
{
/// <summary>
/// 角色菜单
/// </summary>
[SugarTable("sys_role_menu")]
[SugarTable("sys_role_menu", "角色菜单")]
[Tenant("0")]
public class SysRoleMenu
public class SysRoleMenu : SysBase
{
[JsonProperty("roleId")]
[SugarColumn(IsPrimaryKey = true)]
[SugarColumn(IsPrimaryKey = true, ExtendedAttribute = ProteryConstant.NOTNULL)]
public long Role_id { get; set; }
[JsonProperty("menuId")]
[SugarColumn(IsPrimaryKey = true)]
[SugarColumn(IsPrimaryKey = true, ExtendedAttribute = ProteryConstant.NOTNULL)]
public long Menu_id { get; set; }
public DateTime Create_time { get; set; }
public string Create_by { get; set; }
}
}

View File

@ -1,15 +0,0 @@
using SqlSugar;
namespace ZR.Model.System
{
/// <summary>
/// 角色部门
/// </summary>
[SugarTable("sys_role_post")]
[Tenant("0")]
public class SysRolePost
{
public long RoleId { get; set; }
public long DeptId { get; set; }
}
}

View File

@ -1,5 +1,4 @@
using Newtonsoft.Json;
using SqlSugar;
using SqlSugar;
using System;
using System.ComponentModel.DataAnnotations;
@ -8,9 +7,9 @@ namespace ZR.Model.System
///<summary>
///计划任务
///</summary>
[SugarTable("sys_tasks")]
[SugarTable("sys_tasks", "计划任务表")]
[Tenant("0")]
public class SysTasks
public class SysTasks : SysBase
{
public SysTasks()
{
@ -28,42 +27,42 @@ namespace ZR.Model.System
/// 任务名称
/// </summary>
[Display(Name = "任务名称")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string Name { get; set; }
/// <summary>
/// 任务分组
/// </summary>
[Display(Name = "任务分组")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string JobGroup { get; set; }
/// <summary>
/// 运行时间表达式
/// </summary>
[Display(Name = "运行时间表达式")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string Cron { get; set; }
/// <summary>
/// 程序集名称
/// </summary>
[Display(Name = "程序集名称")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string AssemblyName { get; set; }
/// <summary>
/// 任务所在类
/// </summary>
[Display(Name = "任务所在类")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string ClassName { get; set; }
/// <summary>
/// 任务描述
/// </summary>
[Display(Name = "任务描述")]
public string Remark { get; set; }
/// <summary>
/// 执行次数
/// </summary>
[Display(Name = "执行次数")]
[SugarColumn(DefaultValue = "0", ExtendedAttribute = ProteryConstant.NOTNULL)]
public int RunTimes { get; set; }
/// <summary>
@ -83,6 +82,7 @@ namespace ZR.Model.System
/// 默认 : 1
/// </summary>
[Display(Name = "触发器类型0、simple 1、cron")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public int TriggerType { get; set; }
/// <summary>
@ -90,42 +90,22 @@ namespace ZR.Model.System
/// 默认 : 0
/// </summary>
[Display(Name = "执行间隔时间(单位:秒)")]
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public int IntervalSecond { get; set; }
/// <summary>
/// 是否启动
/// 默认 : 0
/// </summary>
[Display(Name = "是否启动")]
[SugarColumn(DefaultValue = "0", ExtendedAttribute = ProteryConstant.NOTNULL)]
public int IsStart { get; set; }
/// <summary>
/// 传入参数
/// 默认 :
/// </summary>
[Display(Name = "传入参数")]
public string JobParams { get; set; }
[SugarColumn(IsOnlyIgnoreUpdate = true)]//设置后修改不会有此字段
[JsonProperty(propertyName: "CreateBy")]
public string Create_by { get; set; }
/// <summary>
/// 创建时间
/// </summary>
//[Display(Name = "创建时间")]
[SugarColumn(IsOnlyIgnoreUpdate = true)]//设置后修改不会有此字段
[JsonProperty(propertyName: "CreateTime")]
public DateTime Create_time { get; set; } = DateTime.Now;
[JsonIgnore]
[JsonProperty(propertyName: "UpdateBy")]
[SugarColumn(IsOnlyIgnoreInsert = true)]
public string Update_by { get; set; }
[SugarColumn(IsOnlyIgnoreInsert = true)]//设置后插入数据不会有此字段
[JsonProperty(propertyName: "UpdateTime")]
public DateTime Update_time { get; set; } = DateTime.Now;
/// <summary>
/// 最后运行时间
/// </summary>
@ -137,6 +117,7 @@ namespace ZR.Model.System
/// <summary>
/// 任务类型 1、程序集 2、网络请求 3、SQL语句
/// </summary>
[SugarColumn(DefaultValue = "1")]
public int TaskType { get; set; }
/// <summary>
@ -146,6 +127,7 @@ namespace ZR.Model.System
/// <summary>
/// 网络请求方式
/// </summary>
[SugarColumn(Length = 20)]
public string RequestMethod { get; set; }
}
}

View File

@ -6,7 +6,7 @@ namespace ZR.Model.System
/// <summary>
/// 任务日志
/// </summary>
[SugarTable("sys_tasks_log")]
[SugarTable("sys_tasks_log", "任务日志表")]
[Tenant("0")]
public class SysTasksLog
{
@ -18,12 +18,22 @@ namespace ZR.Model.System
/// <summary>
/// 任务Id
/// </summary>
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string JobId { get; set; }
/// <summary>
/// 任务名
/// </summary>
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string JobName { get; set; }
/// <summary>
/// 任务分组
/// </summary>
[SugarColumn(ExtendedAttribute = ProteryConstant.NOTNULL)]
public string JobGroup { get; set; }
/// <summary>
/// 执行状态0正常 1失败
/// </summary>
[SugarColumn(DefaultValue = "0")]
public string Status { get; set; }
/// <summary>
/// 异常

View File

@ -9,7 +9,7 @@ namespace ZR.Model.System
/// <summary>
/// 用户表
/// </summary>
[SugarTable("sys_user")]
[SugarTable("sys_user", "用户表")]
[Tenant("0")]
public class SysUser : SysBase
{
@ -21,12 +21,12 @@ namespace ZR.Model.System
/// <summary>
/// 登录用户名
/// </summary>
[SugarColumn(Length = 30, ColumnDescription = "用户账号", IsNullable = false)]
[SugarColumn(Length = 30, ColumnDescription = "用户账号", ExtendedAttribute = ProteryConstant.NOTNULL)]
public string UserName { get; set; }
/// <summary>
/// 用户昵称
/// </summary>
[SugarColumn(Length = 30, ColumnDescription = "用户昵称", IsNullable = false)]
[SugarColumn(Length = 30, ColumnDescription = "用户昵称", ExtendedAttribute = ProteryConstant.NOTNULL)]
public string NickName { get; set; }
/// <summary>
/// 用户类型00系统用户
@ -40,7 +40,7 @@ namespace ZR.Model.System
[JsonIgnore]
[ExcelIgnore]
[SugarColumn(Length = 100, ColumnDescription = "密码", IsNullable = false)]
[SugarColumn(Length = 100, ColumnDescription = "密码", ExtendedAttribute = ProteryConstant.NOTNULL)]
public string Password { get; set; }
/// <summary>
/// 手机号

View File

@ -5,11 +5,13 @@ namespace ZR.Model.System
/// <summary>
/// 用户岗位
/// </summary>
[SugarTable("sys_user_post")]
[SugarTable("sys_user_post", "用户与岗位关联表")]
[Tenant("0")]
public class SysUserPost
{
[SugarColumn(IsPrimaryKey = true, ExtendedAttribute = ProteryConstant.NOTNULL)]
public long UserId { get; set; }
[SugarColumn(IsPrimaryKey = true, ExtendedAttribute = ProteryConstant.NOTNULL)]
public long PostId { get; set; }
}
}

View File

@ -5,7 +5,7 @@ namespace ZR.Model.System
/// <summary>
/// 用户角色关联表 用户N-1 角色
/// </summary>
[SugarTable("sys_user_role")]
[SugarTable("sys_user_role", "用户和角色关联表")]
[Tenant("0")]
public class SysUserRole
{

View File

@ -2,16 +2,14 @@
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<DocumentationFile>../ZR.Admin.WebApi/ZRModel.xml</DocumentationFile>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>1701;1702;1591;1570</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MiniExcel" Version="1.30.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.73" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.84-preview10" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup>
</Project>

View File

@ -12,7 +12,7 @@ using ZR.Model;
namespace ZR.Repository
{
/// <summary>
///
/// 数据仓库类
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseRepository<T> : SimpleClient<T> where T : class, new()
@ -79,7 +79,7 @@ namespace ZR.Repository
/// <summary>
/// 实体根据主键更新指定字段
/// return Update(user, t => new { t.NickName, }, true);
/// return Update(new SysUser(){ Status = 1 }, t => new { t.NickName, }, true);
/// </summary>
/// <param name="entity"></param>
/// <param name="expression"></param>
@ -91,12 +91,12 @@ namespace ZR.Repository
}
/// <summary>
/// 根据指定条件更新指定列 egUpdate(new SysUser(){ }, it => new { it.Status }, f => f.Userid == 1));
/// 根据指定条件更新指定列 egUpdate(new SysUser(){ Status = 1 }, it => new { it.Status }, f => f.Userid == 1));
/// 只更新Status列条件是包含
/// </summary>
/// <param name="entity"></param>
/// <param name="expression"></param>
/// <param name="where"></param>
/// <param name="entity">实体类</param>
/// <param name="expression">要更新列的表达式</param>
/// <param name="where">where表达式</param>
/// <returns></returns>
public int Update(T entity, Expression<Func<T, object>> expression, Expression<Func<T, bool>> where)
{
@ -117,14 +117,11 @@ namespace ZR.Repository
/// <returns></returns>
public int Update(T entity, List<string> list = null, bool isNull = true)
{
if (list == null)
{
list = new List<string>()
list ??= new List<string>()
{
"Create_By",
"Create_time"
};
}
return Context.Updateable(entity).IgnoreColumns(isNull).IgnoreColumns(list.ToArray()).ExecuteCommand();
}
@ -171,6 +168,7 @@ namespace ZR.Repository
{
return Context.Storageable(t);
}
/// <summary>
///
/// </summary>
@ -192,6 +190,11 @@ namespace ZR.Repository
}
}
/// <summary>
/// 使用事务
/// </summary>
/// <param name="action"></param>
/// <returns></returns>
public bool UseTran2(Action action)
{
var result = Context.Ado.UseTran(() => action());
@ -239,36 +242,6 @@ namespace ZR.Repository
return Context.Queryable<T>();
}
public (List<T>, int) QueryableToPage(Expression<Func<T, bool>> expression, int pageIndex = 0, int pageSize = 10)
{
int totalNumber = 0;
var list = Context.Queryable<T>().Where(expression).ToPageList(pageIndex, pageSize, ref totalNumber);
return (list, totalNumber);
}
public (List<T>, int) QueryableToPage(Expression<Func<T, bool>> expression, string order, int pageIndex = 0, int pageSize = 10)
{
int totalNumber = 0;
var list = Context.Queryable<T>().Where(expression).OrderBy(order).ToPageList(pageIndex, pageSize, ref totalNumber);
return (list, totalNumber);
}
public (List<T>, int) QueryableToPage(Expression<Func<T, bool>> expression, Expression<Func<T, object>> orderFiled, string orderBy, int pageIndex = 0, int pageSize = 10)
{
int totalNumber = 0;
if (orderBy.Equals("DESC", StringComparison.OrdinalIgnoreCase))
{
var list = Context.Queryable<T>().Where(expression).OrderBy(orderFiled, OrderByType.Desc).ToPageList(pageIndex, pageSize, ref totalNumber);
return (list, totalNumber);
}
else
{
var list = Context.Queryable<T>().Where(expression).OrderBy(orderFiled, OrderByType.Asc).ToPageList(pageIndex, pageSize, ref totalNumber);
return (list, totalNumber);
}
}
public List<T> SqlQueryToList(string sql, object obj = null)
{
return Context.Ado.SqlQuery<T>(sql, obj);
@ -296,9 +269,21 @@ namespace ZR.Repository
return source.ToPage(parm);
}
/// <summary>
/// 分页获取数据
/// </summary>
/// <param name="where">条件表达式</param>
/// <param name="parm"></param>
/// <param name="order"></param>
/// <param name="orderEnum"></param>
/// <returns></returns>
public PagedInfo<T> GetPages(Expression<Func<T, bool>> where, PagerInfo parm, Expression<Func<T, object>> order, OrderByType orderEnum = OrderByType.Asc)
{
var source = Context.Queryable<T>().Where(where).OrderByIF(orderEnum == OrderByType.Asc, order, OrderByType.Asc).OrderByIF(orderEnum == OrderByType.Desc, order, OrderByType.Desc);
var source = Context
.Queryable<T>()
.Where(where)
.OrderByIF(orderEnum == OrderByType.Asc, order, OrderByType.Asc)
.OrderByIF(orderEnum == OrderByType.Desc, order, OrderByType.Desc);
return source.ToPage(parm);
}

View File

@ -71,12 +71,6 @@ namespace ZR.Repository
ISugarQueryable<T> Queryable();
List<T> GetAll(bool useCache = false, int cacheSecond = 3600);
(List<T>, int) QueryableToPage(Expression<Func<T, bool>> expression, int pageIndex = 0, int pageSize = 10);
(List<T>, int) QueryableToPage(Expression<Func<T, bool>> expression, string order, int pageIndex = 0, int pageSize = 10);
(List<T>, int) QueryableToPage(Expression<Func<T, bool>> expression, Expression<Func<T, object>> orderFiled, string orderBy, int pageIndex = 0, int pageSize = 10);
List<T> SqlQueryToList(string sql, object obj = null);
T GetId(object pkValue);

View File

@ -15,6 +15,6 @@
<PackageReference Include="MySqlConnector" Version="2.2.6" />
<PackageReference Include="NETCore.Encrypt" Version="2.1.1" />
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.73" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.84-preview10" />
</ItemGroup>
</Project>

View File

@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZR.Common;
using ZR.Common.Cache;
namespace ZR.Service.System
{
@ -13,15 +11,18 @@ namespace ZR.Service.System
public static List<string> GetUserPerms(string key)
{
return (List<string>)CacheHelper.GetCache(key);
//return RedisServer.Cache.Get<List<string>>(key).ToList();
}
public static void SetUserPerms(string key, object data)
{
CacheHelper.SetCache(key, data);
//RedisServer.Cache.Set(key, data);
}
public static void RemoveUserPerms(string key)
{
CacheHelper.Remove(key);
//RedisServer.Cache.Del(key);
}
#endregion
}

View File

@ -2,6 +2,7 @@
using ZR.Model.System.Dto;
using ZR.Model.System;
using ZR.Model.System.Vo;
using ZR.Model.System.Generate;
namespace ZR.Service.System.IService
{
@ -14,9 +15,9 @@ namespace ZR.Service.System.IService
SysMenu GetMenuByMenuId(int menuId);
List<SysMenu> GetMenusByMenuId(int menuId, long userId);
int AddMenu(SysMenu menu);
long AddMenu(SysMenu menu);
int EditMenu(SysMenu menu);
long EditMenu(SysMenu menu);
int DeleteMenuById(int menuId);
@ -37,6 +38,10 @@ namespace ZR.Service.System.IService
List<RouterVo> BuildMenus(List<SysMenu> menus);
List<TreeSelectVo> BuildMenuTreeSelect(List<SysMenu> menus);
void AddSysMenu(GenTable genTableInfo, string permPrefix, bool showEdit, bool showExport);
List<SysMenu> SelectTreeMenuListByRoles(MenuQueryDto menu, List<long> roles);
List<RoleMenuExportDto> SelectRoleMenuListByRole(MenuQueryDto menu, int roleId);
}
/// <summary>

View File

@ -7,7 +7,7 @@ namespace ZR.Service.System.IService
{
public interface ISysUserService : IBaseService<SysUser>
{
public PagedInfo<SysUser> SelectUserList(SysUser user, PagerInfo pager);
public PagedInfo<SysUser> SelectUserList(SysUserQueryDto user, PagerInfo pager);
/// <summary>
/// 通过用户ID查询用户

View File

@ -1,11 +1,16 @@
using Infrastructure.Extensions;
using MiniExcelLibs;
using SqlSugar.IOC;
using System.Collections.Generic;
using System.Linq;
using ZR.Common;
using ZR.Model.System;
namespace ZR.Service.System
{
/// <summary>
/// 种子数据处理
/// </summary>
public class SeedDataService
{
/// <summary>
@ -44,14 +49,12 @@ namespace ZR.Service.System
public (string, object, object) InitMenuData(List<SysMenu> data)
{
var db = DbScoped.SugarScope;
db.Ado.BeginTran();
var x = db.Storageable(data)
.SplitInsert(it => it.NotAny())
.WhereColumns(it => it.MenuId)//如果不是主键可以这样实现多字段it=>new{it.x1,it.x2}
.ToStorage();
var result = x.AsInsertable.OffIdentity().ExecuteCommand();//插入可插入部分;
db.Ado.CommitTran();
string msg = $"[菜单数据] 插入{x.InsertList.Count} 错误数据{x.ErrorList.Count} 总共{x.TotalList.Count}";
return (msg, x.ErrorList, x.IgnoreList);
}
@ -84,7 +87,7 @@ namespace ZR.Service.System
.SplitInsert(it => it.NotAny())
.WhereColumns(it => it.DeptId)
.ToStorage();
var result = x.AsInsertable.ExecuteCommand();
var result = x.AsInsertable.OffIdentity().ExecuteCommand();
string msg = $"[部门数据] 插入{x.InsertList.Count} 错误数据{x.ErrorList.Count} 总共{x.TotalList.Count}";
return (msg, x.ErrorList, x.IgnoreList);
@ -218,5 +221,74 @@ namespace ZR.Service.System
string msg = $"[任务数据] 插入{x.InsertList.Count} 错误数据{x.ErrorList.Count} 总共{x.TotalList.Count}";
return (msg, x.ErrorList, x.IgnoreList);
}
/// <summary>
/// 初始化种子数据
/// </summary>
/// <param name="path"></param>
/// <param name="clean"></param>
/// <returns></returns>
public List<string> InitSeedData(string path, bool clean)
{
List<string> result = new();
var db = DbScoped.SugarScope;
if (clean)
{
db.DbMaintenance.TruncateTable<SysRoleDept>();
db.DbMaintenance.TruncateTable<SysRoleMenu>();
db.DbMaintenance.TruncateTable<SysMenu>();
db.DbMaintenance.TruncateTable<SysRole>();
db.DbMaintenance.TruncateTable<SysUser>();
db.DbMaintenance.TruncateTable<SysDept>();
db.DbMaintenance.TruncateTable<SysPost>();
}
var sysUser = MiniExcel.Query<SysUser>(path, sheetName: "user").ToList();
var result1 = InitUserData(sysUser);
result.Add(result1.Item1);
var sysPost = MiniExcel.Query<SysPost>(path, sheetName: "post").ToList();
var result2 = InitPostData(sysPost);
result.Add(result2.Item1);
var sysRole = MiniExcel.Query<SysRole>(path, sheetName: "role").ToList();
var result3 = InitRoleData(sysRole);
result.Add(result3.Item1);
var sysUserRole = MiniExcel.Query<SysUserRole>(path, sheetName: "user_role").ToList();
var result4 = InitUserRoleData(sysUserRole);
result.Add(result4.Item1);
var sysMenu = MiniExcel.Query<SysMenu>(path, sheetName: "menu").ToList();
var result5 = InitMenuData(sysMenu);
result.Add(result5.Item1);
var sysConfig = MiniExcel.Query<SysConfig>(path, sheetName: "config").ToList();
var result6 = InitConfigData(sysConfig);
result.Add(result6.Item1);
var sysRoleMenu = MiniExcel.Query<SysRoleMenu>(path, sheetName: "role_menu").ToList();
var result7 = InitRoleMenuData(sysRoleMenu);
result.Add(result7.Item1);
var sysDict = MiniExcel.Query<SysDictType>(path, sheetName: "dict_type").ToList();
var result8 = InitDictType(sysDict);
result.Add(result8.Item1);
var sysDictData = MiniExcel.Query<SysDictData>(path, sheetName: "dict_data").ToList();
var result9 = InitDictData(sysDictData);
result.Add(result9.Item1);
var sysDept = MiniExcel.Query<SysDept>(path, sheetName: "dept").ToList();
var result10 = InitDeptData(sysDept);
result.Add(result10.Item1);
var sysArticleCategory = MiniExcel.Query<ArticleCategory>(path, sheetName: "article_category").ToList();
var result11 = InitArticleCategoryData(sysArticleCategory);
result.Add(result11.Item1);
return result;
}
}
}

View File

@ -7,6 +7,8 @@ using System.Linq;
using ZR.Common;
using ZR.Model.System;
using ZR.Model.System.Dto;
using ZR.Model.System.Enums;
using ZR.Model.System.Generate;
using ZR.Model.System.Vo;
using ZR.Service.System.IService;
@ -31,17 +33,11 @@ namespace ZR.Service
/// <returns></returns>
public List<SysMenu> SelectTreeMenuList(MenuQueryDto menu, long userId)
{
List<SysMenu> menuList;
//if (SysRoleService.IsAdmin(userId))
//{
// menuList = SelectTreeMenuList(menu);
//}
//else
//{
// var userRoles = SysRoleService.SelectUserRoles(userId);
// menuList = SelectTreeMenuListByRoles(menu, userRoles);
//}
menuList = BuildMenuTree(SelectMenuList(menu, userId));
if (menu.ParentId != null)
{
return GetMenusByMenuId(menu.ParentId.ParseToInt(), userId);
}
List<SysMenu> menuList = BuildMenuTree(SelectMenuList(menu, userId));
return menuList;
}
@ -106,10 +102,10 @@ namespace ZR.Service
/// </summary>
/// <param name="menu"></param>
/// <returns></returns>
public int AddMenu(SysMenu menu)
public long AddMenu(SysMenu menu)
{
menu.Create_time = DateTime.Now;
return InsertReturnIdentity(menu);
return InsertReturnBigIdentity(menu);
}
/// <summary>
@ -117,7 +113,7 @@ namespace ZR.Service
/// </summary>
/// <param name="menu"></param>
/// <returns></returns>
public int EditMenu(SysMenu menu)
public long EditMenu(SysMenu menu)
{
menu.Icon = string.IsNullOrEmpty(menu.Icon) ? "" : menu.Icon;
return Update(menu, false);
@ -219,7 +215,7 @@ namespace ZR.Service
/// <param name="menu"></param>
/// <param name="roles">用户角色集合</param>
/// <returns></returns>
private List<SysMenu> SelectTreeMenuListByRoles(MenuQueryDto menu, List<long> roles)
public List<SysMenu> SelectTreeMenuListByRoles(MenuQueryDto menu, List<long> roles)
{
var roleMenus = Context.Queryable<SysRoleMenu>()
.Where(r => roles.Contains(r.Role_id))
@ -236,20 +232,52 @@ namespace ZR.Service
.ToTree(it => it.Children, it => it.ParentId, 0);
}
/// <summary>
/// 根据用户查询系统菜单列表
/// </summary>
/// <param name="menu"></param>
/// <param name="roleId">用户角色</param>
/// <returns></returns>
public List<RoleMenuExportDto> SelectRoleMenuListByRole(MenuQueryDto menu, int roleId)
{
var menuIds = Context.Queryable<SysRoleMenu>()
.Where(r => r.Role_id == roleId)
.Select(f => f.Menu_id).Distinct().ToList();
return Context.Queryable<SysMenu>()
.InnerJoin<SysMenu>((t1, t2) => t1.MenuId == t2.ParentId)
.InnerJoin<SysMenu>((t1, t2, t3) => t2.MenuId == t3.ParentId)
.Where((t1, t2, t3) => menuIds.Contains(t1.MenuId))
.Select((t1, t2, t3) => new RoleMenuExportDto()
{
MenuName = $"{t1.MenuName}->{t2.MenuName}->{t3.MenuName}",
//MenuName1 = t2.MenuName,
//MenuName2 = t3.MenuName,
Path = t2.Path,
Component = t2.Component,
Perms = t3.Perms,
//MenuType = (MenuType)Enum.Parse(typeof(MenuType), t3.MenuType) //(MenuType)t3.MenuType,
//Status = t3.Status
}).ToList();
}
/// <summary>
/// 获取所有菜单
/// </summary>
/// <returns></returns>
private List<SysMenu> SelectMenuList(MenuQueryDto menu)
{
var menuExp = Expressionable.Create<SysMenu>();
menuExp.AndIF(!string.IsNullOrEmpty(menu.MenuName), it => it.MenuName.Contains(menu.MenuName));
menuExp.AndIF(!string.IsNullOrEmpty(menu.Visible), it => it.Visible == menu.Visible);
menuExp.AndIF(!string.IsNullOrEmpty(menu.Status), it => it.Status == menu.Status);
menuExp.AndIF(!string.IsNullOrEmpty(menu.MenuTypeIds), it => menu.MenuTypeIdArr.Contains(it.MenuType));
menuExp.AndIF(menu.ParentId != null, it => it.ParentId == menu.ParentId);
return Queryable()
.WhereIF(!string.IsNullOrEmpty(menu.MenuName), it => it.MenuName.Contains(menu.MenuName))
.WhereIF(!string.IsNullOrEmpty(menu.Visible), it => it.Visible == menu.Visible)
.WhereIF(!string.IsNullOrEmpty(menu.Status), it => it.Status == menu.Status)
.WhereIF(!string.IsNullOrEmpty(menu.MenuTypeIds), it => menu.MenuTypeIdArr.Contains(it.MenuType))
.WhereIF(menu.ParentId != null, it => it.ParentId == menu.ParentId)
.OrderBy(it => new { it.ParentId, it.OrderNum })
.ToList();
.Where(menuExp.ToExpression())
.OrderBy(it => new { it.ParentId, it.OrderNum })
.ToList();
}
/// <summary>
@ -561,5 +589,110 @@ namespace ZR.Service
}
#endregion
public void AddSysMenu(GenTable genTableInfo, string permPrefix, bool showEdit, bool showExport)
{
var menu = GetFirst(f => f.MenuName == genTableInfo.FunctionName);
if (menu is null)
{
menu = new()
{
MenuName = genTableInfo.FunctionName,
ParentId = genTableInfo.Options.ParentMenuId,
OrderNum = 0,
Path = genTableInfo.BusinessName,
Component = $"{genTableInfo.ModuleName.FirstLowerCase()}/{genTableInfo.BusinessName}",
Perms = $"{permPrefix}:list",
IsCache = "1",
MenuType = "C",
Visible = "0",
Status = "0",
Icon = "icon1",
Create_by = "system",
};
menu.MenuId = AddMenu(menu);
}
List<SysMenu> menuList = new();
SysMenu menuQuery = new()
{
MenuName = "查询",
ParentId = menu.MenuId,
OrderNum = 1,
Perms = $"{permPrefix}:query",
MenuType = "F",
Visible = "0",
Status = "0",
Icon = "",
};
SysMenu menuAdd = new()
{
MenuName = "新增",
ParentId = menu.MenuId,
OrderNum = 2,
Perms = $"{permPrefix}:add",
MenuType = "F",
Visible = "0",
Status = "0",
Icon = "",
};
SysMenu menuDel = new()
{
MenuName = "删除",
ParentId = menu.MenuId,
OrderNum = 3,
Perms = $"{permPrefix}:delete",
MenuType = "F",
Visible = "0",
Status = "0",
Icon = "",
};
SysMenu menuEdit = new()
{
MenuName = "修改",
ParentId = menu.MenuId,
OrderNum = 4,
Perms = $"{permPrefix}:edit",
MenuType = "F",
Visible = "0",
Status = "0",
Icon = "",
};
SysMenu menuExport = new()
{
MenuName = "导出",
ParentId = menu.MenuId,
OrderNum = 5,
Perms = $"{permPrefix}:export",
MenuType = "F",
Visible = "0",
Status = "0",
Icon = "",
};
menuList.Add(menuQuery);
menuList.Add(menuAdd);
menuList.Add(menuDel);
if (showEdit)
{
menuList.Add(menuEdit);
}
if (showExport)
{
menuList.Add(menuExport);
}
//Insert(menuList);
var x = Storageable(menuList)
.SplitInsert(it => !it.Any())
.SplitUpdate(it => !it.Any())
.WhereColumns(it => new { it.MenuName, it.ParentId })
.ToStorage();
x.AsInsertable.ExecuteCommand();//插入可插入部分;
x.AsUpdateable.ExecuteCommand();
}
}
}

View File

@ -28,7 +28,7 @@ namespace ZR.Service.System
var predicate = Expressionable.Create<SysNotice>();
//搜索条件查询语法参考Sqlsugar
predicate = predicate.And(m => m.Status == "0");
predicate = predicate.And(m => m.Status == 0);
return GetList(predicate.ToExpression());
}

View File

@ -39,7 +39,7 @@ namespace ZR.Service
/// 根据条件分页查询用户列表
/// </summary>
/// <returns></returns>
public PagedInfo<SysUser> SelectUserList(SysUser user, PagerInfo pager)
public PagedInfo<SysUser> SelectUserList(SysUserQueryDto user, PagerInfo pager)
{
var exp = Expressionable.Create<SysUser>();
exp.AndIF(!string.IsNullOrEmpty(user.UserName), u => u.UserName.Contains(user.UserName));
@ -51,15 +51,9 @@ namespace ZR.Service
if (user.DeptId != 0)
{
List<SysDept> depts = Context.Queryable<SysDept>().ToList();
var allChildDepts = Context.Queryable<SysDept>().ToChildList(it => it.ParentId, user.DeptId);
var newDepts = depts.FindAll(delegate (SysDept dept)
{
string[] parentDeptId = dept.Ancestors.Split(",", StringSplitOptions.RemoveEmptyEntries);
return parentDeptId.Contains(user.DeptId.ToString());
});
string[] deptArr = newDepts.Select(x => x.DeptId.ToString()).ToArray();
exp.AndIF(user.DeptId != 0, u => u.DeptId == user.DeptId || deptArr.Contains(u.DeptId.ToString()));
exp.And(u => allChildDepts.Select(f => f.DeptId).ToList().Contains(u.DeptId));
}
var query = Queryable()
.LeftJoin<SysDept>((u, dept) => u.DeptId == dept.DeptId)
@ -223,6 +217,10 @@ namespace ZR.Service
{
throw new CustomException("密码强度不符合要求");
}
if (!Tools.CheckUserName(dto.Username))
{
throw new CustomException("用户名不符合要求");
}
//密码md5
string password = NETCore.Encrypt.EncryptProvider.Md5(dto.Password);
@ -325,7 +323,7 @@ namespace ZR.Service
/// <returns></returns>
public SysUser Login(LoginBodyDto user)
{
return GetFirst(it => it.UserName == user.Username && it.Password == user.Password);
return GetFirst(it => it.UserName == user.Username && it.Password.ToLower() == user.Password.ToLower());
}
/// <summary>

View File

@ -34,6 +34,7 @@
"js-beautify": "1.10.2",
"js-cookie": "2.2.0",
"jsencrypt": "3.0.0-rc.1",
"jsrsasign": "^10.8.6",
"less-loader": "^6.0.0",
"mavon-editor": "^2.9.1",
"normalize.css": "7.0.0",

View File

@ -6,7 +6,7 @@ export function login(username, password, code, uuid) {
username,
password,
code,
uuid
uuid,
}
return request({
url: '/login',
@ -19,7 +19,7 @@ export function login(username, password, code, uuid) {
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
method: 'get',
})
}
@ -27,7 +27,7 @@ export function getInfo() {
export function logout() {
return request({
url: '/LogOut',
method: 'POST'
method: 'POST',
})
}
@ -35,18 +35,26 @@ export function logout() {
export function getCodeImg() {
return request({
url: '/captchaImage',
method: 'get'
method: 'get',
})
}
/**
* 注册
* @returns
* @returns
*/
export function register(data) {
return request({
url: '/register',
method: 'post',
data: data
data: data,
})
}
}
// 获取RSA公钥
export function getRsaKey() {
return request({
url: '/getRsaKey',
method: 'get',
})
}

View File

@ -1,6 +1,6 @@
import { login, logout, getInfo } from '@/api/system/login'
import { login, logout, getInfo, getRsaKey } from '@/api/system/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { encryptByPublicKey } from '@/api/utils/jsencrypt'
const user = {
state: {
userInfo: '',
@ -8,7 +8,7 @@ const user = {
name: '',
avatar: '',
roles: [],
permissions: []
permissions: [],
},
mutations: {
@ -29,29 +29,34 @@ const user = {
},
SET_USERINFO: (state, value) => {
state.userInfo = value
}
},
},
actions: {
// 登录
Login({ commit }, userInfo) {
const username = userInfo.username.trim()
const password = userInfo.password
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
if (res.code == 200) {
setToken(res.data)
//提交上面的mutaions方法
commit('SET_TOKEN', res.data)
resolve() //then处理
} else {
console.log('login error ' + res);
reject(res) //catch处理
}
}).catch(err => {
reject(err);
getRsaKey().then((response) => {
const publicKey = response.data.publicKey
const username = userInfo.username.trim()
const password = encryptByPublicKey(userInfo.password, publicKey)
const code = userInfo.code
const uuid = userInfo.uuid
login(username, password, code, uuid)
.then((res) => {
if (res.code == 200) {
setToken(res.data)
//提交上面的mutaions方法
commit('SET_TOKEN', res.data)
resolve() //then处理
} else {
console.log('login error ' + res)
reject(res) //catch处理
}
})
.catch((err) => {
reject(err)
})
})
})
},
@ -59,24 +64,27 @@ const user = {
// 获取用户信息
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const data = res.data
const avatar = data.user.avatar == "" ? require("@/assets/image/profile.jpg") : data.user.avatar;
getInfo()
.then((res) => {
const data = res.data
const avatar = data.user.avatar == '' ? require('@/assets/image/profile.jpg') : data.user.avatar
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', data.roles)
commit('SET_PERMISSIONS', data.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
if (data.roles && data.roles.length > 0) {
// 验证返回的roles是否是一个非空数组
commit('SET_ROLES', data.roles)
commit('SET_PERMISSIONS', data.permissions)
} else {
commit('SET_ROLES', ['ROLE_DEFAULT'])
}
commit('SET_NAME', data.user.nickName)
commit('SET_AVATAR', avatar)
commit('SET_USERINFO', data.user) //新加
resolve(res)
}).catch(error => {
reject(error)
})
commit('SET_NAME', data.user.nickName)
commit('SET_AVATAR', avatar)
commit('SET_USERINFO', data.user) //新加
resolve(res)
})
.catch((error) => {
reject(error)
})
})
},
@ -84,27 +92,29 @@ const user = {
LogOut({ commit, state }) {
console.log('退出登录')
return new Promise((resolve, reject) => {
logout().then((res) => {
removeToken() // 必须先移除token
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
resolve(res)
}).catch(error => {
reject(error)
})
logout()
.then((res) => {
removeToken() // 必须先移除token
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
commit('SET_PERMISSIONS', [])
resolve(res)
})
.catch((error) => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
return new Promise((resolve) => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
}
}
},
},
}
export default user
export default user

View File

@ -1,5 +1,5 @@
import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
import jsrsasign from 'jsrsasign'
// 密钥对生成 http://web.chacuo.net/netrsakeypair
const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALj0zjON+EVdBsnMcR4Uj+jOYgp5ZipftQZ1utW8KvVioz+RSaotF1JHt59q9SC/mZcWWpbpcEqQ3WyyyCC33msCAwEAAQ=='
@ -21,3 +21,7 @@ export function decrypt(txt) {
return encryptor.decrypt(txt) // 对数据进行解密
}
export const encryptByPublicKey = (txt, publicKey) => {
const pubKey = jsrsasign.KEYUTIL.getKey(publicKey)
return jsrsasign.KJUR.crypto.Cipher.encrypt(txt, pubKey)
}

Some files were not shown because too many files have changed in this diff Show More