86 Commits
Author SHA1 Message Date
不做码农 7afaad77ca update README.md 2024-01-05 12:33:37 +08:00
不做码农 0009d99ff7 :arrow_up:升级包 2024-01-03 09:41:58 +08:00
不做码农 bc6ae48588 :bug:fix查看文章详情文章不存在报错 2023-12-24 21:50:30 +08:00
不做码农 2a3d8bab6c :sparkles:新增请求大小限制,默认50M 2023-12-23 20:26:56 +08:00
不做码农 24c2cd1cc7 :sparkles:系统监控数据查询新增登录验证 2023-12-23 20:06:58 +08:00
不做码农 41dbfd511e :pencil:更新文档 2023-12-23 20:03:47 +08:00
不做码农 f9276f10b9 🐛 fix signalr向用户发送消息失败 link https://gitee.com/izory/ZrAdminNetCore/issues/I8NZA1 2023-12-20 14:31:05 +08:00
不做码农 589c707647 :zap:代码生成导入表优化 2023-12-19 20:28:43 +08:00
不做码农 09b6a8fb81 :bug:fix 控制台警告 2023-12-19 20:26:36 +08:00
不做码农 563c757741 :zap:代码生成模板优化&新增前端模板选择 2023-12-19 19:25:47 +08:00
不做码农 542fdd8ff6 :pencil:修改微信通知提示语 2023-12-19 16:58:59 +08:00
不做码农 22b2c35392 :sparkles:新增数据大屏菜单 2023-12-17 16:25:57 +08:00
不做码农 78213d91cf :zap:优化移动端代码生成模板 2023-12-17 16:25:56 +08:00
不做码农 0ee1ab8af5 :sparkles:新增文件下载接口 2023-12-17 16:25:56 +08:00
不做码农 7c78ce8ed5 :zap:代码生成优化 2023-12-17 16:25:56 +08:00
不做码农 d67d401f14 :arrow_up:升级包 2023-12-14 18:16:33 +08:00
不做码农 5103a83e1f :pencil:数据库脚本修改&增加使用说明 2023-12-14 09:29:00 +08:00
不做码农 01daf4f591 :zap:优化代码生成导出模板 2023-12-13 21:18:42 +08:00
不做码农 bfe8b68a94 ⚡ 优化代码生成删除操作 2023-12-12 21:15:25 +08:00
不做码农 925440716b ⚡ 优化代码生成模板 2023-12-12 17:53:14 +08:00
不做码农 10f0d12842 update config.yaml 2023-12-12 17:52:44 +08:00
不做码农 df10dd2cbd ⚡ 优化代码生成字典重复问题 link https://gitee.com/izory/ZrAdminNetCore/issues/I8LL2O 2023-12-12 09:45:42 +08:00
字母搬运工 dac25c8785 !39 update ZR.Vue/package.json.
Merge pull request !39 from xbzhu/N/A
2023-12-12 01:38:11 +00:00
字母搬运工 0d60d4f650 !40 update ZR.Vue/vue.config.js.
Merge pull request !40 from xbzhu/N/A
2023-12-12 01:37:56 +00:00
不做码农 f05dec13da :zap:优化Vue2功能 2023-12-09 19:57:41 +08:00
不做码农 5375b9e308 :zap:代码生成优化&配置文件优化 2023-12-09 14:37:20 +08:00
不做码农 dc6f41d96e :zap:代码生成优化 2023-12-09 12:57:03 +08:00
不做码农 1316e14664 :sparkles:子表代码生成模板新增图片上传组件 2023-12-09 07:40:32 +08:00
不做码农 eed3ffa650 :sparkles:测试任务新增访问数据库示例 2023-12-08 09:21:55 +08:00
不做码农 c7e6e322bc :sparkles:新增执行sql超时记录日志 2023-12-08 09:21:55 +08:00
不做码农 0bcdb1cdfc :sparkles:新增雪花workID配置 2023-12-08 09:21:54 +08:00
不做码农 d8504a194e :zap:代码生成模板优化、同步功能优化 2023-12-08 09:21:54 +08:00
不做码农 8745df6ece :zap:优化代码生成 2023-12-08 08:28:39 +08:00
不做码农 9393b3f6a5 📝 add document/images/23.png 2023-12-07 22:04:46 +08:00
不做码农 e6e4009ea0 📝 update README.md 2023-12-07 22:03:50 +08:00
不做码农 f2a58057d1 :zap:优化操作日志查询 2023-12-07 22:02:50 +08:00
不做码农 9a93282ce7 :sparkles:代码生成新增记录日志配置 2023-12-07 21:31:17 +08:00
不做码农 ae4bb658fd Merge commit 'refs/pull/45/head' of https://gitee.com/izory/ZrAdminNetCore 2023-12-06 13:12:03 +08:00
xbzhu b01335a125 update ZR.Tasks/TaskScheduler/Job_SyncTest.cs.
增加带返回值的Job Demo

Signed-off-by: xbzhu <5430389+xbzhu@user.noreply.gitee.com>
2023-12-06 04:04:23 +00:00
xbzhu 9f6ee330ae update ZR.Tasks/TaskScheduler/JobBase.cs.
增加了构造发放,在执行任务时,接收Job返回的结果,将结果保存在任务执行中。

Signed-off-by: xbzhu <5430389+xbzhu@user.noreply.gitee.com>
2023-12-06 04:01:55 +00:00
字母搬运工 18702eaa38 update .gitee/ISSUE_TEMPLATE/config.yaml.
Signed-off-by: 字母搬运工 <791736813@qq.com>
2023-12-05 07:55:09 +00:00
不做码农 9f8e7dbecc ✨ 新增git反馈提交模板 2023-12-04 16:11:57 +08:00
不做码农 3aec182f0d :arrow_down:降级jnt模板包,最新版本$开头的变量会去掉前面的空格 2023-12-01 15:35:45 +08:00
不做码农 b250cc21df :zap:修改自动刷新token时间为30分钟 2023-11-30 17:40:29 +08:00
不做码农 9b37c26e0d :pencil:update README.md 2023-11-30 14:25:02 +08:00
不做码农 8867c7ba45 :zap:优化代码生成模板 2023-11-30 14:17:12 +08:00
不做码农 3337b9abb3 :zap:优化代码生成 2023-11-29 20:05:39 +08:00
不做码农 eef8962974 :pencil:update README.md 2023-11-28 20:40:34 +08:00
不做码农 98663c9d7e :zap:刷新token新增日志记录 2023-11-28 16:29:11 +08:00
字母搬运工 913a155b50 !42 ping:修复 代码生成时无法更新上级菜单BUG
Merge pull request !42 from ckping0987/master
2023-11-28 08:28:15 +00:00
ckping0987 fe929db358 !1 修复BUG
Merge pull request !1 from ckping0987/feature/ping
2023-11-27 09:08:31 +00:00
Cosmokey 367a78a04c ping:修复 代码生成时无法更新上级菜单BUG 2023-11-27 17:01:52 +08:00
不做码农 11d02d451c ⚡ 优化用户管理 2023-11-26 21:03:35 +08:00
不做码农 11de19a735 :zap:优化初始化数据 2023-11-24 20:17:22 +08:00
字母搬运工 40c4070c49 !41 修复dockerfile
Merge pull request !41 from yuan浩/master
2023-11-23 13:11:41 +00:00
yuan浩 780b32abc4 update ZR.Admin.WebApi/Dockerfile.
Signed-off-by: yuan浩 <8004617+zhang-haoww@user.noreply.gitee.com>
2023-11-23 13:09:41 +00:00
不做码农 e42530379d :zap:优化引用 2023-11-23 18:23:32 +08:00
不做码农 302a2e06c7 :zap:优化基础数据 2023-11-23 18:10:09 +08:00
不做码农 0d68423ce0 :zap:优化命名空间 2023-11-23 18:10:08 +08:00
不做码农 4c91f65759 :arrow_up:升级包 2023-11-23 18:10:08 +08:00
不做码农 aa27674b9c :pencil:update readme 2023-11-22 21:37:47 +08:00
不做码农 ea4acde028 :zap:优化代码生成 2023-11-22 21:37:26 +08:00
不做码农 332acde5a0 :sparkles:代码生成导出数据支持字典类型数据导出 2023-11-22 18:24:55 +08:00
不做码农 d49d59f1e9 :zap:优化代码生成模板 2023-11-21 17:07:21 +08:00
不做码农 de143b04bc :sparkles:新增邮件发送日志 2023-11-21 11:48:22 +08:00
不做码农 e8812787ad :sparkles:代码生成添加方法新增可以生成雪花id列 2023-11-20 17:46:44 +08:00
不做码农 a8fbf4e156 :recycle:文章管理目录调整 2023-11-20 12:57:50 +08:00
不做码农 65e1fcfd49 :zap:优化文章管理权限字符 2023-11-19 21:17:10 +08:00
不做码农 baf3630847 :sparkles:新增手机短信验证码管理 2023-11-19 21:16:59 +08:00
不做码农 df36de52fa :sparkles:新增手机号登录功能 2023-11-19 21:15:41 +08:00
不做码农 f859748825 🗃️ fix:sys_role_menu表缺少字段 2023-11-18 18:40:18 +08:00
不做码农 3f8486f6ce :arrow_up:升级包 2023-11-13 20:04:04 +08:00
不做码农 e234189af3 ✨ 新增邮件模板 2023-11-13 19:56:29 +08:00
不做码农 2e0db37d42 📝 初始化数据修改 2023-11-13 19:38:29 +08:00
不做码农 f78ccc2b4c ⚡ 优化功能 2023-11-12 10:08:42 +08:00
不做码农 2bc2911718 :pencil:update README.md 2023-11-01 20:55:09 +08:00
不做码农 bc4e92bcad :arrow_up:升级包 2023-10-21 10:21:35 +08:00
不做码农 2071219c34 :card_file_box:sys_user表新增province、city字段 2023-10-11 17:42:01 +08:00
不做码农 eca2d2fd73 :card_file_box:SysUser表新增字段 2023-09-27 18:37:44 +08:00
不做码农 d0158f0eef :fire:移除未使用配置初始化数据 2023-09-27 18:29:15 +08:00
不做码农 945f64e46a :zap:优化signalr消息发送接收 2023-09-27 18:28:03 +08:00
不做码农 31980c80bb :zap:角色管理优化 2023-09-27 10:11:48 +08:00
不做码农 56c4b8897b :zap:优化菜单管理查询过滤父节点下架不显示子节点数据 2023-09-26 18:34:01 +08:00
不做码农 1db16082be :zap:优化菜单管理 2023-09-24 16:50:57 +08:00
xbzhu 0dc97f3b9a update ZR.Vue/vue.config.js.
增加了打包分析

Signed-off-by: xbzhu <5430389+xbzhu@user.noreply.gitee.com>
2023-08-03 09:10:15 +00:00
xbzhu cf0559c5d9 update ZR.Vue/package.json.
开发依赖增加了webpack-bundle-analyzer插件,分析打包后的js文件

Signed-off-by: xbzhu <5430389+xbzhu@user.noreply.gitee.com>
2023-08-03 09:07:37 +00:00
207 changed files with 2702 additions and 3585 deletions
+88
View File
@@ -0,0 +1,88 @@
name: 问题反馈
description: 当你在代码中发现了一个 Bug,导致应用崩溃或抛出异常,或者有一个组件存在问题,或者某些地方看起来不对劲。
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
感谢对项目的支持与关注。在提出问题之前,请确保你已查看相关开发或使用文档:
- http://www.izhaorui.cn/doc
- type: checkboxes
attributes:
label: 这个问题是否已经存在?
options:
- label: 我已经搜索过现有的问题 (https://gitee.com/../../issues)
required: true
- type: checkboxes
attributes:
label: 代码是否是最新获取的?
options:
- label: 我已经确认代码是最新主分支的代码
required: true
- type: textarea
attributes:
label: 如何复现
description: 请详细告诉我们如何复现你遇到的问题,如涉及代码,可提供一个最小代码示例,并使用反引号```附上它
placeholder: |
1. ...
2. ...
3. ...
validations:
required: true
- type: textarea
attributes:
label: 预期结果
description: 请告诉我们你预期会发生什么。
validations:
required: false
- type: textarea
attributes:
label: 实际结果
description: 请告诉我们实际发生了什么。
validations:
required: false
- type: textarea
attributes:
label: 截图或视频
description: 如果可以的话,上传任何关于 bug 的截图。
value: |
[在这里上传图片]
- type: dropdown
id: version
attributes:
label: vue版本
description: 你当前正在使用我们软件的哪个前端版本
options:
- vue3 (默认)
- vue2
validations:
required: true
- type: dropdown
id: version
attributes:
label: 运行环境
options:
- 开发环境 (development)
- 生产环境(production)
validations:
required: true
- type: dropdown
id: version
attributes:
label: 应用程序托管
options:
- 前端iis + 后端iis
- 前端nginx + 后端 iis
- 前端nginx + 后端自启动
- docker
- 其他
validations:
required: true
contact_links:
- name: 使用文档
url: http://www.izhaorui.cn/doc/
about: 官方文档
- name: ♥️ VIP 服务 ♥️
url: https://www.izhaorui.cn/doc/support.html
about: 支持作者
+13
View File
@@ -0,0 +1,13 @@
name: 功能建议
description: 对本项目提出一个功能建议
title: "[功能建议]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
感谢对项目的支持与关注。如果你在使用中有什么好的建议欢迎提出来
- type: textarea
attributes:
label: 请输入内容
description: 如果可以的话,上传任何关于 功能 的截图。
@@ -8,6 +8,7 @@ using Newtonsoft.Json.Serialization;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading.Tasks;
using System.Web; using System.Web;
namespace Infrastructure.Controllers namespace Infrastructure.Controllers
@@ -15,6 +16,7 @@ namespace Infrastructure.Controllers
/// <summary> /// <summary>
/// web层通用数据处理 /// web层通用数据处理
/// </summary> /// </summary>
//[ApiController]
public class BaseController : ControllerBase public class BaseController : ControllerBase
{ {
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss"; public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
@@ -74,6 +76,23 @@ namespace Infrastructure.Controllers
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName)); return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
} }
/// <summary>
/// 下载文件
/// </summary>
/// <param name="path"></param>
/// <param name="fileName">文件名,一定要带扩展名</param>
/// <returns></returns>
protected IActionResult DownFile(string path, string fileName)
{
if (!System.IO.File.Exists(path))
{
return NotFound();
}
var stream = System.IO.File.OpenRead(path); //创建文件流
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(stream, "application/octet-stream", HttpUtility.UrlEncode(fileName));
}
#region 方法 #region 方法
/// <summary> /// <summary>
-5
View File
@@ -5,11 +5,6 @@
/// </summary> /// </summary>
public class GlobalConstant public class GlobalConstant
{ {
/// <summary>
/// 代码生成常量
/// </summary>
public static readonly string CodeGenDbConfig;
/// <summary> /// <summary>
/// 管理员权限 /// 管理员权限
/// </summary> /// </summary>
+2 -12
View File
@@ -144,7 +144,7 @@ namespace Infrastructure
/// 写文件 /// 写文件
/// </summary> /// </summary>
/// <param name="path">完整路径带扩展名的</param> /// <param name="path">完整路径带扩展名的</param>
/// <param name="content"></param> /// <param name="content">写入文件内容</param>
public static void WriteAndSave(string path, string content) public static void WriteAndSave(string path, string content)
{ {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
@@ -158,17 +158,7 @@ namespace Infrastructure
Console.WriteLine("开始写入文件,Path=" + path); Console.WriteLine("开始写入文件,Path=" + path);
try try
{ {
//实例化一个文件流--->与写入文件相关联 File.WriteAllText(path, content);
using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
//实例化一个StreamWriter-->与fs相关联
using var sw = new StreamWriter(fs);
//开始写入
sw.Write(content);
//清空缓冲区
sw.Flush();
//关闭流
sw.Close();
fs.Close();
} }
catch (Exception ex) catch (Exception ex)
{ {
+25
View File
@@ -0,0 +1,25 @@
using System;
using System.Text;
namespace ZR.Infrastructure.Helper
{
public class RandomHelper
{
/// <summary>
/// 生成n为验证码
/// </summary>
/// <param name="Length"></param>
/// <returns></returns>
public static string GenerateNum(int Length)
{
char[] constant = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
StringBuilder newRandom = new(constant.Length);
Random rd = new();
for (int i = 0; i < Length; i++)
{
newRandom.Append(constant[rd.Next(constant.Length - 1)]);
}
return newRandom.ToString();
}
}
}
+5 -3
View File
@@ -155,9 +155,11 @@ namespace Infrastructure
{ {
var claims = new List<Claim>() var claims = new List<Claim>()
{ {
new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()), new(ClaimTypes.PrimarySid, user.UserId.ToString()),
new Claim(ClaimTypes.Name, user.UserName), new(ClaimTypes.NameIdentifier, user.UserId.ToString()),
new Claim(ClaimTypes.UserData, JsonConvert.SerializeObject(user)) new(ClaimTypes.Name, user.UserName),
new(ClaimTypes.GroupSid, user.DeptId.ToString()),
new(ClaimTypes.UserData, JsonConvert.SerializeObject(user))
}; };
return claims; return claims;
+9 -15
View File
@@ -1,26 +1,24 @@
using Infrastructure.Constant; using Infrastructure.Constant;
using Newtonsoft.Json;
using System.Collections.Generic; using System.Collections.Generic;
namespace Infrastructure.Model namespace Infrastructure.Model
{ {
public class ApiResult : Dictionary<string, object> public class ApiResult : Dictionary<string, object>
{ {
/** 状态码 */ /// <summary>
/// 状态码
/// </summary>
public static readonly string CODE_TAG = "code"; public static readonly string CODE_TAG = "code";
/** 返回内容 */ /// <summary>
/// 返回内容
/// </summary>
public static readonly string MSG_TAG = "msg"; public static readonly string MSG_TAG = "msg";
/** 数据对象 */
public static readonly string DATA_TAG = "data";
//public int Code { get; set; }
//public string Msg { get; set; }
/// <summary> /// <summary>
/// 如果data值为null,则忽略序列化将不会返回data字段 /// 数据对象
/// </summary> /// </summary>
//[JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public static readonly string DATA_TAG = "data";
//public object Data { get; set; }
/// <summary> /// <summary>
/// 初始化一个新创建的APIResult对象,使其表示一个空消息 /// 初始化一个新创建的APIResult对象,使其表示一个空消息
@@ -55,6 +53,7 @@ namespace Infrastructure.Model
Add(DATA_TAG, data); Add(DATA_TAG, data);
} }
} }
/// <summary> /// <summary>
/// 返回成功消息 /// 返回成功消息
/// </summary> /// </summary>
@@ -125,9 +124,4 @@ namespace Infrastructure.Model
return this; return this;
} }
} }
public class ApiResult<T> : ApiResult
{
public T Result { get; set; }
}
} }
+5 -3
View File
@@ -23,7 +23,7 @@ namespace Infrastructure.Model
public Upload Upload { get; set; } public Upload Upload { get; set; }
public ALIYUN_OSS ALIYUN_OSS { get; set; } public ALIYUN_OSS ALIYUN_OSS { get; set; }
public JwtSettings JwtSettings { get; set; } public JwtSettings JwtSettings { get; set; }
public Gen Gen { get; set; } public CodeGen CodeGen { get; set; }
public List<DbConfigs> DbConfigs { get; set; } public List<DbConfigs> DbConfigs { get; set; }
public DbConfigs CodeGenDbConfig { get; set; } public DbConfigs CodeGenDbConfig { get; set; }
} }
@@ -94,13 +94,15 @@ namespace Infrastructure.Model
public string TokenType { get; set; } = "Bearer"; public string TokenType { get; set; } = "Bearer";
} }
public class Gen public class CodeGen
{ {
public bool ShowApp { get; set; } public bool ShowApp { get; set; }
public bool AutoPre { get; set; } public bool AutoPre { get; set; }
public string VuePath { get; set; } public string VuePath { get; set; }
public string Author { get; set; } public string Author { get; set; }
public DbConfigs GenDbConfig { get; set; } public string TablePrefix { get; set; }
public string ModuleName { get; set; }
public int FrontTpl { get; set; }
public CsharpTypeArr CsharpTypeArr { get; set; } public CsharpTypeArr CsharpTypeArr { get; set; }
} }
+4
View File
@@ -23,5 +23,9 @@ namespace Infrastructure.Model
/// </summary> /// </summary>
public bool SendMe { get; set; } public bool SendMe { get; set; }
public DateTime AddTime { get; set; } public DateTime AddTime { get; set; }
/// <summary>
/// 是否发送
/// </summary>
public bool IsSend { get; set; }
} }
} }
@@ -19,6 +19,7 @@ namespace Infrastructure
types.GetProperty("CreateBy", flag)?.SetValue(source, context.GetName(), null); types.GetProperty("CreateBy", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("Create_by", flag)?.SetValue(source, context.GetName(), null); types.GetProperty("Create_by", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("UserId", flag)?.SetValue(source, context.GetUId(), null); types.GetProperty("UserId", flag)?.SetValue(source, context.GetUId(), null);
types.GetProperty("DeptId", flag)?.SetValue(source, context.GetDeptId(), null);
return source; return source;
} }
@@ -80,6 +80,17 @@ namespace Infrastructure.Extensions
return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0; return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0;
} }
/// <summary>
/// 获取部门id
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static long GetDeptId(this HttpContext context)
{
var deptId = context.User.FindFirstValue(ClaimTypes.GroupSid);
return !string.IsNullOrEmpty(deptId) ? long.Parse(deptId) : 0;
}
/// <summary> /// <summary>
/// 获取登录用户名 /// 获取登录用户名
/// </summary> /// </summary>
@@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace ZR.Infrastructure.WebExtensions
{
public static class RequestLimitExtension
{
/// <summary>
/// 请求body大小设置
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddRequestLimit(this IServiceCollection services, IConfiguration configuration)
{
var sizeM = configuration.GetSection("upload:requestLimitSize").Get<int>();
services.Configure<FormOptions>(x =>
{
x.MultipartBodyLengthLimit = sizeM * 1024 * 1024;
x.MemoryBufferThreshold = sizeM * 1024 * 1024;
x.ValueLengthLimit = int.MaxValue;
});
services.Configure<KestrelServerOptions>(options =>
{
options.Limits.MaxRequestBodySize = sizeM * 1024 * 1024;
});
services.Configure<IISServerOptions>(options =>
{
options.MaxRequestBodySize = sizeM * 1024 * 1024; // 设置最大请求体大小为500MB
});
}
}
}
+3 -3
View File
@@ -17,9 +17,9 @@
<PackageReference Include="UAParser" Version="3.1.47" /> <PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="IPTools.China" Version="1.6.0" /> <PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" />
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" /> <PackageReference Include="JinianNet.JNTemplate" Version="2.4.2" />
<PackageReference Include="MiniExcel" Version="1.31.2" /> <PackageReference Include="MiniExcel" Version="1.31.3" />
<PackageReference Include="CSRedisCore" Version="3.8.670" /> <PackageReference Include="CSRedisCore" Version="3.8.802" />
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" /> <PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
</ItemGroup> </ItemGroup>
+33 -12
View File
@@ -1,12 +1,17 @@
<h2 align="center"> ZR.Admin.NET Back-end management system</h2> <h2 align="center"> ZR.Admin.NET Back-end management system</h2>
<h4 align="center">base .Net7 + vue2.x/vue3.x/uniapp Front-end and back-end separation of .NET rapid development framework</h4> <h4 align="center">base .Net7 + vue2.x/vue3.x/uniapp Front-end and back-end separation of .NET rapid development framework</h4>
<p align="center"> <div style="text-align:center">
<a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a>
<a href='https://gitee.com/izory/ZrAdminNetCore/members'><img src='https://gitee.com/izory/ZrAdminNetCore/badge/fork.svg?theme=dark' alt='fork'></img></a> [![stars](https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark)](https://gitee.com/izory/ZrAdminNetCore)
<a href="https://gitee.com/izory/ZrAdminNetCore/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> [![fork](https://gitee.com//izory/ZrAdminNetCore/badge/fork.svg?theme=dark)](https://gitee.com/izory/ZrAdminNetCore/members)
<a href="http://www.izhaorui.cn/doc/changelog.html"><img src="https://img.shields.io/badge/更新日志-20230920-yellow"/></a> [![Change log](https://img.shields.io/badge/ChangeLog-20240105-yellow)](http://www.izhaorui.cn/doc/changelog.html)
</p>
[![GitHub license](https://img.shields.io/github/license/izhaorui/ZrAdmin.NET)](https://github.com/izhaorui/ZrAdmin.NET/blob/main/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/izhaorui/ZrAdmin.NET?style=social)](https://github.com/izhaorui/ZrAdmin.NET/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/izhaorui/ZrAdmin.NET?style=social)](https://github.com/izhaorui/ZrAdmin.NET/network)
</div>
--- ---
@@ -27,6 +32,10 @@
If it helps you, you can click "Star" in the upper right corner to collect it, so that the author has the motivation to continue to go on for free, thank you! ~ If it helps you, you can click "Star" in the upper right corner to collect it, so that the author has the motivation to continue to go on for free, thank you! ~
``` ```
## 📈 Quick start
- Quick start:[https://www.izhaorui.cn/doc/quickstart.html](https://www.izhaorui.cn/doc/quickstart.html)
## 🍿 Online experience ## 🍿 Online experience
- Official documentation:http://www.izhaorui.cn/doc - Official documentation:http://www.izhaorui.cn/doc
@@ -46,10 +55,10 @@ Since it is a personal project, the funds are limited, and the experience server
## 💒 Code repository ## 💒 Code repository
| repository | Github | Gitee | | repository | Github | Gitee |
| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- | | ---------- | ----------------------------------------------------------- | -------------------------------------------------------- |
| Net7 | [Clone/Download](https://github.com/izhaorui/Zr.Admin.NET) | [Clone/Download](https://gitee.com/izory/ZrAdminNetCore) | | Net7 | [Clone/Download](https://github.com/izhaorui/Zr.Admin.NET) | [Clone/Download](https://gitee.com/izory/ZrAdminNetCore) |
| Vue3(Hot) | [Clone/Download](https://github.com/izhaorui/ZR.Admin.Vue3) | [Clone/Download](https://gitee.com/izory/ZRAdmin-vue) | | Vue3(Hot) | [Clone/Download](https://github.com/izhaorui/ZR.Admin.Vue3) | [Clone/Download](https://gitee.com/izory/ZRAdmin-vue) |
## 🍁 Front-end technology ## 🍁 Front-end technology
@@ -149,9 +158,16 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/19.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/19.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/20.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/20.png"/></td>
</tr> </tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/21.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/22.png"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/23.png"/></td>
</tr>
</table> </table>
## Mobile Storyplate ## 📱 Mobile Storyplate
<table> <table>
<tr> <tr>
@@ -170,8 +186,12 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a7.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a7.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a9.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a9.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a10.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a10.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a11.png"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a12.png"/></td>
</tr> </tr>
</table> </table>
@@ -192,6 +212,7 @@ Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router,
- 👉SqlSugar:[SqlSugar](https://gitee.com/dotnetchina/SqlSugar) - 👉SqlSugar:[SqlSugar](https://gitee.com/dotnetchina/SqlSugar)
- 👉vue-element-admin:[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) - 👉vue-element-admin:[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- 👉Meiam.System:[Meiam.System](https://github.com/91270/Meiam.System) - 👉Meiam.System:[Meiam.System](https://github.com/91270/Meiam.System)
- 👉Furion:[Furion](https://gitee.com/dotnetchina/Furion)
## 🎀 donation ## 🎀 donation
+38 -12
View File
@@ -1,12 +1,24 @@
<h2 align="center"> ZR.Admin.NET后台管理系统</h2> <h2 align="center"> ZR.Admin.NET后台管理系统</h2>
<h4 align="center">基于.Net7 + vue2.x/vue3.x/uniapp前后端分离的.net快速开发框架</h4> <h4 align="center">基于.Net7 + vue2.x/vue3.x/uniapp前后端分离的.net快速开发框架</h4>
<p align="center"> <!-- <p align="center">
<a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/izory/ZrAdminNetCore"><img src="https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark"></a>
<a href='https://gitee.com/izory/ZrAdminNetCore/members'><img src='https://gitee.com/izory/ZrAdminNetCore/badge/fork.svg?theme=dark' alt='fork'></img></a> <a href='https://gitee.com/izory/ZrAdminNetCore/members'><img src='https://gitee.com/izory/ZrAdminNetCore/badge/fork.svg?theme=dark' alt='fork'></img></a>
<a href="https://gitee.com/izory/ZrAdminNetCore/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/izory/ZrAdminNetCore/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
<a href="http://www.izhaorui.cn/doc/changelog.html"><img src="https://img.shields.io/badge/更新日志-20230920-yellow"/></a> <a href="http://www.izhaorui.cn/doc/changelog.html"><img src="https://img.shields.io/badge/更新日志-20230920-yellow"/></a>
</p> </p> -->
<div style="text-align:center">
[![stars](https://gitee.com/izory/ZrAdminNetCore/badge/star.svg?theme=dark)](https://gitee.com/izory/ZrAdminNetCore)
[![fork](https://gitee.com//izory/ZrAdminNetCore/badge/fork.svg?theme=dark)](https://gitee.com/izory/ZrAdminNetCore/members)
[![更新日志](https://img.shields.io/badge/更新日志-20240105-yellow)](http://www.izhaorui.cn/doc/changelog.html)
[![GitHub license](https://img.shields.io/github/license/izhaorui/ZrAdmin.NET)](https://github.com/izhaorui/ZrAdmin.NET/blob/main/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/izhaorui/ZrAdmin.NET?style=social)](https://github.com/izhaorui/ZrAdmin.NET/stargazers)
[![GitHub forks](https://img.shields.io/github/forks/izhaorui/ZrAdmin.NET?style=social)](https://github.com/izhaorui/ZrAdmin.NET/network)
</div>
--- ---
@@ -31,13 +43,17 @@
如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,谢谢!~ 如果对您有帮助,您可以点右上角 “Star” 收藏一下 ,谢谢!~
``` ```
## 📈 快速开始
- 快速开始:[https://www.izhaorui.cn/doc/quickstart.html](https://www.izhaorui.cn/doc/quickstart.html)
## 🍿 在线体验 ## 🍿 在线体验
- 官方文档:http://www.izhaorui.cn/doc - 官方文档:http://www.izhaorui.cn/doc
- 加入群聊:[立即加入](http://www.izhaorui.cn/doc/contact.html) - 加入群聊:[立即加入](http://www.izhaorui.cn/doc/contact.html)
- Vue3.x 版本体验:[http://www.izhaorui.cn/vue3](http://www.izhaorui.cn/vue3) - Vue3.x 版本体验:[http://demo.izhaorui.cn/vue3](http://demo.izhaorui.cn/vue3)
- Vue2.x 版本体验:[http://www.izhaorui.cn/admin](http://www.izhaorui.cn/admin) - Vue2.x 版本体验:[http://demo.izhaorui.cn/admin](http://demo.izhaorui.cn/admin)
- Uniapp 版本体验:[http://www.izhaorui.cn/h5](http://www.izhaorui.cn/h5) - Uniapp 版本体验:[http://demo.izhaorui.cn/h5](http://demo.izhaorui.cn/h5)
- 账号密码:admin/123456,普通用户 user/123456 - 账号密码:admin/123456,普通用户 user/123456
| H5 | 微信小程序 | | H5 | 微信小程序 |
@@ -61,7 +77,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
## 🍀 后端技术 ## 🍀 后端技术
- 核心框架:.Net5.0/.Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis - 核心框架:.Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis
- 定时计划任务:Quartz.Net 组件,支持执行程序集或者 http 网络请求 - 定时计划任务:Quartz.Net 组件,支持执行程序集或者 http 网络请求
- 安全支持:过滤器(数据权限过滤)、Sql 注入、请求伪造 - 安全支持:过滤器(数据权限过滤)、Sql 注入、请求伪造
- 日志管理:NLog、登录日志、操作日志、定时任务日志 - 日志管理:NLog、登录日志、操作日志、定时任务日志
@@ -70,7 +86,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
- 代码生成:高效率开发,代码生成器可以一键生成所有前后端代码 - 代码生成:高效率开发,代码生成器可以一键生成所有前后端代码
- 数据字典:支持数据字典,可以方便对一些状态进行管理 - 数据字典:支持数据字典,可以方便对一些状态进行管理
- 分库分表:使用 orm sqlsugar 可以很轻松的实现分库分库性能优越 - 分库分表:使用 orm sqlsugar 可以很轻松的实现分库分库性能优越
- 多 租 户:支持多租户功能 - 多 租 户:支持多租户功能(多数据库源)
- 缓存数据:内置内存缓存和 Redis - 缓存数据:内置内存缓存和 Redis
- signalR:使用 signalr 管理用户在线状态 - signalR:使用 signalr 管理用户在线状态
@@ -87,7 +103,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
9. 系统接口:使用 swagger 生成相关 api 接口文档。 9. 系统接口:使用 swagger 生成相关 api 接口文档。
10. 服务监控:监视当前系统 CPU、内存、磁盘、堆栈等相关信息。 10. 服务监控:监视当前系统 CPU、内存、磁盘、堆栈等相关信息。
11. 在线构建器:拖动表单元素生成相应的 VUE 代码(仅支持 vue2)。 11. 在线构建器:拖动表单元素生成相应的 VUE 代码(仅支持 vue2)。
12. 任务系统:基于 Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。 12. 任务系统:基于 Quartz.NET,可以在线(添加、修改、删除、手动执行)任务调度包含执行结果日志。
13. 文章管理:可以写文章记录。 13. 文章管理:可以写文章记录。
14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、.sql、uniapp 等)支持下载,自定义配置前端展示控件、让开发更快捷高效(史上最强)。 14. 代码生成:可以一键生成前后端代码(.cs、.vue、.js、.sql、uniapp 等)支持下载,自定义配置前端展示控件、让开发更快捷高效(史上最强)。
15. 参数管理:对系统动态配置常用参数。 15. 参数管理:对系统动态配置常用参数。
@@ -99,6 +115,8 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
21. 在线用户:可以查看正在登录使用的用户,可以对其踢出、通知操作 21. 在线用户:可以查看正在登录使用的用户,可以对其踢出、通知操作
22. db 审计日志:数据库审计功能 22. db 审计日志:数据库审计功能
23. 三方登录:提供三方登录实现逻辑 23. 三方登录:提供三方登录实现逻辑
24. 导入导出:支持中文表头导入、字典数据转换成文本导出
25. 数据大屏:更直观的展示数据
## 🍻 项目结构 ## 🍻 项目结构
@@ -161,10 +179,15 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
</tr> </tr>
<tr> <tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/21.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/21.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/22.png"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/23.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/24.png"/></td>
</tr> </tr>
</table> </table>
## 移动端演示图 ## 📱 移动端演示图
<table> <table>
<tr> <tr>
@@ -183,8 +206,12 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a7.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a7.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a9.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a9.png"/></td>
</tr> </tr>
<tr> <tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a10.png"/></td> <td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a10.png"/></td>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a11.png"/></td>
</tr>
<tr>
<td><img src="https://gitee.com/izory/ZrAdminNetCore/raw/master/document/images/a12.png"/></td>
</tr> </tr>
</table> </table>
@@ -196,9 +223,8 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
3. 前台与后台系统分离,分别为不同的系统(域名可独立) 3. 前台与后台系统分离,分别为不同的系统(域名可独立)
4. 全局异常统一处理 4. 全局异常统一处理
5. 自定义的代码生成功能 5. 自定义的代码生成功能
6. 依赖少,上手容易 6. 依赖少(只需数据库即可使用),上手容易
7. 文档全面 7. 文档全面
8. 支持中文表头导入数据
## 💐 特别鸣谢 ## 💐 特别鸣谢
@@ -1,9 +1,8 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.Dto; using ZR.Model.Dto;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -1,10 +1,9 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SqlSugar; using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -33,7 +32,7 @@ namespace ZR.Admin.WebApi.Controllers
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpGet("list")] [HttpGet("list")]
[ActionPermissionFilter(RolePermi = "admin")] [ActionPermissionFilter(Permission = "system:article:list")]
public IActionResult Query([FromQuery] ArticleQueryDto parm) public IActionResult Query([FromQuery] ArticleQueryDto parm)
{ {
var response = _ArticleService.GetList(parm); var response = _ArticleService.GetList(parm);
@@ -86,6 +85,7 @@ namespace ZR.Admin.WebApi.Controllers
long userId = HttpContext.GetUId(); long userId = HttpContext.GetUId();
var response = _ArticleService.GetId(id); var response = _ArticleService.GetId(id);
var model = response.Adapt<ArticleDto>(); var model = response.Adapt<ArticleDto>();
if (model == null) return ToResponse(ResultCode.FAIL, "文章不存在");
if (model.IsPublic == 0 && userId != model.UserId) if (model.IsPublic == 0 && userId != model.UserId)
{ {
return ToResponse(ResultCode.CUSTOM_ERROR, "访问失败"); return ToResponse(ResultCode.CUSTOM_ERROR, "访问失败");
+30 -36
View File
@@ -1,11 +1,8 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.IService; using ZR.Service.IService;
using ZR.Service.System;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -75,39 +72,6 @@ namespace ZR.Admin.WebApi.Controllers
return SUCCESS(msg); return SUCCESS(msg);
} }
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="sendEmailVo">请求参数接收实体</param>
/// <returns></returns>
[ActionPermissionFilter(Permission = "tool:email:send")]
[Log(Title = "发送邮件")]
[HttpPost]
public IActionResult SendEmail([FromBody] SendEmailDto sendEmailVo)
{
if (sendEmailVo == null)
{
return ToResponse(ApiResult.Error($"请求参数不完整"));
}
if (string.IsNullOrEmpty(OptionsSetting.MailOptions.FromEmail) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password))
{
return ToResponse(ApiResult.Error($"请配置邮箱信息"));
}
MailHelper mailHelper = new();
string[] toUsers = sendEmailVo.ToUser.Split(",", StringSplitOptions.RemoveEmptyEntries);
if (sendEmailVo.SendMe)
{
toUsers.Append(mailHelper.FromEmail);
}
string result = mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent);
logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}, 结果{result}");
return SUCCESS(result);
}
#region 上传 #region 上传
/// <summary> /// <summary>
@@ -187,6 +151,36 @@ namespace ZR.Admin.WebApi.Controllers
#endregion #endregion
/// <summary>
/// 下载文件
/// </summary>
/// <param name="path"></param>
/// <param name="fileId"></param>
/// <returns></returns>
[HttpGet]
[Verify]
[ActionPermissionFilter(Permission = "common")]
[Log(Title = "下载文件", IsSaveResponseData = false)]
public IActionResult DownloadFile(string? path, long fileId = 0)
{
var tempPath = path;
if (fileId > 0)
{
var fileInfo = SysFileService.GetById(fileId);
if (fileInfo != null)
{
tempPath = fileInfo.FileUrl;
}
}
string fullPath = tempPath;
if (tempPath.StartsWith("/"))
{
fullPath = Path.Combine(WebHostEnvironment.WebRootPath, tempPath.ReplaceFirst("/", ""));
}
string fileName = Path.GetFileName(fullPath);
return DownFile(fullPath, fileName);
}
/// <summary> /// <summary>
/// 初始化种子数据 /// 初始化种子数据
/// </summary> /// </summary>
@@ -0,0 +1,142 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using ZR.Admin.WebApi.Filters;
using ZR.Model.Dto;
using ZR.ServiceCore.Model;
using ZR.ServiceCore.Services;
//创建时间:2023-11-20
namespace ZR.Admin.WebApi.Controllers.Email
{
/// <summary>
/// 邮件发送记录
/// </summary>
[Verify]
[Route("system/EmailLog")]
[ApiExplorerSettings(GroupName = "sys")]
public class EmailLogController : BaseController
{
/// <summary>
/// 邮件发送记录接口
/// </summary>
private readonly IEmailLogService _EmailLogService;
private OptionsSetting OptionsSetting;
public EmailLogController(
IEmailLogService EmailLogService,
IOptions<OptionsSetting> options)
{
_EmailLogService = EmailLogService;
OptionsSetting = options.Value;
}
/// <summary>
/// 查询邮件发送记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "emaillog:list")]
public IActionResult QueryEmailLog([FromQuery] EmailLogQueryDto parm)
{
var response = _EmailLogService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询邮件发送记录详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
[ActionPermissionFilter(Permission = "emaillog:query")]
public IActionResult GetEmailLog(long Id)
{
var response = _EmailLogService.GetInfo(Id);
var info = response.Adapt<EmailLogDto>();
return SUCCESS(info);
}
/// <summary>
/// 添加邮件发送记录
/// </summary>
/// <returns></returns>
[HttpPost("sendEmail")]
[ActionPermissionFilter(Permission = "tool:email:send")]
[Log(Title = "邮件发送", BusinessType = BusinessType.INSERT)]
public IActionResult SendEmail([FromBody] EmailLogDto dto)
{
if (dto.IdArr.Length <= 0) { return ToResponse(ApiResult.Error($"发送失败Id 不能为空")); }
int count = 0;
foreach (var item in dto.IdArr)
{
var response = _EmailLogService.GetInfo(item);
if (response?.IsSend == 0)
{
MailHelper mailHelper = new();
string[] toUsers = response.ToEmails.Split(",", StringSplitOptions.RemoveEmptyEntries);
string result = mailHelper.SendMail(toUsers, response.Subject, "", response.FileUrl, response.EmailContent);
count += _EmailLogService.Update(x => x.Id == item, x => new EmailLog()
{
IsSend = 1,
SendTime = DateTime.Now,
SendResult = result
});
}
}
return SUCCESS(count);
}
/// <summary>
/// 删除邮件发送记录
/// </summary>
/// <returns></returns>
[HttpDelete("{ids}")]
[ActionPermissionFilter(Permission = "emaillog:delete")]
[Log(Title = "邮件发送记录", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteEmailLog(string ids)
{
long[] idsArr = Tools.SpitLongArrary(ids);
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
var response = _EmailLogService.Delete(idsArr);
return ToResponse(response);
}
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="sendEmailVo">请求参数接收实体</param>
/// <returns></returns>
[ActionPermissionFilter(Permission = "tool:email:send")]
[Log(Title = "发送邮件")]
[HttpPost("/common/SendEmail")]
public IActionResult SendEmail([FromBody] SendEmailDto sendEmailVo)
{
if (sendEmailVo == null)
{
return ToResponse(ApiResult.Error($"请求参数不完整"));
}
if (string.IsNullOrEmpty(OptionsSetting.MailOptions.FromEmail) || string.IsNullOrEmpty(OptionsSetting.MailOptions.Password))
{
return ToResponse(ApiResult.Error($"请配置邮箱信息"));
}
MailHelper mailHelper = new();
string[] toUsers = sendEmailVo.ToUser.Split(",", StringSplitOptions.RemoveEmptyEntries);
string result = string.Empty;
if (sendEmailVo.IsSend)
{
result = mailHelper.SendMail(toUsers, sendEmailVo.Subject, sendEmailVo.Content, sendEmailVo.FileUrl, sendEmailVo.HtmlContent);
}
_EmailLogService.AddEmailLog(new EmailLog() { EmailContent = sendEmailVo.HtmlContent, Subject = sendEmailVo.Subject, ToEmails = sendEmailVo.ToUser, AddTime = DateTime.Now, FromEmail = OptionsSetting.MailOptions.FromEmail, IsSend = sendEmailVo.IsSend ? 1 : 0, SendResult = result });
//logger.Info($"发送邮件{JsonConvert.SerializeObject(sendEmailVo)}, 结果{result}");
return SUCCESS(result);
}
}
}
@@ -0,0 +1,102 @@
using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters;
using ZR.Model.Dto;
using ZR.ServiceCore.Model;
//创建时间:2023-11-12
namespace ZR.Admin.WebApi.Controllers.Email
{
/// <summary>
/// 邮件模板
/// </summary>
[Verify]
[Route("system/EmailTpl")]
[ApiExplorerSettings(GroupName = "sys")]
public class EmailTplController : BaseController
{
/// <summary>
/// 邮件模板接口
/// </summary>
private readonly IEmailTplService _EmailTplService;
public EmailTplController(IEmailTplService EmailTplService)
{
_EmailTplService = EmailTplService;
}
/// <summary>
/// 查询邮件模板列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "tool:emailtpl:list")]
public IActionResult QueryEmailTpl([FromQuery] EmailTplQueryDto parm)
{
var response = _EmailTplService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 查询邮件模板详情
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
[HttpGet("{Id}")]
public IActionResult GetEmailTpl(int Id)
{
var response = _EmailTplService.GetInfo(Id);
var info = response.Adapt<EmailTpl>();
return SUCCESS(info);
}
/// <summary>
/// 添加邮件模板
/// </summary>
/// <returns></returns>
[HttpPost]
[ActionPermissionFilter(Permission = "tool:emailtpl:add")]
[Log(Title = "邮件模板", BusinessType = BusinessType.INSERT)]
public IActionResult AddEmailTpl([FromBody] EmailTplDto parm)
{
var modal = parm.Adapt<EmailTpl>().ToCreate(HttpContext);
var response = _EmailTplService.AddEmailTpl(modal);
return SUCCESS(response);
}
/// <summary>
/// 更新邮件模板
/// </summary>
/// <returns></returns>
[HttpPut]
[ActionPermissionFilter(Permission = "tool:emailtpl:edit")]
[Log(Title = "邮件模板", BusinessType = BusinessType.UPDATE)]
public IActionResult UpdateEmailTpl([FromBody] EmailTplDto parm)
{
var modal = parm.Adapt<EmailTpl>().ToUpdate(HttpContext);
var response = _EmailTplService.UpdateEmailTpl(modal);
return ToResponse(response);
}
/// <summary>
/// 删除邮件模板
/// </summary>
/// <returns></returns>
[HttpDelete("{ids}")]
[ActionPermissionFilter(Permission = "tool:emailtpl:delete")]
[Log(Title = "邮件模板", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteEmailTpl(string ids)
{
int[] idsArr = Tools.SpitIntArrary(ids);
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
var response = _EmailTplService.Delete(idsArr);
return ToResponse(response);
}
}
}
@@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using SqlSugar; using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.CodeGenerator; using ZR.CodeGenerator;
using ZR.CodeGenerator.Model; using ZR.CodeGenerator.Model;
@@ -8,7 +8,6 @@ using ZR.CodeGenerator.Service;
using ZR.Model; using ZR.Model;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Model.System.Generate; using ZR.Model.System.Generate;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -25,16 +24,20 @@ namespace ZR.Admin.WebApi.Controllers
private readonly IGenTableColumnService GenTableColumnService; private readonly IGenTableColumnService GenTableColumnService;
private readonly ISysMenuService SysMenuService; private readonly ISysMenuService SysMenuService;
private readonly IWebHostEnvironment WebHostEnvironment; private readonly IWebHostEnvironment WebHostEnvironment;
private readonly OptionsSetting OptionsSetting;
public CodeGeneratorController( public CodeGeneratorController(
IGenTableService genTableService, IGenTableService genTableService,
IGenTableColumnService genTableColumnService, IGenTableColumnService genTableColumnService,
IWebHostEnvironment webHostEnvironment, IWebHostEnvironment webHostEnvironment,
IOptions<OptionsSetting> options,
ISysMenuService sysMenuService) ISysMenuService sysMenuService)
{ {
GenTableService = genTableService; GenTableService = genTableService;
GenTableColumnService = genTableColumnService; GenTableColumnService = genTableColumnService;
WebHostEnvironment = webHostEnvironment; WebHostEnvironment = webHostEnvironment;
SysMenuService = sysMenuService; SysMenuService = sysMenuService;
OptionsSetting = options.Value;
} }
/// <summary> /// <summary>
@@ -134,43 +137,47 @@ namespace ZR.Admin.WebApi.Controllers
/// <summary> /// <summary>
/// 导入表结构(保存) /// 导入表结构(保存)
/// </summary> /// </summary>
/// <param name="tables"></param> /// <param name="dto"></param>
/// <param name="dbName"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("importTable")] [HttpPost("importTable")]
[Log(Title = "代码生成", BusinessType = BusinessType.IMPORT)] [Log(Title = "代码生成", BusinessType = BusinessType.IMPORT)]
[ActionPermissionFilter(Permission = "tool:gen:import")] [ActionPermissionFilter(Permission = "tool:gen:import")]
public IActionResult ImportTableSave(string tables, string dbName) public IActionResult ImportTableSave([FromBody] ImportCodeGenTableDto dto)
{ {
if (string.IsNullOrEmpty(tables)) if (string.IsNullOrEmpty(dto.DbName) || dto.Tables == null)
{ {
throw new CustomException("表不能为空"); throw new CustomException("表或数据库不能为空");
} }
DbConfigs dbConfig = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig));
string[] tableNames = tables.Split(',', StringSplitOptions.RemoveEmptyEntries);
int result = 0; int result = 0;
foreach (var tableName in tableNames) foreach (var table in dto.Tables)
{ {
var tabInfo = _CodeGeneraterService.GetTableInfo(dbName, tableName); List<OracleSeq> seqs = new();
if (tabInfo != null) InitTableDto initTableDto = new()
{ {
List<OracleSeq> seqs = new(); DbName = dto.DbName,
GenTable genTable = CodeGeneratorTool.InitTable(dbName, HttpContext.GetName(), tableName, tabInfo?.Description); UserName = HttpContext.GetName(),
genTable.TableId = GenTableService.ImportGenTable(genTable); TableName = table.Name,
if (dbConfig.DbType == 3) Desc = table.Description,
{ CodeGen = OptionsSetting.CodeGen,
seqs = _CodeGeneraterService.GetAllOracleSeqs(dbName); FrontTpl = dto.FrontTpl,
} };
if (genTable.TableId > 0)
{ GenTable genTable = CodeGeneratorTool.InitTable(initTableDto);
//保存列信息 genTable.TableId = GenTableService.ImportGenTable(genTable);
List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(dbName, tableName); if (OptionsSetting.CodeGenDbConfig.DbType == 3)
List<GenTableColumn> genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos, seqs); {
GenTableColumnService.DeleteGenTableColumnByTableName(tableName); seqs = _CodeGeneraterService.GetAllOracleSeqs(table.Name);
GenTableColumnService.InsertGenTableColumn(genTableColumns); }
genTable.Columns = genTableColumns; if (genTable.TableId > 0)
result++; {
} //保存列信息
List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(dto.DbName, table.Name);
List<GenTableColumn> genTableColumns = CodeGeneratorTool.InitGenTableColumn(genTable, dbColumnInfos, seqs, OptionsSetting.CodeGen);
GenTableColumnService.DeleteGenTableColumnByTableName(table.Name);
GenTableColumnService.InsertGenTableColumn(genTableColumns);
genTable.Columns = genTableColumns;
result++;
} }
} }
@@ -195,7 +202,7 @@ namespace ZR.Admin.WebApi.Controllers
var genTable = genTableDto.Adapt<GenTable>().ToUpdate(HttpContext); var genTable = genTableDto.Adapt<GenTable>().ToUpdate(HttpContext);
//将前端额外参数转成字符串存入Options中 //将前端额外参数转成字符串存入Options中
genTable.Options = genTableDto.Params.Adapt<Options>(); genTable.Options = genTableDto.Params.Adapt<CodeOptions>();
DbResult<bool> result = GenTableService.UseTran(() => DbResult<bool> result = GenTableService.UseTran(() =>
{ {
int rows = GenTableService.UpdateGenTable(genTable); int rows = GenTableService.UpdateGenTable(genTable);
@@ -224,9 +231,8 @@ namespace ZR.Admin.WebApi.Controllers
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空"); throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
} }
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId); var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
var dbConfig = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig));
dto.DbType = dbConfig.DbType; dto.DbType = OptionsSetting.CodeGenDbConfig.DbType;
dto.GenTable = genTableInfo; dto.GenTable = genTableInfo;
dto.IsPreview = true; dto.IsPreview = true;
@@ -249,44 +255,53 @@ namespace ZR.Admin.WebApi.Controllers
{ {
throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空"); throw new CustomException(ResultCode.CUSTOM_ERROR, "请求参数为空");
} }
var genTableInfo = GenTableService.GetGenTableInfo(dto.TableId);
var dbConfig = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig));
dto.DbType = dbConfig.DbType; dto.DbType = OptionsSetting.CodeGenDbConfig.DbType;
dto.GenTable = genTableInfo; dto.GenTable = GenTableService.GetGenTableInfo(dto.TableId);
//自定义路径 //生成压缩包
if (genTableInfo.GenType == "1") string zipReturnFileName = $"ZrAdmin.NET-{dto.GenTable.TableName}-{DateTime.Now:MMddHHmmss}.zip";
//生成代码到指定文件夹
CodeGeneratorTool.Generate(dto);
if (dto.GenTable.Options.GenerateMenu)
{ {
var genPath = genTableInfo.GenPath; SysMenuService.AddSysMenu(dto.GenTable, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport, dto.ReplaceDto.ShowBtnImport);
}
if (dto.GenTable.GenType == "1")//自定义路径
{
var genPath = dto.GenTable.GenPath;
string parentPath;
string tempPath = WebHostEnvironment.ContentRootPath; string tempPath = WebHostEnvironment.ContentRootPath;
var parentPath = tempPath[..tempPath.LastIndexOf(@"\")];
if (ComputerHelper.IsUnix())
{
parentPath = Path.Combine(WebHostEnvironment.WebRootPath, "Generatecode");
}
else
{
parentPath = tempPath[..tempPath.LastIndexOf(@"\")];
}
Console.WriteLine("代码生成路径" + parentPath);
//代码生成文件夹路径 //代码生成文件夹路径
dto.GenCodePath = (genPath.IsEmpty() || genPath.Equals("/")) ? parentPath : genTableInfo.GenPath; dto.GenCodePath = (genPath.IsEmpty() || genPath.Equals("/")) ? parentPath : genPath;
} }
else else
{ {
dto.ZipPath = Path.Combine(WebHostEnvironment.WebRootPath, "Generatecode"); dto.ZipPath = Path.Combine(WebHostEnvironment.WebRootPath, "Generatecode");
dto.GenCodePath = Path.Combine(dto.ZipPath, DateTime.Now.ToString("yyyyMMdd")); dto.GenCodePath = Path.Combine(dto.ZipPath, DateTime.Now.ToString("yyyyMMdd"));
} }
//生成压缩包
string zipReturnFileName = $"ZrAdmin.NET-{genTableInfo.TableComment}-{DateTime.Now:MMddHHmmss}.zip";
//生成代码到指定文件夹
CodeGeneratorTool.Generate(dto);
if (genTableInfo.Options.GenerateMenu)
{
SysMenuService.AddSysMenu(genTableInfo, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport, dto.ReplaceDto.ShowBtnImport);
}
//写入文件
foreach (var item in dto.GenCodes) foreach (var item in dto.GenCodes)
{ {
item.Path = Path.Combine(dto.GenCodePath, item.Path); item.Path = Path.Combine(dto.GenCodePath, item.Path);
FileUtil.WriteAndSave(item.Path, item.Content); FileUtil.WriteAndSave(item.Path, item.Content);
} }
if (dto.GenTable.GenType != "1")
//下载文件 {
FileUtil.ZipGenCode(dto.ZipPath, dto.GenCodePath, zipReturnFileName); //压缩文件
FileUtil.ZipGenCode(dto.ZipPath, dto.GenCodePath, zipReturnFileName);
}
return SUCCESS(new { path = "/Generatecode/" + zipReturnFileName, fileName = dto.ZipFileName }); return SUCCESS(new { path = "/Generatecode/" + zipReturnFileName, fileName = dto.ZipFileName });
} }
@@ -306,8 +321,9 @@ namespace ZR.Admin.WebApi.Controllers
if (table == null) { throw new CustomException("同步数据失败,原表结构不存在"); } if (table == null) { throw new CustomException("同步数据失败,原表结构不存在"); }
table.Update_by = HttpContext.GetName(); table.Update_by = HttpContext.GetName();
var codeGen = AppSettings.Get<CodeGen>("codeGen");
List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(table.DbName, tableName); List<DbColumnInfo> dbColumnInfos = _CodeGeneraterService.GetColumnInfo(table.DbName, tableName);
List<GenTableColumn> dbTableColumns = CodeGeneratorTool.InitGenTableColumn(table, dbColumnInfos); List<GenTableColumn> dbTableColumns = CodeGeneratorTool.InitGenTableColumn(table, dbColumnInfos, codeGen: codeGen);
bool result = GenTableService.SynchDb(tableId, table, dbTableColumns); bool result = GenTableService.SynchDb(tableId, table, dbTableColumns);
return SUCCESS(result); return SUCCESS(result);
@@ -1,11 +1,9 @@
using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs; using MiniExcelLibs;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.Dto; using ZR.Model.Dto;
using ZR.Model.Models; using ZR.Model.Models;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -1,11 +1,8 @@
using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SqlSugar; using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -3,7 +3,6 @@ using System.Collections;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -3,7 +3,6 @@ using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -4,7 +4,7 @@ using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -3,7 +3,6 @@ using SqlSugar;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
{ {
@@ -1,11 +1,10 @@
using Lazy.Captcha.Core; using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Infrastructure.Helper;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System; using ZR.ServiceCore.Model.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -15,8 +14,6 @@ namespace ZR.Admin.WebApi.Controllers.System
[ApiExplorerSettings(GroupName = "sys")] [ApiExplorerSettings(GroupName = "sys")]
public class SysLoginController : BaseController public class SysLoginController : BaseController
{ {
//static readonly NLog.Logger logger = NLog.LogManager.GetLogger("LoginController");
private readonly IHttpContextAccessor httpContextAccessor;
private readonly ISysUserService sysUserService; private readonly ISysUserService sysUserService;
private readonly ISysMenuService sysMenuService; private readonly ISysMenuService sysMenuService;
private readonly ISysLoginService sysLoginService; private readonly ISysLoginService sysLoginService;
@@ -24,28 +21,26 @@ namespace ZR.Admin.WebApi.Controllers.System
private readonly ICaptcha SecurityCodeHelper; private readonly ICaptcha SecurityCodeHelper;
private readonly ISysConfigService sysConfigService; private readonly ISysConfigService sysConfigService;
private readonly ISysRoleService roleService; private readonly ISysRoleService roleService;
private readonly OptionsSetting optionSettings; private readonly ISmsCodeLogService smsCodeLogService;
public SysLoginController( public SysLoginController(
IHttpContextAccessor contextAccessor,
ISysMenuService sysMenuService, ISysMenuService sysMenuService,
ISysUserService sysUserService, ISysUserService sysUserService,
ISysLoginService sysLoginService, ISysLoginService sysLoginService,
ISysPermissionService permissionService, ISysPermissionService permissionService,
ISysConfigService configService, ISysConfigService configService,
ISysRoleService sysRoleService, ISysRoleService sysRoleService,
ICaptcha captcha, ISmsCodeLogService smsCodeLogService,
IOptions<OptionsSetting> optionSettings) ICaptcha captcha)
{ {
httpContextAccessor = contextAccessor;
SecurityCodeHelper = captcha; SecurityCodeHelper = captcha;
this.sysMenuService = sysMenuService; this.sysMenuService = sysMenuService;
this.sysUserService = sysUserService; this.sysUserService = sysUserService;
this.sysLoginService = sysLoginService; this.sysLoginService = sysLoginService;
this.permissionService = permissionService; this.permissionService = permissionService;
this.sysConfigService = configService; this.sysConfigService = configService;
this.smsCodeLogService = smsCodeLogService;
roleService = sysRoleService; roleService = sysRoleService;
this.optionSettings = optionSettings.Value;
} }
@@ -172,7 +167,7 @@ namespace ZR.Admin.WebApi.Controllers.System
{ {
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误"); return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
} }
dto.UserIP = HttpContext.GetClientUserIp();
SysUser user = sysUserService.Register(dto); SysUser user = sysUserService.Register(dto);
if (user.UserId > 0) if (user.UserId > 0)
{ {
@@ -261,5 +256,73 @@ namespace ZR.Admin.WebApi.Controllers.System
} }
#endregion #endregion
/// <summary>
///
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPost("checkMobile")]
[Log(Title = "发送短息", BusinessType = BusinessType.INSERT)]
public IActionResult CheckMobile([FromBody] PhoneLoginDto dto)
{
dto.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
if (sysConfig?.ConfigValue != "off" && !SecurityCodeHelper.Validate(dto.Uuid, dto.Code, false))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "验证码错误");
}
string location = HttpContextExtension.GetIpInfo(dto.LoginIP);
var info = sysUserService.GetFirst(f => f.Phonenumber == dto.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
var smsCode = RandomHelper.GenerateNum(6);
var smsContent = $"验证码{smsCode}(随机验证码),有效期10分钟。";
//TODO 发送短息验证码,1分钟内允许一次
smsCodeLogService.AddSmscodeLog(new ServiceCore.Model.SmsCodeLog()
{
Userid = info.UserId,
PhoneNum = dto.PhoneNum.ParseToLong(),
AddTime = DateTime.Now,
SendType = 1,
SmsCode = smsCode,
SmsContent = smsContent,
UserIP = dto.LoginIP,
Location = location,
});
CacheService.SetPhoneCode(dto.PhoneNum, smsCode);
return SUCCESS(new { smsCode });
}
/// <summary>
/// 手机号登录
/// </summary>
/// <param name="loginBody">登录对象</param>
/// <returns></returns>
[Route("PhoneLogin")]
[HttpPost]
[Log(Title = "手机号登录")]
public IActionResult PhoneLogin([FromBody] PhoneLoginDto loginBody)
{
if (loginBody == null) { throw new CustomException("请求参数错误"); }
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
if (!CacheService.CheckPhoneCode(loginBody.PhoneNum, loginBody.PhoneCode))
{
return ToResponse(ResultCode.CUSTOM_ERROR, "短信验证码错误");
}
var info = sysUserService.GetFirst(f => f.Phonenumber == loginBody.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
sysLoginService.CheckLockUser(info.UserName);
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
var user = sysLoginService.PhoneLogin(loginBody, new SysLogininfor() { LoginLocation = location }, info);
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
//权限集合 eg *:*:*,system:user:list
List<string> permissions = permissionService.GetMenuPermission(user);
TokenModel loginUser = new(user.Adapt<TokenModel>(), roles.Adapt<List<Roles>>());
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
}
} }
} }
@@ -2,7 +2,7 @@
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -28,16 +28,28 @@ namespace ZR.Admin.WebApi.Controllers.System
this.sysRoleMenuService = sysRoleMenuService; this.sysRoleMenuService = sysRoleMenuService;
} }
/// <summary>
/// 获取菜单树列表
/// </summary>
/// <returns></returns>
[ActionPermissionFilter(Permission = "system:menu:list")]
[HttpGet("treelist")]
public IActionResult TreeMenuList([FromQuery] MenuQueryDto menu)
{
long userId = HttpContext.GetUId();
return SUCCESS(sysMenuService.SelectTreeMenuList(menu, userId), "yyyy-MM-dd HH:mm:ss");
}
/// <summary> /// <summary>
/// 获取菜单列表 /// 获取菜单列表
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[ActionPermissionFilter(Permission = "system:menu:list")] [ActionPermissionFilter(Permission = "system:menu:list")]
[HttpGet("list")] [HttpGet("list")]
public IActionResult TreeMenuList([FromQuery] MenuQueryDto menu) public IActionResult MenuList([FromQuery] MenuQueryDto menu)
{ {
long userId = HttpContext.GetUId(); long userId = HttpContext.GetUId();
return SUCCESS(sysMenuService.SelectTreeMenuList(menu, userId), "yyyy-MM-dd HH:mm:ss"); return SUCCESS(sysMenuService.SelectMenuList(menu, userId), "yyyy-MM-dd HH:mm:ss");
} }
/// <summary> /// <summary>
@@ -5,7 +5,6 @@ using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
using ZR.ServiceCore.Signalr; using ZR.ServiceCore.Signalr;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
@@ -3,7 +3,7 @@ using SqlSugar;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -3,7 +3,7 @@ using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -168,7 +168,7 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns> /// <returns></returns>
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色导出")] [Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色导出")]
[HttpGet("export")] [HttpGet("export")]
//[ActionPermissionFilter(Permission = "system:role:export")] [ActionPermissionFilter(Permission = "system:role:export")]
public IActionResult Export() public IActionResult Export()
{ {
var list = sysRoleService.SelectRoleAll(); var list = sysRoleService.SelectRoleAll();
@@ -184,7 +184,7 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <returns></returns> /// <returns></returns>
[Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色菜单导出")] [Log(BusinessType = BusinessType.EXPORT, IsSaveResponseData = false, Title = "角色菜单导出")]
[HttpGet("exportRoleMenu")] [HttpGet("exportRoleMenu")]
[AllowAnonymous] [ActionPermissionFilter(Permission = "system:role:export")]
public IActionResult ExportRoleMenu(int roleId) public IActionResult ExportRoleMenu(int roleId)
{ {
MenuQueryDto dto = new() { Status = "0", MenuTypeIds = "M,C,F" }; MenuQueryDto dto = new() { Status = "0", MenuTypeIds = "M,C,F" };
@@ -5,7 +5,6 @@ using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -79,21 +78,20 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <summary> /// <summary>
/// 添加用户 /// 添加用户
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="parm"></param>
/// <returns></returns> /// <returns></returns>
[HttpPost("edit")] [HttpPost("add")]
[Log(Title = "用户管理", BusinessType = BusinessType.INSERT)] [Log(Title = "用户管理", BusinessType = BusinessType.INSERT)]
[ActionPermissionFilter(Permission = "system:user:add")] [ActionPermissionFilter(Permission = "system:user:add")]
public IActionResult AddUser([FromBody] SysUser user) public IActionResult AddUser([FromBody] SysUserDto parm)
{ {
var user = parm.Adapt<SysUser>().ToCreate(HttpContext);
if (user == null) { return ToResponse(ApiResult.Error(101, "请求参数错误")); } if (user == null) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
if (UserConstants.NOT_UNIQUE.Equals(UserService.CheckUserNameUnique(user.UserName))) if (UserConstants.NOT_UNIQUE.Equals(UserService.CheckUserNameUnique(user.UserName)))
{ {
return ToResponse(ApiResult.Error($"新增用户 '{user.UserName}'失败,登录账号已存在")); return ToResponse(ApiResult.Error($"新增用户 '{user.UserName}'失败,登录账号已存在"));
} }
user.Create_by = HttpContext.GetName();
user.Create_time = DateTime.Now;
user.Password = NETCore.Encrypt.EncryptProvider.Md5(user.Password); user.Password = NETCore.Encrypt.EncryptProvider.Md5(user.Password);
return SUCCESS(UserService.InsertUser(user)); return SUCCESS(UserService.InsertUser(user));
@@ -102,16 +100,16 @@ namespace ZR.Admin.WebApi.Controllers.System
/// <summary> /// <summary>
/// 修改用户 /// 修改用户
/// </summary> /// </summary>
/// <param name="user"></param> /// <param name="parm"></param>
/// <returns></returns> /// <returns></returns>
[HttpPut("edit")] [HttpPut("edit")]
[Log(Title = "用户管理", BusinessType = BusinessType.UPDATE)] [Log(Title = "用户管理", BusinessType = BusinessType.UPDATE)]
[ActionPermissionFilter(Permission = "system:user:edit")] [ActionPermissionFilter(Permission = "system:user:edit")]
public IActionResult UpdateUser([FromBody] SysUser user) public IActionResult UpdateUser([FromBody] SysUserDto parm)
{ {
var user = parm.Adapt<SysUser>().ToUpdate(HttpContext);
if (user == null || user.UserId <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); } if (user == null || user.UserId <= 0) { return ToResponse(ApiResult.Error(101, "请求参数错误")); }
user.Update_by = HttpContext.GetName();
int upResult = UserService.UpdateUser(user); int upResult = UserService.UpdateUser(user);
return ToResponse(upResult); return ToResponse(upResult);
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -4,7 +4,7 @@ using SqlSugar;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
using ZR.Tasks; using ZR.Tasks;
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
@@ -4,7 +4,7 @@ using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System namespace ZR.Admin.WebApi.Controllers.System
{ {
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ZR.Admin.WebApi.Filters;
namespace ZR.Admin.WebApi.Controllers.monitor namespace ZR.Admin.WebApi.Controllers.monitor
{ {
@@ -10,6 +11,7 @@ namespace ZR.Admin.WebApi.Controllers.monitor
/// 系统监控 /// 系统监控
/// </summary> /// </summary>
[ApiExplorerSettings(GroupName = "sys")] [ApiExplorerSettings(GroupName = "sys")]
[Verify]
public class MonitorController : BaseController public class MonitorController : BaseController
{ {
private OptionsSetting Options; private OptionsSetting Options;
@@ -0,0 +1,77 @@
using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters;
using ZR.Model.Dto;
using ZR.ServiceCore.Services;
//创建时间:2023-11-19
namespace ZR.Admin.WebApi.Controllers.System.monitor
{
/// <summary>
/// 短信验证码记录
/// </summary>
[Verify]
[Route("system/SmscodeLog")]
[ApiExplorerSettings(GroupName = "sys")]
public class SmsCodeLogController : BaseController
{
/// <summary>
/// 短信验证码记录接口
/// </summary>
private readonly ISmsCodeLogService _SmscodeLogService;
public SmsCodeLogController(ISmsCodeLogService SmscodeLogService)
{
_SmscodeLogService = SmscodeLogService;
}
/// <summary>
/// 查询短信验证码记录列表
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
[HttpGet("list")]
[ActionPermissionFilter(Permission = "smscodelog:list")]
public IActionResult QuerySmscodeLog([FromQuery] SmscodeLogQueryDto parm)
{
var response = _SmscodeLogService.GetList(parm);
return SUCCESS(response);
}
/// <summary>
/// 删除短信验证码记录
/// </summary>
/// <returns></returns>
[HttpDelete("{ids}")]
[ActionPermissionFilter(Permission = "smscodelog:delete")]
[Log(Title = "短信验证码记录", BusinessType = BusinessType.DELETE)]
public IActionResult DeleteSmscodeLog(string ids)
{
long[] idsArr = Tools.SpitLongArrary(ids);
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
var response = _SmscodeLogService.Delete(idsArr);
return ToResponse(response);
}
/// <summary>
/// 导出短信验证码记录
/// </summary>
/// <returns></returns>
[Log(Title = "短信验证码记录", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
[HttpGet("export")]
[ActionPermissionFilter(Permission = "smscodelog:export")]
public IActionResult Export([FromQuery] SmscodeLogQueryDto parm)
{
parm.PageNum = 1;
parm.PageSize = 100000;
var list = _SmscodeLogService.GetList(parm).Result;
if (list == null || list.Count <= 0)
{
return ToResponse(ResultCode.FAIL, "没有要导出的数据");
}
var result = ExportExcelMini(list, "短信验证码记录", "短信验证码记录");
return ExportExcel(result.Item2, result.Item1);
}
}
}
@@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
//创建时间:2023-08-17 //创建时间:2023-08-17
namespace ZR.Admin.WebApi.Controllers namespace ZR.Admin.WebApi.Controllers
@@ -4,7 +4,7 @@ using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model; using ZR.Model;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.monitor namespace ZR.Admin.WebApi.Controllers.monitor
{ {
@@ -1,8 +1,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters; using ZR.Admin.WebApi.Filters;
using ZR.Model.System.Dto; using ZR.Model.System.Dto;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.monitor namespace ZR.Admin.WebApi.Controllers.monitor
{ {
@@ -15,12 +14,10 @@ namespace ZR.Admin.WebApi.Controllers.monitor
public class SysOperlogController : BaseController public class SysOperlogController : BaseController
{ {
private ISysOperLogService sysOperLogService; private ISysOperLogService sysOperLogService;
private IWebHostEnvironment WebHostEnvironment;
public SysOperlogController(ISysOperLogService sysOperLogService, IWebHostEnvironment hostEnvironment) public SysOperlogController(ISysOperLogService sysOperLogService)
{ {
this.sysOperLogService = sysOperLogService; this.sysOperLogService = sysOperLogService;
WebHostEnvironment = hostEnvironment;
} }
/// <summary> /// <summary>
+1 -1
View File
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
#创建 /app文件夹 #创建 /app文件夹
WORKDIR /app WORKDIR /app
#创建挂载目录,用于将程序部署在服务器本地 #创建挂载目录,用于将程序部署在服务器本地
@@ -1,4 +1,5 @@
using Quartz.Spi; using Quartz.Spi;
using SqlSugar;
using SqlSugar.IOC; using SqlSugar.IOC;
using ZR.Model.System; using ZR.Model.System;
using ZR.Tasks; using ZR.Tasks;
@@ -49,5 +50,29 @@ namespace ZR.Admin.WebApi.Extensions
return app; return app;
} }
/// <summary>
/// 初始化字典
/// </summary>
/// <param name="app"></param>
/// <returns></returns>
public static IApplicationBuilder UseInit(this IApplicationBuilder app)
{
Console.WriteLine("初始化字典数据...");
var db = DbScoped.SugarScope;
var types = db.Queryable<SysDictType>()
.Where(it => it.Status == "0")
.Select(it => it.DictType)
.ToList();
//上面有耗时操作写在Any上面,保证程序启动后只执行一次
if (!db.ConfigQuery.Any())
{
foreach (var type in types)
{
db.ConfigQuery.SetTable<SysDictData>(it => SqlFunc.ToString(it.DictValue), it => it.DictLabel, type, it => it.DictType == type);
}
}
return app;
}
} }
} }
+1
View File
@@ -8,3 +8,4 @@ global using Mapster;
global using Infrastructure.Extensions; global using Infrastructure.Extensions;
global using Infrastructure.Controllers; global using Infrastructure.Controllers;
global using ZR.ServiceCore.Middleware; global using ZR.ServiceCore.Middleware;
global using ZR.ServiceCore.Services;
+14 -3
View File
@@ -2,8 +2,8 @@ using AspNetCoreRateLimit;
using Infrastructure.Converter; using Infrastructure.Converter;
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.DataProtection;
using NLog.Web; using NLog.Web;
using SqlSugar;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Serialization;
using ZR.Admin.WebApi.Extensions; using ZR.Admin.WebApi.Extensions;
using ZR.Common.Cache; using ZR.Common.Cache;
using ZR.Infrastructure.WebExtensions; using ZR.Infrastructure.WebExtensions;
@@ -37,7 +37,8 @@ builder.Services.AddIPRate(builder.Configuration);
builder.Services.AddHttpContextAccessor(); builder.Services.AddHttpContextAccessor();
//绑定整个对象到Model上 //绑定整个对象到Model上
builder.Services.Configure<OptionsSetting>(builder.Configuration); builder.Services.Configure<OptionsSetting>(builder.Configuration);
builder.Configuration.AddJsonFile("codeGen.json");
builder.Configuration.AddJsonFile("iprate.json");
//jwt 认证 //jwt 认证
builder.Services.AddJwt(); builder.Services.AddJwt();
//配置文件 //配置文件
@@ -46,6 +47,8 @@ builder.Services.AddSingleton(new AppSettings(builder.Configuration));
builder.Services.AddAppService(); builder.Services.AddAppService();
//开启计划任务 //开启计划任务
builder.Services.AddTaskSchedulers(); builder.Services.AddTaskSchedulers();
//请求大小限制
builder.Services.AddRequestLimit(builder.Configuration);
//注册REDIS 服务 //注册REDIS 服务
var openRedis = builder.Configuration["RedisServer:open"]; var openRedis = builder.Configuration["RedisServer:open"];
@@ -83,7 +86,12 @@ InternalApp.Configuration = builder.Configuration;
InternalApp.WebHostEnvironment = app.Environment; InternalApp.WebHostEnvironment = app.Environment;
//初始化db //初始化db
builder.Services.AddDb(app.Environment); builder.Services.AddDb(app.Environment);
var workId = builder.Configuration["workId"].ParseToInt();
if (app.Environment.IsDevelopment())
{
workId += 1;
}
SnowFlakeSingle.WorkId = workId;
//使用全局异常中间件 //使用全局异常中间件
app.UseMiddleware<GlobalExceptionMiddleware>(); app.UseMiddleware<GlobalExceptionMiddleware>();
@@ -121,6 +129,9 @@ if (builder.Environment.IsProduction())
//恢复/启动任务 //恢复/启动任务
app.UseAddTaskSchedulers(); app.UseAddTaskSchedulers();
} }
//初始化字典数据
app.UseInit();
//使用swagger //使用swagger
app.UseSwagger(); app.UseSwagger();
//启用客户端IP限制速率 //启用客户端IP限制速率
+5 -5
View File
@@ -15,12 +15,12 @@
<ProjectReference Include="..\ZR.Tasks\ZR.Tasks.csproj" /> <ProjectReference Include="..\ZR.Tasks\ZR.Tasks.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.3" /> <PackageReference Include="Lazy.Captcha.Core" Version="2.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" /> <PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.12" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.3" /> <PackageReference Include="NLog.Web.AspNetCore" Version="5.3.8" />
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.5" /> <PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.88.6" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+18 -51
View File
@@ -30,19 +30,22 @@
"Audience": "ZRAdmin.NET", //指该token是服务于哪个群体的(群体范围) "Audience": "ZRAdmin.NET", //指该token是服务于哪个群体的(群体范围)
"SecretKey": "SecretKey-ZRADMIN.NET-20210101", "SecretKey": "SecretKey-ZRADMIN.NET-20210101",
"Expire": 1440, //jwt登录过期时间(分) "Expire": 1440, //jwt登录过期时间(分)
"RefreshTokenTime": 5,//分钟 "RefreshTokenTime": 30, //分钟
"TokenType": "Bearer" "TokenType": "Bearer"
}, },
"InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks", "ZR.ServiceCore" ], //自动注入类 "InjectClass": [ "ZR.Repository", "ZR.Service", "ZR.Tasks", "ZR.ServiceCore" ], //自动注入类
"ShowDbLog": true, //是否打印db日志 "ShowDbLog": true, //是否打印db日志
"InitDb": false, //是否初始化db "InitDb": false, //是否初始化db
"DemoMode": false, //是否演示模式 "DemoMode": false, //是否演示模式
"SingleLogin": false,//是否单点登录 "SingleLogin": false, //是否允许多设备/浏览器登录
"workId": 1, //雪花id唯一数字
"sqlExecutionTime": 5, //Sql执行时间超过多少秒记录日志并警报
"Upload": { "Upload": {
"uploadUrl": "http://localhost:8888", //本地存储资源访问路径 "uploadUrl": "http://localhost:8888", //本地存储资源访问路径
"localSavePath": "", //本地上传默认文件存储目录 wwwroot "localSavePath": "", //本地上传默认文件存储目录 wwwroot
"maxSize": 15, //上传文件大小限制 15M "maxSize": 15, //上传文件大小限制 15M
"notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ] "notAllowedExt": [ ".bat", ".exe", ".jar", ".js" ],
"requestLimitSize": 50//请求body大小限制
}, },
//阿里云存储配置 //阿里云存储配置
"ALIYUN_OSS": { "ALIYUN_OSS": {
@@ -65,26 +68,6 @@
"AppID": "", "AppID": "",
"AppSecret": "" "AppSecret": ""
}, },
//代码生成配置
"gen": {
//是否显示移动端代码生成
"showApp": false,
//自动去除表前缀
"autoPre": true,
"author": "admin",
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
"vuePath": "", //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
"csharpTypeArr": {
"string": [ "varchar", "nvarchar", "text", "longtext" ],
"int": [ "int", "integer", "smallint", "int4", "int8", "int2" ],
"long": [ "bigint", "number" ],
"float": [ "numeric", "real", "float" ],
"decimal": [ "money", "decimal", "smallmoney" ],
"dateTime": [ "date", "datetime", "datetime2", "smalldatetime", "timestamp" ],
"byte": [ "tinyint" ],
"bool": [ "bit" ]
}
},
//邮箱配置信息 //邮箱配置信息
"MailOptions": { "MailOptions": {
//发件人名称 //发件人名称
@@ -105,36 +88,20 @@
"Cache": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:", "Cache": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=cache:",
"Session": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:" "Session": "127.0.0.1:6379,defaultDatabase=0,poolsize=50,ssl=false,writeBuffer=10240,prefix=session:"
}, },
//接口请求限制
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
"ContentType": "application/json",
"StatusCode": 429
},
//通用规则,api规则,结尾一定要带*
"GeneralRules": [
{
"Endpoint": "*:/captchaImage",
//时间段,格式:{数字}{单位};可使用单位:s, m, h, d
"Period": "3s",
"Limit": 5
},
{
"Endpoint": "((post)|(put)):*",
"Period": "3s",
"Limit": 1
}
]
},
//验证码配置 //验证码配置
"CaptchaOptions": { "CaptchaOptions": {
"IgnoreCase": true // 比较时是否忽略大小写 "IgnoreCase": true // 比较时是否忽略大小写
},
//代码生成配置
"CodeGen": {
//是否显示移动端代码生成
"showApp": false,
//自动去除表前缀
"autoPre": true,
//默认生成业务模块名
"moduleName": "business",
"author": "admin",
"tablePrefix": "sys_", //"表前缀(生成类名不会包含表前缀,多个用逗号分隔)",
"vuePath": "" //前端代码存储路径eg:D:\Work\ZRAdmin-Vue3
} }
} }
+14
View File
@@ -0,0 +1,14 @@
{
"CodeGen": {
"csharpTypeArr": {
"string": [ "varchar", "nvarchar", "text", "longtext" ],
"int": [ "int", "integer", "smallint", "int4", "int8", "int2" ],
"long": [ "bigint", "number" ],
"float": [ "numeric", "real", "float" ],
"decimal": [ "money", "decimal", "smallmoney" ],
"dateTime": [ "date", "datetime", "datetime2", "smalldatetime", "timestamp" ],
"byte": [ "tinyint" ],
"bool": [ "bit" ]
}
}
}
+30
View File
@@ -0,0 +1,30 @@
{
//接口请求限制
"IpRateLimiting": {
"EnableEndpointRateLimiting": true,
"StackBlockedRequests": false,
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
"EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
"ContentType": "application/json",
"StatusCode": 429
},
//通用规则,api规则,结尾一定要带*
"GeneralRules": [
{
"Endpoint": "*:/captchaImage",
//时间段,格式:{数字}{单位};可使用单位:s, m, h, d
"Period": "3s",
"Limit": 5
},
{
"Endpoint": "((post)|(put)):*",
"Period": "3s",
"Limit": 1
}
]
}
}
@@ -80,7 +80,7 @@ $if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
*/ */
export function del${genTable.BusinessName}(pid) { export function del${genTable.BusinessName}(pid) {
return request({ return request({
url: '${genTable.ModuleName}/${genTable.BusinessName}/' + pid, url: '${genTable.ModuleName}/${genTable.BusinessName}/delete/' + pid,
method: 'delete' method: 'delete'
}) })
} }
@@ -0,0 +1 @@
你在期待什么...
@@ -56,7 +56,7 @@ $if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
*/ */
export function del${genTable.BusinessName}(pid) { export function del${genTable.BusinessName}(pid) {
return request({ return request({
url: '/${genTable.ModuleName}/${genTable.BusinessName}/' + pid, url: '/${genTable.ModuleName}/${genTable.BusinessName}/delete/' + pid,
method: 'delete' method: 'delete'
}) })
} }
@@ -73,6 +73,6 @@ $end
$if(replaceDto.ShowBtnExport) $if(replaceDto.ShowBtnExport)
// 导出${genTable.functionName} // 导出${genTable.functionName}
export async function export${genTable.BusinessName}(query) { export async function export${genTable.BusinessName}(query) {
await downFile('$/{genTable.ModuleName}/${genTable.BusinessName}/export', { ...query }) await downFile('/${genTable.ModuleName}/${genTable.BusinessName}/export', { ...query })
} }
$end $end
@@ -12,7 +12,7 @@ $if(column.CsharpType == "int" || column.CsharpType == "long")
$end $end
$if(column.IsPK || column.IsIncrement) $if(column.IsPK || column.IsIncrement)
$if(column.IsPK && column.IsIncrement == false) $if(column.IsPK && column.IsIncrement == false && replaceDto.useSnowflakeId == false)
<u-form-item label="${labelName}" prop="${columnName}"> <u-form-item label="${labelName}" prop="${columnName}">
<u--input type="number" v-model.number="form.${columnName}" placeholder="请输入${labelName}" :disabled="opertype != 1"></u--input> <u--input type="number" v-model.number="form.${columnName}" placeholder="请输入${labelName}" :disabled="opertype != 1"></u--input>
</u-form-item> </u-form-item>
@@ -83,7 +83,6 @@ $end
</template> </template>
<script> <script>
import "@/static/scss/page.scss";
import { import {
get${genTable.BusinessName}, get${genTable.BusinessName},
$if(replaceDto.ShowBtnAdd) $if(replaceDto.ShowBtnAdd)
@@ -92,15 +91,9 @@ $end
$if(replaceDto.ShowBtnEdit) $if(replaceDto.ShowBtnEdit)
update${genTable.BusinessName}, update${genTable.BusinessName},
$end $end
} } from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
export default { export default {
$if(replaceDto.UploadFile == 1)
components: {
UploadImage
},
$end
dicts: [ dicts: [
$foreach(item in genTable.Columns) $foreach(item in genTable.Columns)
$if((item.HtmlType == "radio" || item.HtmlType.Contains("select") || item.HtmlType == "checkbox") && item.DictType != "") $if((item.HtmlType == "radio" || item.HtmlType.Contains("select") || item.HtmlType == "checkbox") && item.DictType != "")
@@ -110,7 +103,15 @@ $end
], ],
data() { data() {
return { return {
form: {}, form: {
$foreach(item in genTable.Columns)
$if(item.HtmlType == "checkbox")
${item.CsharpFieldFl}Checked: [],
$else
$item.CsharpFieldFl: undefined,
$end
$end
},
rules: { rules: {
$foreach(column in genTable.Columns) $foreach(column in genTable.Columns)
$if(column.IsRequired && column.IsIncrement == false) $if(column.IsRequired && column.IsIncrement == false)
@@ -202,7 +203,8 @@ $end
} }
</script> </script>
<style scoped> <style lang="scss" scoped>
@import "@/static/scss/page.scss";
.btn-wrap { .btn-wrap {
margin: 150rpx auto 0 auto; margin: 150rpx auto 0 auto;
width: 80% width: 80%
@@ -134,14 +134,12 @@ $end
import { import {
checkPermi checkPermi
} from '@/utils/permission.js' } from '@/utils/permission.js'
import "@/static/scss/page.scss";
import { import {
list${genTable.BusinessName}, list${genTable.BusinessName},
$if(replaceDto.ShowBtnDelete) $if(replaceDto.ShowBtnDelete)
del${genTable.BusinessName}, del${genTable.BusinessName},
$end $end
} } from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.ToLower()}.js'
import { import {
getDate getDate
@@ -286,3 +284,7 @@ $end
} }
} }
</script> </script>
<style lang="scss" scoped>
@import "@/static/scss/page.scss";
</style>
@@ -66,7 +66,7 @@ $end
{ {
var response = _${replaceDto.ModelTypeName}Service.GetInfo(${replaceDto.PKName}); var response = _${replaceDto.ModelTypeName}Service.GetInfo(${replaceDto.PKName});
var info = response.Adapt<${replaceDto.ModelTypeName}>(); var info = response.Adapt<${replaceDto.ModelTypeName}Dto>();
return SUCCESS(info); return SUCCESS(info);
} }
@@ -86,8 +86,8 @@ $if(replaceDto.ShowBtnAdd)
return SUCCESS(response); return SUCCESS(response);
} }
$end
$end
$if(replaceDto.ShowBtnEdit) $if(replaceDto.ShowBtnEdit)
/// <summary> /// <summary>
/// 更新${genTable.FunctionName} /// 更新${genTable.FunctionName}
@@ -103,27 +103,24 @@ $if(replaceDto.ShowBtnEdit)
return ToResponse(response); return ToResponse(response);
} }
$end
$end
$if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel) $if(replaceDto.ShowBtnDelete || replaceDto.ShowBtnMultiDel)
/// <summary> /// <summary>
/// 删除${genTable.FunctionName} /// 删除${genTable.FunctionName}
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
[HttpDelete("{ids}")] [HttpDelete("delete/{ids}")]
[ActionPermissionFilter(Permission = "${replaceDto.PermissionPrefix}:delete")] [ActionPermissionFilter(Permission = "${replaceDto.PermissionPrefix}:delete")]
[Log(Title = "${genTable.FunctionName}", BusinessType = BusinessType.DELETE)] [Log(Title = "${genTable.FunctionName}", BusinessType = BusinessType.DELETE)]
public IActionResult Delete${replaceDto.ModelTypeName}(string ids) public IActionResult Delete${replaceDto.ModelTypeName}([FromRoute]string ids)
{ {
int[] idsArr = Tools.SpitIntArrary(ids); var idArr = Tools.SplitAndConvert<${replaceDto.PKType}>(ids);
if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
var response = _${replaceDto.ModelTypeName}Service.Delete(idsArr); return ToResponse(_${replaceDto.ModelTypeName}Service.Delete(idArr$if(replaceDto.enableLog), "删除${genTable.FunctionName}"$end));
return ToResponse(response);
} }
$end
$end
$if(replaceDto.ShowBtnExport) $if(replaceDto.ShowBtnExport)
/// <summary> /// <summary>
/// 导出${genTable.FunctionName} /// 导出${genTable.FunctionName}
@@ -136,7 +133,7 @@ $if(replaceDto.ShowBtnExport)
{ {
parm.PageNum = 1; parm.PageNum = 1;
parm.PageSize = 100000; parm.PageSize = 100000;
var list = _${replaceDto.ModelTypeName}Service.GetList(parm).Result; var list = _${replaceDto.ModelTypeName}Service.ExportList(parm).Result;
if (list == null || list.Count <= 0) if (list == null || list.Count <= 0)
{ {
return ToResponse(ResultCode.FAIL, "没有要导出的数据"); return ToResponse(ResultCode.FAIL, "没有要导出的数据");
@@ -144,8 +141,8 @@ $if(replaceDto.ShowBtnExport)
var result = ExportExcelMini(list, "${genTable.FunctionName}", "${genTable.FunctionName}"); var result = ExportExcelMini(list, "${genTable.FunctionName}", "${genTable.FunctionName}");
return ExportExcel(result.Item2, result.Item1); return ExportExcel(result.Item2, result.Item1);
} }
$end
$end
$if(replaceDto.ShowBtnTruncate) $if(replaceDto.ShowBtnTruncate)
/// <summary> /// <summary>
/// 清空${genTable.FunctionName} /// 清空${genTable.FunctionName}
@@ -162,8 +159,8 @@ $if(replaceDto.ShowBtnTruncate)
} }
return SUCCESS(_${replaceDto.ModelTypeName}Service.Truncate${replaceDto.ModelTypeName}()); return SUCCESS(_${replaceDto.ModelTypeName}Service.Truncate${replaceDto.ModelTypeName}());
} }
$end
$end
$if(replaceDto.ShowBtnImport) $if(replaceDto.ShowBtnImport)
/// <summary> /// <summary>
/// 导入 /// 导入
@@ -196,8 +193,8 @@ $if(replaceDto.ShowBtnImport)
var result = DownloadImportTemplate(new List<${replaceDto.ModelTypeName}Dto>() { }, "${replaceDto.ModelTypeName}"); var result = DownloadImportTemplate(new List<${replaceDto.ModelTypeName}Dto>() { }, "${replaceDto.ModelTypeName}");
return ExportExcel(result.Item2, result.Item1); return ExportExcel(result.Item2, result.Item1);
} }
$end
$end
$if(showCustomInput) $if(showCustomInput)
/// <summary> /// <summary>
/// 保存排序 /// 保存排序
@@ -1,7 +1,3 @@
using System.ComponentModel.DataAnnotations;
$if(replaceDto.ShowBtnExport)
using MiniExcelLibs.Attributes;
$end
$if(null != genTable.SubTableName && "" != genTable.SubTableName) $if(null != genTable.SubTableName && "" != genTable.SubTableName)
using ${subTableOptions.ModelsNamespace}.${subTableOptions.SubNamespace}; using ${subTableOptions.ModelsNamespace}.${subTableOptions.SubNamespace};
$end $end
@@ -33,18 +29,24 @@ $end
public class ${replaceDto.ModelTypeName}Dto public class ${replaceDto.ModelTypeName}Dto
{ {
$foreach(item in genTable.Columns) $foreach(item in genTable.Columns)
$set(labelName = "")
$if(item.ColumnComment != "")
$set(labelName = item.ColumnComment)
$else
$set(labelName = item.CsharpField)
$end
$if(item.IsRequired) $if(item.IsRequired)
[Required(ErrorMessage = "${item.ColumnComment}不能为空")] [Required(ErrorMessage = "${item.ColumnComment}不能为空")]
$end $end
$if(replaceDto.ShowBtnExport) $if(replaceDto.ShowBtnExport)
$if(item.IsExport) $if(item.IsExport)
[ExcelColumn(Name = "$if(item.ColumnComment == "")${item.CsharpField}${else}${item.ColumnComment}${end}"$if(item.CsharpType == "DateTime"), Format = "yyyy-MM-dd HH:mm:ss"$end)] [ExcelColumn(Name = "$labelName"$if(item.CsharpType == "DateTime"), Format = "yyyy-MM-dd HH:mm:ss", Width = 20$end)]
[ExcelColumnName("$if(item.ColumnComment == "")${item.CsharpField}${else}${item.ColumnComment}${end}")] [ExcelColumnName("$labelName")]
$else $else
[ExcelIgnore] [ExcelIgnore]
$end $end
$end $end
$if(item.CsharpType == "long") $if(item.CsharpType == "long" && replaceDto.useSnowflakeId == true && item.IsPk)
[JsonConverter(typeof(ValueToStringConverter))] [JsonConverter(typeof(ValueToStringConverter))]
$end $end
public $item.CsharpType$item.RequiredStr $item.CsharpField { get; set; } public $item.CsharpType$item.RequiredStr $item.CsharpField { get; set; }
@@ -63,6 +65,12 @@ $if(replaceDto.ShowBtnExport)
[ExcelIgnore] [ExcelIgnore]
$end $end
public List<${genTable.SubTable.ClassName}Dto> ${genTable.SubTable.ClassName}Nav { get; set; } public List<${genTable.SubTable.ClassName}Dto> ${genTable.SubTable.ClassName}Nav { get; set; }
$end
$foreach(column in dicts)
$if(column.IsExport)
[ExcelColumn(Name = "$if(column.ColumnComment == "")${column.CsharpField}${else}${column.ColumnComment}${end}")]
public string ${column.CsharpField}Label { get; set; }
$end
$end $end
} }
} }
@@ -1,8 +1,6 @@
using System; using ${options.BaseNamespace}Model;
using ${options.BaseNamespace}Model;
using ${options.DtosNamespace}; using ${options.DtosNamespace};
using ${options.ModelsNamespace}.${options.SubNamespace}; using ${options.ModelsNamespace}.${options.SubNamespace};
using System.Collections.Generic;
namespace ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNamespace}Service namespace ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNamespace}Service
{ {
@@ -18,6 +16,7 @@ namespace ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNam
$if(genTable.TplCategory == "tree") $if(genTable.TplCategory == "tree")
List<${replaceDto.ModelTypeName}> GetTreeList(${replaceDto.ModelTypeName}QueryDto parm); List<${replaceDto.ModelTypeName}> GetTreeList(${replaceDto.ModelTypeName}QueryDto parm);
$end $end
${replaceDto.ModelTypeName} Add${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm); ${replaceDto.ModelTypeName} Add${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm);
int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm); int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} parm);
@@ -28,5 +27,9 @@ $end
$if(replaceDto.ShowBtnImport) $if(replaceDto.ShowBtnImport)
(string, object, object) Import${replaceDto.ModelTypeName}(List<${replaceDto.ModelTypeName}> list); (string, object, object) Import${replaceDto.ModelTypeName}(List<${replaceDto.ModelTypeName}> list);
$end $end
$if(replaceDto.ShowBtnExport)
PagedInfo<${replaceDto.ModelTypeName}Dto> ExportList(${replaceDto.ModelTypeName}QueryDto parm);
$end
} }
} }
@@ -1,6 +1,4 @@
using System; using Infrastructure.Attribute;
using SqlSugar;
using Infrastructure.Attribute;
using Infrastructure.Extensions; using Infrastructure.Extensions;
using ${options.BaseNamespace}Model; using ${options.BaseNamespace}Model;
using ${options.DtosNamespace}; using ${options.DtosNamespace};
@@ -27,28 +25,8 @@ namespace ${options.ServicesNamespace}.${options.SubNamespace}
/// <returns></returns> /// <returns></returns>
public PagedInfo<${replaceDto.ModelTypeName}Dto> GetList(${replaceDto.ModelTypeName}QueryDto parm) public PagedInfo<${replaceDto.ModelTypeName}Dto> GetList(${replaceDto.ModelTypeName}QueryDto parm)
{ {
var predicate = Expressionable.Create<${replaceDto.ModelTypeName}>(); var predicate = QueryExp(parm);
$foreach(column in genTable.Columns)
$if(column.IsQuery)
$if(column.HtmlType == "selectMulti")
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => parm.${column.CsharpField}.Contains(it.${column.CsharpField}));
$elseif(column.CsharpType == "string")
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.${column.CsharpField}), ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
$elseif(column.CsharpType == "DateTime")
$if(column.HtmlType == "month")
DateTime monthEnd = Convert.ToDateTime(parm.${column.CsharpField}).AddMonths(1);
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.${column.CsharpField} && it.${column.CsharpField} < monthEnd);
$else
predicate = predicate.AndIF(parm.Begin${column.CsharpField} == null, it => it.${column.CsharpField} >= DateTime.Now.ToShortDateString().ParseToDateTime());
predicate = predicate.AndIF(parm.Begin${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.Begin${column.CsharpField});
predicate = predicate.AndIF(parm.End${column.CsharpField} != null, it => it.${column.CsharpField} <= parm.End${column.CsharpField});
$end
$elseif(column.CsharpType == "int" || column.CsharpType == "long")
predicate = predicate.AndIF(parm.${column.CsharpField} != null, ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
$end
$end
$end
var response = Queryable() var response = Queryable()
$if(null != genTable.SubTableName && "" != genTable.SubTableName) $if(null != genTable.SubTableName && "" != genTable.SubTableName)
//.Includes(x => x.${genTable.SubTable.ClassName}Nav) //填充子对象 //.Includes(x => x.${genTable.SubTable.ClassName}Nav) //填充子对象
@@ -117,7 +95,12 @@ $end
$if(null != genTable.SubTableName && "" != genTable.SubTableName) $if(null != genTable.SubTableName && "" != genTable.SubTableName)
return Context.InsertNav(model).Include(s1 => s1.${genTable.SubTable.ClassName}Nav).ExecuteReturnEntity(); return Context.InsertNav(model).Include(s1 => s1.${genTable.SubTable.ClassName}Nav).ExecuteReturnEntity();
$else $else
return Context.Insertable(model).ExecuteReturnEntity(); $if(replaceDto.useSnowflakeId)
Insertable(model).ExecuteReturnSnowflakeId();
return model;
$else
return Insertable(model).ExecuteReturnEntity();
$end
$end $end
} }
@@ -128,19 +111,10 @@ $end
/// <returns></returns> /// <returns></returns>
public int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} model) public int Update${replaceDto.ModelTypeName}(${replaceDto.ModelTypeName} model)
{ {
//var response = Update(w => w.${replaceDto.PKName} == model.${replaceDto.PKName}, it => new ${replaceDto.ModelTypeName}()
//{
$foreach(item in genTable.Columns)
$if((item.IsEdit))
// $item.CsharpField = model.$item.CsharpField,
$end
${end}
//});
//return response;
$if(null != genTable.SubTableName && "" != genTable.SubTableName) $if(null != genTable.SubTableName && "" != genTable.SubTableName)
return Context.UpdateNav(model).Include(z1 => z1.${genTable.SubTable.ClassName}Nav).ExecuteCommand() ? 1 : 0; return Context.UpdateNav(model).Include(z1 => z1.${genTable.SubTable.ClassName}Nav).ExecuteCommand() ? 1 : 0;
$else $else
return Update(model, true); return Update(model, true$if(replaceDto.enableLog), "修改${genTable.FunctionName}"$end);
$end $end
} }
$if(replaceDto.ShowBtnTruncate) $if(replaceDto.ShowBtnTruncate)
@@ -194,5 +168,63 @@ $end
return (msg, x.ErrorList, x.IgnoreList); return (msg, x.ErrorList, x.IgnoreList);
} }
$end $end
$if(replaceDto.ShowBtnExport)
/// <summary>
/// 导出${genTable.FunctionName}
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
public PagedInfo<${replaceDto.ModelTypeName}Dto> ExportList(${replaceDto.ModelTypeName}QueryDto parm)
{
var predicate = QueryExp(parm);
var response = Queryable()
.Where(predicate.ToExpression())
.Select((it) => new ${replaceDto.ModelTypeName}Dto()
{
$foreach(column in dicts)
$if(column.DictType != "")
${column.CsharpField}Label = it.${column.CsharpField}.GetConfigValue<Model.System.SysDictData>("${column.DictType}"),
$end
$end
}, true)
.ToPage(parm);
return response;
}
$end
/// <summary>
/// 查询导出表达式
/// </summary>
/// <param name="parm"></param>
/// <returns></returns>
private static Expressionable<${replaceDto.ModelTypeName}> QueryExp(${replaceDto.ModelTypeName}QueryDto parm)
{
var predicate = Expressionable.Create<${replaceDto.ModelTypeName}>();
$foreach(column in genTable.Columns)
$if(column.IsQuery)
$if(column.HtmlType == "selectMulti")
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => parm.${column.CsharpField}.Contains(it.${column.CsharpField}));
$elseif(column.CsharpType == "string")
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.${column.CsharpField}), ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
$elseif(column.CsharpType == "DateTime")
$if(column.HtmlType == "month")
DateTime monthEnd = Convert.ToDateTime(parm.${column.CsharpField}).AddMonths(1);
predicate = predicate.AndIF(parm.${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.${column.CsharpField} && it.${column.CsharpField} < monthEnd);
$else
predicate = predicate.AndIF(parm.Begin${column.CsharpField} == null, it => it.${column.CsharpField} >= DateTime.Now.ToShortDateString().ParseToDateTime());
predicate = predicate.AndIF(parm.Begin${column.CsharpField} != null, it => it.${column.CsharpField} >= parm.Begin${column.CsharpField});
predicate = predicate.AndIF(parm.End${column.CsharpField} != null, it => it.${column.CsharpField} <= parm.End${column.CsharpField});
$end
$elseif(column.CsharpType == "int" || column.CsharpType == "long")
predicate = predicate.AndIF(parm.${column.CsharpField} != null, ${codeTool.QueryExp(column.CsharpField, column.QueryType)};
$end
$end
$end
return predicate;
}
} }
} }
@@ -230,7 +230,7 @@ $end
$* 一对一/一对多列表显示详情 *$ $* 一对一/一对多列表显示详情 *$
$if(sub) $if(sub)
<el-drawer v-model="drawer" :with-header="false" direction="btt"> <el-drawer v-model="drawer" size="50%" direction="rtl">
<el-table :data="$tool.FirstLowerCase(genTable.SubTable.ClassName)List" header-row-class-name="text-navy"> <el-table :data="$tool.FirstLowerCase(genTable.SubTable.ClassName)List" header-row-class-name="text-navy">
<el-table-column label="序号" type="index" width="80" /> <el-table-column label="序号" type="index" width="80" />
$foreach(column in genSubTable.Columns) $foreach(column in genSubTable.Columns)
@@ -267,7 +267,7 @@ $if(column.CsharpType == "int" || column.CsharpType == "long")
$end $end
$if(column.IsPK || column.IsIncrement) $if(column.IsPK || column.IsIncrement)
$if(column.IsPK && column.IsIncrement == false) $if(column.IsPK && column.IsIncrement == false && replaceDto.useSnowflakeId == false)
<el-col :lg="${options.ColNum}"> <el-col :lg="${options.ColNum}">
<el-form-item label="${labelName}" prop="${columnName}"> <el-form-item label="${labelName}" prop="${columnName}">
<el-input v-model${number}="form.${columnName}" placeholder="请输入${labelName}" :disabled="opertype != 1"/> <el-input v-model${number}="form.${columnName}" placeholder="请输入${labelName}" :disabled="opertype != 1"/>
@@ -392,7 +392,7 @@ $if(sub)
</el-col> </el-col>
</el-row> </el-row>
<el-table :data="${tool.FirstLowerCase(genTable.SubTable.ClassName)}List" :row-class-name="row${genTable.SubTable.ClassName}Index" @selection-change="handle${genTable.SubTable.ClassName}SelectionChange" ref="${genTable.SubTable.ClassName}Ref"> <el-table :data="${tool.FirstLowerCase(genTable.SubTable.ClassName)}List" :row-class-name="row${genTable.SubTable.ClassName}Index" @selection-change="handle${genTable.SubTable.ClassName}SelectionChange" ref="${genTable.SubTable.ClassName}Ref">
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="40" align="center" />
<el-table-column label="序号" align="center" prop="index" width="50"/> <el-table-column label="序号" align="center" prop="index" width="50"/>
$foreach(column in genTable.SubTable.Columns) $foreach(column in genTable.SubTable.Columns)
$set(labelName = column.ColumnComment) $set(labelName = column.ColumnComment)
@@ -435,6 +435,12 @@ $elseif(column.HtmlType == "switch")
<el-switch v-model="scope.row.${columnName}" ${switchType} /> <el-switch v-model="scope.row.${columnName}" ${switchType} />
</template> </template>
</el-table-column> </el-table-column>
$elseif(column.HtmlType == "imageUpload")
<el-table-column label="${labelName}" prop="${columnName}">
<template #default="scope">
<UploadImage v-model="form.${columnName}" :isShowTip="false" :style="{ 'width': '50px' }" :data="{ uploadType: 1 }" />
</template>
</el-table-column>
$else $else
<el-table-column label="${labelName}" align="center" prop="${columnName}"> <el-table-column label="${labelName}" align="center" prop="${columnName}">
<template #default="scope"> <template #default="scope">
@@ -635,9 +641,11 @@ const state = reactive({
form: {}, form: {},
rules: { rules: {
$foreach(column in genTable.Columns) $foreach(column in genTable.Columns)
$if(column.IsRequired && column.IsIncrement == false) $if(column.IsRequired && column.IsPk && replaceDto.useSnowflakeId)
${column.CsharpFieldFl}: [{ required: true, message: "${column.ColumnComment}不能为空", trigger: $if(column.htmlType == "select")"change"$else"blur"$end }],
$elseif(column.IsRequired && column.IsIncrement == false)
${column.CsharpFieldFl}: [{ required: true, message: "${column.ColumnComment}不能为空", trigger: $if(column.htmlType == "select")"change"$else"blur"$end ${column.CsharpFieldFl}: [{ required: true, message: "${column.ColumnComment}不能为空", trigger: $if(column.htmlType == "select")"change"$else"blur"$end
$if(column.CsharpType == "int" || column.CsharpType == "long"), type: "number"$end }], $if(column.CsharpType == "int" || column.CsharpType == "long"), type: "number" $end }],
$end $end
$end $end
}, },
@@ -675,6 +683,37 @@ $if(sub)
$end $end
proxy.resetForm("formRef") proxy.resetForm("formRef")
} }
$if(replaceDto.ShowBtnView)
/**
* 查看
* @param {*} row
*/
function handlePreview(row) {
reset()
const id = row.${replaceDto.FistLowerPk}
get${genTable.BusinessName}(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '查看'
opertype.value = 3
form.value = {
...data,
$foreach(item in genTable.Columns)
$if(item.HtmlType == "checkbox" || item.HtmlType == "selectMulti")
${item.CsharpFieldFl}Checked: data.${item.CsharpFieldFl} ? data.${item.CsharpFieldFl}.split(',') : [],
$end
$end
}
$if(sub)
${tool.FirstLowerCase(genTable.SubTable.ClassName)}List.value = res.data.${tool.FirstLowerCase(genTable.SubTable.ClassName)}Nav
$end
}
})
}
$end
$if(replaceDto.ShowBtnAdd) $if(replaceDto.ShowBtnAdd)
// 添加按钮操作 // 添加按钮操作
function handleAdd() { function handleAdd() {
@@ -782,20 +821,6 @@ function handleClear() {
} }
$end $end
$if(replaceDto.ShowBtnView)
/**
* 查看
* @param {*} row
*/
function handlePreview(row) {
reset()
open.value = true
title.value = '查看'
opertype.value = 3
form.value = { ...row }
}
$end
$if(replaceDto.ShowBtnImport) $if(replaceDto.ShowBtnImport)
// 导入数据成功处理 // 导入数据成功处理
const handleFileSuccess = (response) => { const handleFileSuccess = (response) => {
@@ -841,6 +866,7 @@ function row${genTable.SubTable.ClassName}Index({ row, rowIndex }) {
/** ${genTable.SubTable.FunctionName}添加按钮操作 */ /** ${genTable.SubTable.FunctionName}添加按钮操作 */
function handleAdd${genTable.SubTable.ClassName}() { function handleAdd${genTable.SubTable.ClassName}() {
let obj = {}; let obj = {};
//下面的代码自己设置默认值
$foreach(column in genTable.SubTable.Columns) $foreach(column in genTable.SubTable.Columns)
$if(column.IsPK || column.CsharpField == genTable.SubTableFkName) $if(column.IsPK || column.CsharpField == genTable.SubTableFkName)
$elseif(column.IsList == true && "" != column.CsharpField) $elseif(column.IsList == true && "" != column.CsharpField)
Binary file not shown.
+1 -6
View File
@@ -1,9 +1,4 @@
using System; namespace ZR.CodeGenerator
using System.Linq;
using System.Text;
using ZR.Model.System.Generate;
namespace ZR.CodeGenerator
{ {
/// <summary> /// <summary>
/// 代码生成模板 /// 代码生成模板
+79 -71
View File
@@ -27,8 +27,8 @@ namespace ZR.CodeGenerator
/// <param name="dto"></param> /// <param name="dto"></param>
public static void Generate(GenerateDto dto) public static void Generate(GenerateDto dto)
{ {
var genOptions = AppSettings.Get<Gen>("gen"); var genOptions = AppSettings.Get<CodeGen>("codeGen");
dto.VueParentPath = dto.VueVersion == 3 ? "ZRAdmin-vue" : "ZR.Vue"; dto.VueParentPath = "Frontend";
if (!genOptions.VuePath.IsEmpty()) if (!genOptions.VuePath.IsEmpty())
{ {
dto.VueParentPath = genOptions.VuePath; dto.VueParentPath = genOptions.VuePath;
@@ -38,6 +38,10 @@ namespace ZR.CodeGenerator
{ {
dto.SubTableOptions = GenerateOption(dto.GenTable.SubTable); dto.SubTableOptions = GenerateOption(dto.GenTable.SubTable);
} }
if (dto.GenTable.SubTableName.IsNotEmpty() && dto.GenTable.SubTable == null)
{
throw new CustomException($"{dto.GenTable.SubTableName}子表不存在");
}
ReplaceDto replaceDto = new() ReplaceDto replaceDto = new()
{ {
@@ -53,7 +57,9 @@ namespace ZR.CodeGenerator
ShowBtnMultiDel = dto.GenTable.Options.CheckedBtn.Any(f => f == 7), ShowBtnMultiDel = dto.GenTable.Options.CheckedBtn.Any(f => f == 7),
ShowBtnImport = dto.GenTable.Options.CheckedBtn.Any(f => f == 8), ShowBtnImport = dto.GenTable.Options.CheckedBtn.Any(f => f == 8),
ViewFileName = dto.GenTable.BusinessName.FirstUpperCase(), ViewFileName = dto.GenTable.BusinessName.FirstUpperCase(),
OperBtnStyle = dto.GenTable.Options.OperBtnStyle OperBtnStyle = dto.GenTable.Options.OperBtnStyle,
UseSnowflakeId = dto.GenTable.Options.UseSnowflakeId,
EnableLog = dto.GenTable.Options.EnableLog
}; };
var columns = dto.GenTable.Columns; var columns = dto.GenTable.Columns;
@@ -69,14 +75,18 @@ namespace ZR.CodeGenerator
GenerateModels(replaceDto, dto); GenerateModels(replaceDto, dto);
GenerateService(replaceDto, dto); GenerateService(replaceDto, dto);
GenerateControllers(replaceDto, dto); GenerateControllers(replaceDto, dto);
if (dto.VueVersion == 3) if (dto.GenTable.Options.FrontTpl == 2)
{ {
GenerateVue3Views(replaceDto, dto); GenerateVue3Views(replaceDto, dto);
} }
else else if (dto.GenTable.Options.FrontTpl == 1)
{ {
GenerateVueViews(replaceDto, dto); GenerateVueViews(replaceDto, dto);
} }
else
{
GenerateAntDesignViews(replaceDto, dto);
}
if (dto.GenTable.Options.GenerateRepo == 1) if (dto.GenTable.Options.GenerateRepo == 1)
{ {
GenerateRepository(replaceDto, dto); GenerateRepository(replaceDto, dto);
@@ -118,8 +128,9 @@ namespace ZR.CodeGenerator
/// <param name="replaceDto">替换实体</param> /// <param name="replaceDto">替换实体</param>
private static void GenerateModels(ReplaceDto replaceDto, GenerateDto generateDto) private static void GenerateModels(ReplaceDto replaceDto, GenerateDto generateDto)
{ {
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplModel.txt"); var path = Path.Combine(CodeTemplateDir, "csharp");
var tplDto = JnHelper.ReadTemplate(CodeTemplateDir, "TplDto.txt"); var tpl = JnHelper.ReadTemplate(path, "TplModel.txt");
var tplDto = JnHelper.ReadTemplate(path, "TplDto.txt");
string fullPath = Path.Combine(generateDto.GenOptions.ModelsNamespace, "Models", generateDto.GenOptions.SubNamespace, replaceDto.ModelTypeName + ".cs"); string fullPath = Path.Combine(generateDto.GenOptions.ModelsNamespace, "Models", generateDto.GenOptions.SubNamespace, replaceDto.ModelTypeName + ".cs");
string fullPathDto = Path.Combine(generateDto.GenOptions.ModelsNamespace, "Dto", generateDto.GenOptions.SubNamespace, replaceDto.ModelTypeName + "Dto.cs"); string fullPathDto = Path.Combine(generateDto.GenOptions.ModelsNamespace, "Dto", generateDto.GenOptions.SubNamespace, replaceDto.ModelTypeName + "Dto.cs");
@@ -135,7 +146,7 @@ namespace ZR.CodeGenerator
/// <param name="replaceDto">替换实体</param> /// <param name="replaceDto">替换实体</param>
private static void GenerateRepository(ReplaceDto replaceDto, GenerateDto generateDto) private static void GenerateRepository(ReplaceDto replaceDto, GenerateDto generateDto)
{ {
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplRepository.txt"); var tpl = JnHelper.ReadTemplate(Path.Combine(CodeTemplateDir, "csharp"), "TplRepository.txt");
var result = tpl.Render(); var result = tpl.Render();
var fullPath = Path.Combine(generateDto.GenOptions.RepositoriesNamespace, generateDto.GenOptions.SubNamespace, $"{replaceDto.ModelTypeName}Repository.cs"); var fullPath = Path.Combine(generateDto.GenOptions.RepositoriesNamespace, generateDto.GenOptions.SubNamespace, $"{replaceDto.ModelTypeName}Repository.cs");
@@ -147,8 +158,9 @@ namespace ZR.CodeGenerator
/// </summary> /// </summary>
private static void GenerateService(ReplaceDto replaceDto, GenerateDto generateDto) private static void GenerateService(ReplaceDto replaceDto, GenerateDto generateDto)
{ {
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplService.txt"); var path = Path.Combine(CodeTemplateDir, "csharp");
var tpl2 = JnHelper.ReadTemplate(CodeTemplateDir, "TplIService.txt"); var tpl = JnHelper.ReadTemplate(path, "TplService.txt");
var tpl2 = JnHelper.ReadTemplate(path, "TplIService.txt");
var fullPath = Path.Combine(generateDto.GenOptions.ServicesNamespace, generateDto.GenOptions.SubNamespace, $"{replaceDto.ModelTypeName}Service.cs"); var fullPath = Path.Combine(generateDto.GenOptions.ServicesNamespace, generateDto.GenOptions.SubNamespace, $"{replaceDto.ModelTypeName}Service.cs");
var fullPath2 = Path.Combine(generateDto.GenOptions.IServicsNamespace, generateDto.GenOptions.SubNamespace, $"I{generateDto.GenOptions.SubNamespace}Service", $"I{replaceDto.ModelTypeName}Service.cs"); var fullPath2 = Path.Combine(generateDto.GenOptions.IServicsNamespace, generateDto.GenOptions.SubNamespace, $"I{generateDto.GenOptions.SubNamespace}Service", $"I{replaceDto.ModelTypeName}Service.cs");
@@ -162,7 +174,7 @@ namespace ZR.CodeGenerator
/// </summary> /// </summary>
private static void GenerateControllers(ReplaceDto replaceDto, GenerateDto generateDto) private static void GenerateControllers(ReplaceDto replaceDto, GenerateDto generateDto)
{ {
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, "TplControllers.txt"); var tpl = JnHelper.ReadTemplate(Path.Combine(CodeTemplateDir, "csharp"), "TplControllers.txt");
tpl.Set("QueryCondition", replaceDto.QueryCondition); tpl.Set("QueryCondition", replaceDto.QueryCondition);
var result = tpl.Render(); var result = tpl.Render();
@@ -180,9 +192,11 @@ namespace ZR.CodeGenerator
"select" => "TplVueSelect.txt", "select" => "TplVueSelect.txt",
_ => "TplVue.txt", _ => "TplVue.txt",
}; };
replaceDto.VueViewListHtml = GenerateVueTableList(); var path = Path.Combine(CodeTemplateDir, "vue2");
replaceDto.VueQueryFormHtml = GenerateVueQueryForm(); fileName = Path.Combine("vue2", fileName);
replaceDto.VueViewFormHtml = GenerateCurdForm(); replaceDto.VueViewListHtml = JnHelper.ReadTemplate(path, "TableList.txt").Render();
replaceDto.VueQueryFormHtml = JnHelper.ReadTemplate(path, "QueryForm.txt").Render();
replaceDto.VueViewFormHtml = JnHelper.ReadTemplate(path, "CurdForm.txt").Render();
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName); var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName);
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue"); var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue");
@@ -213,6 +227,29 @@ namespace ZR.CodeGenerator
generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result)); generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result));
} }
/// <summary>
/// AntDesign
/// </summary>
/// <param name="generateDto"></param>
private static void GenerateAntDesignViews(ReplaceDto replaceDto, GenerateDto generateDto)
{
string fileName = generateDto.GenTable.TplCategory switch
{
"tree" => "TreeVue.txt",
_ => "Vue2.txt",
};
fileName = Path.Combine("antDesign", fileName);
var tpl = JnHelper.ReadTemplate(CodeTemplateDir, fileName);
tpl.Set("treeCode", generateDto.GenTable?.Options?.TreeCode?.FirstLowerCase());
tpl.Set("treeName", generateDto.GenTable?.Options?.TreeName?.FirstLowerCase());
tpl.Set("treeParentCode", generateDto.GenTable?.Options?.TreeParentCode?.FirstLowerCase());
tpl.Set("options", generateDto.GenTable?.Options);
var result = tpl.Render();
var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{replaceDto.ViewFileName}.vue");
generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result));
}
/// <summary> /// <summary>
/// 生成vue页面api /// 生成vue页面api
/// </summary> /// </summary>
@@ -255,35 +292,9 @@ namespace ZR.CodeGenerator
var result = tpl.Render(); var result = tpl.Render();
string fullPath = Path.Combine(generateDto.GenCodePath, "sql", generateDto.GenTable.BusinessName + ".sql"); string fullPath = Path.Combine(generateDto.GenCodePath, "sql", generateDto.GenTable.BusinessName + ".sql");
generateDto.GenCodes.Add(new GenCode(8, "sql", fullPath, result)); generateDto.GenCodes.Add(new GenCode(8, "sql菜单", fullPath, result));
} }
/// <summary>
/// 生成vue页面查询form
/// </summary>
/// <returns></returns>
public static string GenerateVueQueryForm()
{
return JnHelper.ReadTemplate(CodeTemplateDir, "QueryForm.txt").Render();
}
/// <summary>
/// 生成vue页面table
/// </summary>
/// <returns></returns>
public static string GenerateVueTableList()
{
return JnHelper.ReadTemplate(CodeTemplateDir, "TableList.txt").Render();
}
/// <summary>
/// 生成vue表单
/// </summary>
/// <returns></returns>
public static string GenerateCurdForm()
{
return JnHelper.ReadTemplate(CodeTemplateDir, "CurdForm.txt").Render();
}
#endregion #endregion
#region app页面 #region app页面
@@ -340,11 +351,8 @@ namespace ZR.CodeGenerator
/// </summary> /// </summary>
/// <param name="tableName"></param> /// <param name="tableName"></param>
/// <returns></returns> /// <returns></returns>
public static string GetClassName(string tableName) public static string GetClassName(string tableName, bool autoRemovePre, string tablePrefix)
{ {
bool autoRemovePre = AppSettings.GetAppConfig(GenConstants.Gen_autoPre, false);
string tablePrefix = AppSettings.GetAppConfig<string>(GenConstants.Gen_tablePrefix);
if (!string.IsNullOrEmpty(tablePrefix) && autoRemovePre) if (!string.IsNullOrEmpty(tablePrefix) && autoRemovePre)
{ {
string[] prefixList = tablePrefix.Split(",", StringSplitOptions.RemoveEmptyEntries); string[] prefixList = tablePrefix.Split(",", StringSplitOptions.RemoveEmptyEntries);
@@ -421,32 +429,32 @@ namespace ZR.CodeGenerator
/// <summary> /// <summary>
/// 初始化表信息 /// 初始化表信息
/// </summary> /// </summary>
/// <param name="dbName"></param> /// <param name="dto"></param>
/// <param name="userName"></param>
/// <param name="tableName"></param>
/// <param name="desc"></param>
/// <returns></returns> /// <returns></returns>
public static GenTable InitTable(string dbName, string userName, string tableName, string desc) public static GenTable InitTable(InitTableDto dto)
{ {
var className = GetClassName(dto.TableName, dto.CodeGen.AutoPre, dto.CodeGen.TablePrefix);
GenTable genTable = new() GenTable genTable = new()
{ {
DbName = dbName, DbName = dto.DbName,
BaseNameSpace = "ZR.",//导入默认命名空间前缀 BaseNameSpace = "ZR.",//导入默认命名空间前缀
ModuleName = "business",//导入默认模块名 ModuleName = dto.CodeGen.ModuleName,//导入默认模块名
ClassName = GetClassName(tableName), ClassName = className,
BusinessName = GetClassName(tableName), BusinessName = className,
FunctionAuthor = AppSettings.GetConfig(GenConstants.Gen_author), FunctionAuthor = dto.CodeGen.Author,
TableName = tableName, TableName = dto.TableName,
TableComment = desc, TableComment = dto.Desc,
FunctionName = desc, FunctionName = dto.Desc,
Create_by = userName, Create_by = dto.UserName,
Options = new Options() Options = new CodeOptions()
{ {
SortType = "asc", SortType = "asc",
CheckedBtn = new int[] { 1, 2, 3 } CheckedBtn = new int[] { 1, 2, 3 },
PermissionPrefix = className.ToLower(),
FrontTpl = dto.FrontTpl
} }
}; };
genTable.Options.PermissionPrefix = $"{genTable.ModuleName.ToLower()}:{genTable.ClassName.ToLower()}";//权限
return genTable; return genTable;
} }
@@ -457,16 +465,16 @@ namespace ZR.CodeGenerator
/// <param name="genTable"></param> /// <param name="genTable"></param>
/// <param name="dbColumnInfos"></param> /// <param name="dbColumnInfos"></param>
/// <param name="seqs"></param> /// <param name="seqs"></param>
public static List<GenTableColumn> InitGenTableColumn(GenTable genTable, List<DbColumnInfo> dbColumnInfos, List<OracleSeq> seqs = null) /// <param name="codeGen"></param>
public static List<GenTableColumn> InitGenTableColumn(GenTable genTable, List<DbColumnInfo> dbColumnInfos, List<OracleSeq> seqs = null, CodeGen codeGen = null)
{ {
OptionsSetting optionsSetting = new(); OptionsSetting optionsSetting = new();
var gen = AppSettings.Get<Gen>("gen"); var dbConfig = AppSettings.Get<DbConfigs>(nameof(GenConstants.CodeGenDbConfig));
var dbConfig = AppSettings.Get<DbConfigs>("CodeGenDbConfig");
optionsSetting.CodeGenDbConfig = dbConfig ?? throw new CustomException("代码生成节点数据配置异常"); ;
optionsSetting.CodeGen = codeGen ?? throw new CustomException("代码生成节点配置异常");
optionsSetting.CodeGenDbConfig = dbConfig;
optionsSetting.Gen = gen ?? throw new CustomException("代码生成节点配置异常");
optionsSetting.Gen.GenDbConfig = dbConfig ?? throw new CustomException("代码生成节点数据配置异常");
List<GenTableColumn> genTableColumns = new(); List<GenTableColumn> genTableColumns = new();
foreach (var column in dbColumnInfos) foreach (var column in dbColumnInfos)
{ {
@@ -486,7 +494,7 @@ namespace ZR.CodeGenerator
private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column, List<OracleSeq> seqs, OptionsSetting optionsSetting) private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column, List<OracleSeq> seqs, OptionsSetting optionsSetting)
{ {
var dataType = column.DataType; var dataType = column.DataType;
if (optionsSetting.Gen.GenDbConfig.DbType == 3) if (optionsSetting.CodeGenDbConfig.DbType == 3)
{ {
dataType = column.OracleDataType; dataType = column.OracleDataType;
var seqName = $"SEQ_{genTable.TableName}_{column.DbColumnName}"; var seqName = $"SEQ_{genTable.TableName}_{column.DbColumnName}";
@@ -501,7 +509,7 @@ namespace ZR.CodeGenerator
ColumnType = dataType, ColumnType = dataType,
TableId = genTable.TableId, TableId = genTable.TableId,
TableName = genTable.TableName, TableName = genTable.TableName,
CsharpType = GetCSharpDatatype(dataType, optionsSetting.Gen.CsharpTypeArr).ToString(), CsharpType = GetCSharpDatatype(dataType, optionsSetting.CodeGen.CsharpTypeArr).ToString(),
CsharpField = column.DbColumnName.ConvertToPascal("_"), CsharpField = column.DbColumnName.ConvertToPascal("_"),
IsRequired = !column.IsNullable, IsRequired = !column.IsNullable,
IsIncrement = column.IsIdentity, IsIncrement = column.IsIdentity,
@@ -604,7 +612,7 @@ namespace ZR.CodeGenerator
options.Data.Set("showCustomInput", showCustomInput); options.Data.Set("showCustomInput", showCustomInput);
options.Data.Set("tool", new CodeGeneratorTool()); options.Data.Set("tool", new CodeGeneratorTool());
options.Data.Set("codeTool", new CodeGenerateTemplate()); options.Data.Set("codeTool", new CodeGenerateTemplate());
options.Data.Set("dicts", dicts); options.Data.Set("dicts", dicts.DistinctBy(x => x.DictType));
options.Data.Set("sub", dto.GenTable.SubTable != null && dto.GenTable.SubTableName.IsNotEmpty()); options.Data.Set("sub", dto.GenTable.SubTable != null && dto.GenTable.SubTableName.IsNotEmpty());
options.EnableCache = true; options.EnableCache = true;
//...其它数据 //...其它数据
+2 -3
View File
@@ -7,9 +7,8 @@ namespace ZR.CodeGenerator
/// </summary> /// </summary>
public class GenConstants public class GenConstants
{ {
public static string Gen_author = "gen:author"; public static string Gen_author = "codeGen:author";
public static string Gen_autoPre = "gen:autoPre"; public static string CodeGenDbConfig;
public static string Gen_tablePrefix = "gen:tablePrefix";
/// <summary> /// <summary>
/// InputDto输入实体是不包含字段 /// InputDto输入实体是不包含字段
@@ -1,4 +1,4 @@
namespace ZR.CodeGenerator namespace ZR.CodeGenerator.Model
{ {
public class CodeGenerateOption public class CodeGenerateOption
{ {
@@ -39,11 +39,6 @@
/// Api控制器命名空间 /// Api控制器命名空间
/// </summary> /// </summary>
public string ApiControllerNamespace { get; set; } public string ApiControllerNamespace { get; set; }
/// <summary>
/// 去掉的表头字符
/// </summary>
public string ReplaceTableNameStr { get; set; }
/// <summary> /// <summary>
/// 要生数据的表,用“,”分割 /// 要生数据的表,用“,”分割
/// </summary> /// </summary>
@@ -0,0 +1,17 @@
using System.Collections.Generic;
namespace ZR.CodeGenerator.Model
{
public class ImportCodeGenTableDto
{
public int FrontTpl { get; set; }
public string DbName { get; set; }
public List<CodeGenTables> Tables { get; set; }
}
public class CodeGenTables
{
public string Name { get; set; }
public string Description { get; set; }
}
}
+14
View File
@@ -0,0 +1,14 @@
using Infrastructure.Model;
namespace ZR.CodeGenerator.Model
{
public class InitTableDto
{
public int FrontTpl { get; set; }
public string DbName { get; set; }
public string UserName { get; set; }
public string TableName { get; set; }
public string Desc { get; set; }
public CodeGen CodeGen { get; set; }
}
}
+6 -1
View File
@@ -11,7 +11,7 @@ namespace ZR.CodeGenerator.Model
/// <summary> /// <summary>
/// 首字母小写主键 /// 首字母小写主键
/// </summary> /// </summary>
public string FistLowerPk{ get; set; } public string FistLowerPk { get; set; }
/// <summary> /// <summary>
/// 主键类型 /// 主键类型
/// </summary> /// </summary>
@@ -74,5 +74,10 @@ namespace ZR.CodeGenerator.Model
/// 操作按钮样式 /// 操作按钮样式
/// </summary> /// </summary>
public int OperBtnStyle { get; set; } public int OperBtnStyle { get; set; }
/// <summary>
/// 是否使用雪花id
/// </summary>
public bool UseSnowflakeId { get; set; }
public bool EnableLog { get; set; }
} }
} }
@@ -18,7 +18,7 @@ namespace ZR.CodeGenerator.Service
{ {
var db = GetSugarDbContext(); var db = GetSugarDbContext();
//Oracle库特殊处理 //Oracle库特殊处理
DbConfigs configs = AppSettings.Get<DbConfigs>(nameof(GlobalConstant.CodeGenDbConfig)); DbConfigs configs = AppSettings.Get<DbConfigs>(nameof(GenConstants.CodeGenDbConfig));
if (configs.DbType == 3) if (configs.DbType == 3)
{ {
return new List<string>() { configs?.DbName }; return new List<string>() { configs?.DbName };
+2 -2
View File
@@ -11,7 +11,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="JinianNet.JNTemplate" Version="2.3.3" /> <PackageReference Include="JinianNet.JNTemplate" Version="2.4.2" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.105" /> <PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.130" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+12
View File
@@ -29,6 +29,18 @@ namespace ZR.Common
int[] infoIdss = Array.ConvertAll(strIds, s => int.Parse(s)); int[] infoIdss = Array.ConvertAll(strIds, s => int.Parse(s));
return infoIdss; return infoIdss;
} }
public static T[] SplitAndConvert<T>(string input, char split = ',')
{
if (string.IsNullOrEmpty(input)) { return Array.Empty<T>(); }
string[] parts = input.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
T[] result = Array.ConvertAll(parts, s => (T)Convert.ChangeType(s, typeof(T)));
//for (int i = 0; i < parts.Length; i++)
//{
// result[i] = (T)Convert.ChangeType(parts[i], typeof(T));
//}
return result;
}
/// <summary> /// <summary>
/// 根据日期获取星期几 /// 根据日期获取星期几
+1 -1
View File
@@ -42,7 +42,7 @@ namespace ZR.Common
} }
if (string.IsNullOrEmpty(CORPID)) if (string.IsNullOrEmpty(CORPID))
{ {
System.Console.WriteLine("请完成企业微信配置"); System.Console.WriteLine("如需微信接收异常消息,请完成企业微信配置");
return (0, "请完成企业微信通知配置"); return (0, "请完成企业微信通知配置");
} }
WxTokenResult tokenResult = GetAccessToken(); WxTokenResult tokenResult = GetAccessToken();
+1 -1
View File
@@ -6,7 +6,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" /> <PackageReference Include="Aliyun.OSS.SDK.NetCore" Version="2.13.0" />
<PackageReference Include="MailKit" Version="4.1.0" /> <PackageReference Include="MailKit" Version="4.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+2
View File
@@ -2,3 +2,5 @@
global using System; global using System;
global using SqlSugar; global using SqlSugar;
global using Newtonsoft.Json; global using Newtonsoft.Json;
global using MiniExcelLibs.Attributes;
global using System.ComponentModel.DataAnnotations;
+2 -2
View File
@@ -7,9 +7,9 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MiniExcel" Version="1.31.2" /> <PackageReference Include="MiniExcel" Version="1.31.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.105" /> <PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.130" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" /> <PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1 -1
View File
@@ -146,8 +146,8 @@ namespace ZR.Repository
} }
catch (Exception ex) catch (Exception ex)
{ {
Console.WriteLine("事务异常" + ex.Message);
client.AsTenant().RollbackTran(); client.AsTenant().RollbackTran();
Console.WriteLine(ex.Message);
throw; throw;
} }
} }
+3 -3
View File
@@ -10,9 +10,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.4.0" />
<PackageReference Include="MySqlConnector" Version="2.2.6" /> <PackageReference Include="MySqlConnector" Version="2.3.1" />
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" /> <PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
<PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.105" /> <PackageReference Include="SqlSugarCoreNoDrive" Version="5.1.4.130" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1
View File
@@ -2,3 +2,4 @@
global using System; global using System;
global using SqlSugar; global using SqlSugar;
global using Newtonsoft.Json; global using Newtonsoft.Json;
global using ZR.ServiceCore;
+1 -1
View File
@@ -4,7 +4,7 @@ using SqlSugar.IOC;
using ZR.Model.System; using ZR.Model.System;
using ZR.Repository; using ZR.Repository;
using ZR.Service.IService; using ZR.Service.IService;
using ZR.Service.System.IService; using ZR.ServiceCore.Services;
namespace ZR.Service namespace ZR.Service
{ {
+1 -1
View File
@@ -1,6 +1,6 @@
using ZR.Repository; using ZR.Repository;
namespace ZR.Service namespace ZR.ServiceCore
{ {
/// <summary> /// <summary>
/// 基础服务定义 /// 基础服务定义
@@ -3,8 +3,7 @@ using Infrastructure.Model;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.System; using ZR.ServiceCore.Services;
using ZR.Service.System.IService;
namespace ZR.ServiceCore.Middleware namespace ZR.ServiceCore.Middleware
{ {
@@ -82,10 +81,11 @@ namespace ZR.ServiceCore.Middleware
if (!HasPermi && !Permission.Equals("common")) if (!HasPermi && !Permission.Equals("common"))
{ {
logger.Info($"用户{info.UserName}没有权限访问{url},当前权限[{Permission}]"); logger.Info($"用户{info.UserName}没有权限访问{url},当前权限[{Permission}]");
JsonResult result = new(new ApiResult((int)ResultCode.FORBIDDEN, $"你当前没有权限[{Permission}]访问,请联系管理员", url)) JsonResult result = new(new ApiResult((int)ResultCode.FORBIDDEN, $"你当前没有权限访问,请联系管理员", url))
{ {
ContentType = "application/json", ContentType = "application/json",
}; };
context.HttpContext.Response.StatusCode = 403;
context.Result = result; context.Result = result;
} }
} }
@@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using NLog; using NLog;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.System.IService; using ZR.ServiceCore.Services;
namespace ZR.ServiceCore.Middleware namespace ZR.ServiceCore.Middleware
{ {
@@ -16,6 +16,7 @@ namespace ZR.Admin.WebApi.Filters
[AttributeUsage(AttributeTargets.All)] [AttributeUsage(AttributeTargets.All)]
public class VerifyAttribute : Attribute, IAuthorizationFilter public class VerifyAttribute : Attribute, IAuthorizationFilter
{ {
private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
/// <summary> /// <summary>
/// 只判断token是否正确,不判断权限 /// 只判断token是否正确,不判断权限
/// 如果需要判断权限的在Action上加上ApiActionPermission属性标识权限类别,ActionPermissionFilter作权限处理 /// 如果需要判断权限的在Action上加上ApiActionPermission属性标识权限类别,ActionPermissionFilter作权限处理
@@ -56,6 +57,7 @@ namespace ZR.Admin.WebApi.Filters
{ {
context.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "X-Refresh-Token"); context.HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", "X-Refresh-Token");
} }
logger.Info($"刷新token,userName={loginUser.UserName},token={newToken}");
context.HttpContext.Response.Headers.Add("X-Refresh-Token", newToken); context.HttpContext.Response.Headers.Add("X-Refresh-Token", newToken);
} }
} }
+1 -1
View File
@@ -1,6 +1,6 @@
using ZR.Repository; using ZR.Repository;
namespace ZR.Service namespace ZR.ServiceCore
{ {
/// <summary> /// <summary>
/// 基础服务定义 /// 基础服务定义
@@ -8,7 +8,7 @@ using NLog;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using ZR.Common; using ZR.Common;
using ZR.Model.System; using ZR.Model.System;
using ZR.Service.System.IService; using ZR.ServiceCore.Services;
using textJson = System.Text.Json; using textJson = System.Text.Json;
namespace ZR.ServiceCore.Middleware namespace ZR.ServiceCore.Middleware
@@ -0,0 +1,31 @@
namespace ZR.ServiceCore.Model.Dto
{
public class ChatMessageDto
{
public ChatUserDto FromUser { get; set; }
public bool Self { get; set; }
[SugarColumn(IsPrimaryKey = true)]
public string ChatId { get; set; }
/// <summary>
/// 0、文本 1、图片 2、文件 3、语音 4、视频
/// </summary>
public int MsgType { get; set; }
public string StoredKey { get; set; }
public long UserId { get; set; }
public long ToUserId { get; set; }
/// <summary>
/// 消息内容,如果type=1/2/3/4,此属性表示文件的URL地址
/// </summary>
public string Message { get; set; }
public long ChatTime { get; set; }
public int Online { get; set; }
}
public class ChatUserDto
{
public string UserName { get; set; }
public string NickName { get; set; }
public string Avatar { get; set; }
}
}
+44
View File
@@ -0,0 +1,44 @@
using System.ComponentModel.DataAnnotations;
namespace ZR.Model.Dto
{
/// <summary>
/// 邮件发送记录查询对象
/// </summary>
public class EmailLogQueryDto : PagerInfo
{
public string FromEmail { get; set; }
public string Subject { get; set; }
public DateTime? BeginAddTime { get; set; }
public DateTime? EndAddTime { get; set; }
}
/// <summary>
/// 邮件发送记录输入输出对象
/// </summary>
public class EmailLogDto
{
//[Required(ErrorMessage = "Id不能为空")]
[JsonConverter(typeof(ValueToStringConverter))]
public long Id { get; set; }
public string FromEmail { get; set; }
public string Subject { get; set; }
public string ToEmails { get; set; }
public string EmailContent { get; set; }
public DateTime? AddTime { get; set; }
/// <summary>
/// 是否已发送
/// </summary>
public int IsSend { get; set; }
/// <summary>
/// 发送结果
/// </summary>
public string SendResult { get; set; }
public long[] IdArr { get; set; }
}
}
+39
View File
@@ -0,0 +1,39 @@
using System.ComponentModel.DataAnnotations;
namespace ZR.Model.Dto
{
/// <summary>
/// 邮件模板查询对象
/// </summary>
public class EmailTplQueryDto : PagerInfo
{
public string Name { get; set; }
}
/// <summary>
/// 邮件模板输入输出对象
/// </summary>
public class EmailTplDto
{
public int? Id { get; set; }
[Required(ErrorMessage = "Name不能为空")]
public string Name { get; set; }
[Required(ErrorMessage = "模板内容不能为空")]
public string Content { get; set; }
public string CreateBy { get; set; }
public DateTime? CreateTime { get; set; }
public string UpdateBy { get; set; }
public DateTime? UpdateTime { get; set; }
public string Remark { get; set; }
}
}
+2 -21
View File
@@ -1,5 +1,4 @@
using System.Collections.Generic; using ZR.Model.System.Generate;
using ZR.Model.System.Generate;
namespace ZR.Model.System.Dto namespace ZR.Model.System.Dto
{ {
@@ -24,28 +23,10 @@ namespace ZR.Model.System.Dto
/// <summary> /// <summary>
/// 额外参数 /// 额外参数
/// </summary> /// </summary>
public Options Params { get; set; } public CodeOptions Params { get; set; }
public List<GenTableColumnDto> Columns { get; set; } public List<GenTableColumnDto> Columns { get; set; }
} }
/// <summary>
/// 额外参数
/// ****注意里面参数统一首字母小写*****
/// </summary>
public class Params
{
public string TreeCode { get; set; }
public string TreeName { get; set; }
public string TreeParentCode { get; set; }
public int? ParentMenuId { get; set; }
public string SortField { get; set; }
public string SortType { get; set; }
/// <summary>
/// 额外参数字符串
/// </summary>
public string CheckedBtn { get; set; }
public string PermissionPrefix { get; set; }
}
public class GenTableColumnDto public class GenTableColumnDto
{ {
public int ColumnId { get; set; } public int ColumnId { get; set; }
+25
View File
@@ -0,0 +1,25 @@
using System.ComponentModel.DataAnnotations;
namespace ZR.ServiceCore.Model.Dto
{
public class PhoneLoginDto
{
/// <summary>
/// 验证码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 唯一标识
/// </summary>
public string Uuid { get; set; } = "";
public string LoginIP { get; set; }
[Required(ErrorMessage = "手机号不能为空")]
public string PhoneNum { get; set; }
/// <summary>
/// 手机短信验证码
/// </summary>
//[Required(ErrorMessage = "短信验证码不能为空")]
public string PhoneCode { get; set; }
}
}
+1
View File
@@ -30,5 +30,6 @@ namespace ZR.Model.System.Dto
/// 头像 /// 头像
/// </summary> /// </summary>
public string Photo { get; set; } public string Photo { get; set; }
public string UserIP { get; set; }
} }
} }

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