From c97a386f0f305934be247c21baf1bb6bb3c02892 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Fri, 28 Jul 2023 07:26:40 +0800
Subject: [PATCH 01/20] =?UTF-8?q?:sparkles:=20=E7=A7=BB=E5=8A=A8=E7=AB=AF?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81=E7=94=9F=E6=88=90=E8=8E=B7=E5=8F=96=E6=95=B0?=
=?UTF-8?q?=E6=8D=AE=E6=96=B0=E5=A2=9E=E5=8A=A0=E8=BD=BD=E4=B8=AD=E6=8F=90?=
=?UTF-8?q?=E7=A4=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../wwwroot/CodeGenTemplate/app/vue2.txt | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/app/vue2.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/app/vue2.txt
index b2f51734..c964ad94 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/app/vue2.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/app/vue2.txt
@@ -126,7 +126,7 @@ $end
-
+
@@ -174,13 +174,14 @@ $end
loading: false,
$foreach(item in genTable.Columns)
$if((item.HtmlType == "radio" || item.HtmlType == "select" || item.HtmlType == "checkbox") && item.DictType == "")
- // ${item.ColumnComment}选项列表 格式 eg:{ dictLabel: '标签', dictValue: '0'}
+ // ${item.ColumnComment}选项列表 格式 eg:{ label: '标签', value: '0'}
${item.CsharpFieldFl}Options: [],
$elseif(item.HtmlType == "datetime" && item.IsQuery == true)
//${item.ColumnComment}时间范围
dateRange${item.CsharpField}: [],
$end
$end
+ // 排序集合 格式 eg:{ label: '名称', value: 'userId'}
sortOptions: [
$foreach(column in genTable.Columns)
$if(column.IsSort)
@@ -199,6 +200,9 @@ $end
methods: {
checkPermi,
getList() {
+ uni.showLoading({
+ title: 'loading...'
+ });
$foreach(item in genTable.Columns)
$if(item.HtmlType == "datetime" && item.IsQuery == true)
this.addDateRange(this.queryParams, this.dateRange${item.CsharpField}, '${item.CsharpField}');
@@ -206,9 +210,8 @@ $end
$end
list${genTable.BusinessName}(this.queryParams).then(res => {
if (res.code == 200) {
- this.dataList = res.data.result;
+ this.dataList = [...this.dataList, ...res.data.result]
this.total = res.data.totalNum;
- this.loading = false;
}
})
},
@@ -282,10 +285,4 @@ $end
}
}
}
-
-
-
\ No newline at end of file
+
\ No newline at end of file
From a5b2a564b7073fcc4b75058ba04aafddad9cbf3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Fri, 28 Jul 2023 07:27:03 +0800
Subject: [PATCH 02/20] =?UTF-8?q?:sparkles:=20=E7=94=A8=E6=88=B7=E6=9F=A5?=
=?UTF-8?q?=E8=AF=A2=E6=96=B0=E5=A2=9E=E6=A0=B9=E6=8D=AE=E7=94=A8=E6=88=B7?=
=?UTF-8?q?id=E6=9F=A5=E8=AF=A2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ZR.Model/System/Dto/SysUserDto.cs | 2 +-
ZR.Service/System/SysUserService.cs | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/ZR.Model/System/Dto/SysUserDto.cs b/ZR.Model/System/Dto/SysUserDto.cs
index d8ba37a4..2dc0b955 100644
--- a/ZR.Model/System/Dto/SysUserDto.cs
+++ b/ZR.Model/System/Dto/SysUserDto.cs
@@ -18,7 +18,7 @@ namespace ZR.Model.System.Dto
public class SysUserQueryDto
{
- public long UserId { get; set; }
+ public long? UserId { get; set; }
public string UserName { get; set; }
public string NickName { get; set; }
public string Email { get; set; }
diff --git a/ZR.Service/System/SysUserService.cs b/ZR.Service/System/SysUserService.cs
index ee874d4f..ff31d263 100644
--- a/ZR.Service/System/SysUserService.cs
+++ b/ZR.Service/System/SysUserService.cs
@@ -43,6 +43,7 @@ namespace ZR.Service
{
var exp = Expressionable.Create();
exp.AndIF(!string.IsNullOrEmpty(user.UserName), u => u.UserName.Contains(user.UserName));
+ exp.AndIF(user.UserId > 0, u => u.UserId == user.UserId);
exp.AndIF(user.Status != -1, u => u.Status == user.Status);
exp.AndIF(user.BeginTime != DateTime.MinValue && user.BeginTime != null, u => u.Create_time >= user.BeginTime);
exp.AndIF(user.EndTime != DateTime.MinValue && user.EndTime != null, u => u.Create_time <= user.EndTime);
From 84ae9b0a922208b1489fb3d382519580c984152e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Thu, 27 Jul 2023 17:56:52 +0800
Subject: [PATCH 03/20] =?UTF-8?q?:arrow=5Fup:=20=E5=8D=87=E7=BA=A7sqlsugar?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ZR.Admin.WebApi/Program.cs | 3 +--
ZR.CodeGenerator/ZR.CodeGenerator.csproj | 2 +-
ZR.Model/ZR.Model.csproj | 2 +-
ZR.Repository/BaseRepository.cs | 15 +++++++++++----
ZR.Repository/ZR.Repository.csproj | 2 +-
5 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/ZR.Admin.WebApi/Program.cs b/ZR.Admin.WebApi/Program.cs
index 690339a5..db451842 100644
--- a/ZR.Admin.WebApi/Program.cs
+++ b/ZR.Admin.WebApi/Program.cs
@@ -80,8 +80,7 @@ builder.Services.AddMvc(options =>
})
.AddJsonOptions(options =>
{
- options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString |
- JsonNumberHandling.WriteAsString;
+ options.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString;
options.JsonSerializerOptions.WriteIndented = true;
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeConverter());
options.JsonSerializerOptions.Converters.Add(new JsonConverterUtil.DateTimeNullConverter());
diff --git a/ZR.CodeGenerator/ZR.CodeGenerator.csproj b/ZR.CodeGenerator/ZR.CodeGenerator.csproj
index 8cb72a71..f764c135 100644
--- a/ZR.CodeGenerator/ZR.CodeGenerator.csproj
+++ b/ZR.CodeGenerator/ZR.CodeGenerator.csproj
@@ -12,6 +12,6 @@
-
+
diff --git a/ZR.Model/ZR.Model.csproj b/ZR.Model/ZR.Model.csproj
index b5eba233..e9dd6178 100644
--- a/ZR.Model/ZR.Model.csproj
+++ b/ZR.Model/ZR.Model.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/ZR.Repository/BaseRepository.cs b/ZR.Repository/BaseRepository.cs
index e6d7351e..577acd56 100644
--- a/ZR.Repository/BaseRepository.cs
+++ b/ZR.Repository/BaseRepository.cs
@@ -351,8 +351,12 @@ namespace ZR.Repository
var total = 0;
page.PageSize = parm.PageSize;
page.PageIndex = parm.PageNum;
-
- page.Result = source.OrderByIF(parm.Sort.IsNotEmpty(), $"{parm.Sort.ToSqlFilter()} {(!string.IsNullOrWhiteSpace(parm.SortType) && parm.SortType.Contains("desc") ? "desc" : "asc")}")
+ if (parm.Sort.IsNotEmpty())
+ {
+ source.OrderByPropertyName(parm.Sort, parm.SortType.Contains("desc") ? OrderByType.Desc : OrderByType.Asc);
+ }
+ page.Result = source
+ //.OrderByIF(parm.Sort.IsNotEmpty(), $"{parm.Sort.ToSqlFilter()} {(!string.IsNullOrWhiteSpace(parm.SortType) && parm.SortType.Contains("desc") ? "desc" : "asc")}")
.ToPageList(parm.PageNum, parm.PageSize, ref total);
page.TotalNum = total;
return page;
@@ -372,9 +376,12 @@ namespace ZR.Repository
var total = 0;
page.PageSize = parm.PageSize;
page.PageIndex = parm.PageNum;
-
+ if (parm.Sort.IsNotEmpty())
+ {
+ source.OrderByPropertyName(parm.Sort, parm.SortType.Contains("desc") ? OrderByType.Desc : OrderByType.Asc);
+ }
var result = source
- .OrderByIF(parm.Sort.IsNotEmpty(), $"{parm.Sort.ToSqlFilter()} {(!string.IsNullOrWhiteSpace(parm.SortType) && parm.SortType.Contains("desc") ? "desc" : "asc")}")
+ //.OrderByIF(parm.Sort.IsNotEmpty(), $"{parm.Sort.ToSqlFilter()} {(!string.IsNullOrWhiteSpace(parm.SortType) && parm.SortType.Contains("desc") ? "desc" : "asc")}")
.ToPageList(parm.PageNum, parm.PageSize, ref total);
page.TotalNum = total;
diff --git a/ZR.Repository/ZR.Repository.csproj b/ZR.Repository/ZR.Repository.csproj
index a47f0544..a545e8bc 100644
--- a/ZR.Repository/ZR.Repository.csproj
+++ b/ZR.Repository/ZR.Repository.csproj
@@ -15,6 +15,6 @@
-
+
From 2ad3ea1fd8084ba0cf368fc67661f4d8079f98a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Fri, 28 Jul 2023 17:37:36 +0800
Subject: [PATCH 04/20] =?UTF-8?q?:sparkles:=E4=BB=A3=E7=A0=81=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E6=96=B0=E5=A2=9E=E5=AF=BC=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ZR.Admin.WebApi/Controllers/BaseController.cs | 30 +++++++------
.../System/CodeGeneratorController.cs | 2 +-
ZR.Admin.WebApi/GlobalUsing.cs | 7 +++
.../CodeGenTemplate/TplControllers.txt | 43 ++++++++++++++++---
.../wwwroot/CodeGenTemplate/TplIService.txt | 4 ++
.../wwwroot/CodeGenTemplate/TplService.txt | 35 +++++++++++++++
.../wwwroot/CodeGenTemplate/v3/Vue.txt | 41 ++++++++++++++++--
ZR.CodeGenerator/CodeGeneratorTool.cs | 2 +
ZR.CodeGenerator/Model/ReplaceDto.cs | 1 +
ZR.Service/GlobalUsing.cs | 1 +
ZR.Service/System/IService/ISysMenuService.cs | 2 +-
ZR.Service/System/SysMenuService.cs | 18 +++++++-
12 files changed, 160 insertions(+), 26 deletions(-)
create mode 100644 ZR.Admin.WebApi/GlobalUsing.cs
create mode 100644 ZR.Service/GlobalUsing.cs
diff --git a/ZR.Admin.WebApi/Controllers/BaseController.cs b/ZR.Admin.WebApi/Controllers/BaseController.cs
index 53110266..50576ea4 100644
--- a/ZR.Admin.WebApi/Controllers/BaseController.cs
+++ b/ZR.Admin.WebApi/Controllers/BaseController.cs
@@ -58,9 +58,11 @@ namespace ZR.Admin.WebApi.Controllers
///
protected IActionResult ExportExcel(string path, string fileName)
{
- //IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
- //string fileDir = Path.Combine(webHostEnvironment.WebRootPath, path, fileName);
-
+ //var webHostEnvironment = App.WebHostEnvironment;
+ if (!Path.Exists(path))
+ {
+ throw new CustomException(fileName + "文件不存在");
+ }
var stream = Io.File.OpenRead(path); //创建文件流
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
@@ -169,23 +171,23 @@ namespace ZR.Admin.WebApi.Controllers
///
/// 下载导入模板
///
- ///
- ///
- ///
+ /// 数据类型
+ /// 空数据类型集合
/// 下载文件名
///
- protected string DownloadImportTemplate(List list, Stream stream, string fileName)
+ protected (string, string) DownloadImportTemplate(List list, string fileName)
{
- IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
- string sFileName = $"{fileName}模板.xlsx";
- string newFileName = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", sFileName);
+ IWebHostEnvironment webHostEnvironment = App.WebHostEnvironment;
+ string sFileName = $"{fileName}.xlsx";
+ string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", sFileName);
- if (!Directory.Exists(newFileName))
+ //不存在模板创建模板
+ if (!Directory.Exists(fullPath))
{
- Directory.CreateDirectory(Path.GetDirectoryName(newFileName));
+ Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
+ MiniExcel.SaveAs(fullPath, list, overwriteFile: true);
}
- MiniExcel.SaveAs(newFileName, list);
- return sFileName;
+ return (sFileName, fullPath);
}
///
diff --git a/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs b/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs
index 2ae41e22..92187a78 100644
--- a/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/CodeGeneratorController.cs
@@ -280,7 +280,7 @@ namespace ZR.Admin.WebApi.Controllers
CodeGeneratorTool.Generate(dto);
if (genTableInfo.Options.GenerateMenu)
{
- SysMenuService.AddSysMenu(genTableInfo, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport);
+ SysMenuService.AddSysMenu(genTableInfo, dto.ReplaceDto.PermissionPrefix, dto.ReplaceDto.ShowBtnEdit, dto.ReplaceDto.ShowBtnExport, dto.ReplaceDto.ShowBtnImport);
}
foreach (var item in dto.GenCodes)
diff --git a/ZR.Admin.WebApi/GlobalUsing.cs b/ZR.Admin.WebApi/GlobalUsing.cs
new file mode 100644
index 00000000..4d4888ff
--- /dev/null
+++ b/ZR.Admin.WebApi/GlobalUsing.cs
@@ -0,0 +1,7 @@
+global using ZR.Common;
+global using Microsoft.AspNetCore.Authorization;
+global using Infrastructure;
+global using Infrastructure.Attribute;
+global using Infrastructure.Enums;
+global using Infrastructure.Model;
+global using Mapster;
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt
index 3727ab99..34b8aba6 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplControllers.txt
@@ -1,15 +1,12 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Mapster;
using Microsoft.AspNetCore.Mvc;
using ${options.DtosNamespace};
using ${options.ModelsNamespace}.${options.SubNamespace};
using ${options.IServicsNamespace}.${options.SubNamespace}.I${options.SubNamespace}Service;
using ${options.ApiControllerNamespace}.Extensions;
using ${options.ApiControllerNamespace}.Filters;
-using ${options.BaseNamespace}Common;
+$if(replaceDto.ShowBtnImport)
+using MiniExcelLibs;
+$end
//创建时间:${replaceDto.AddTime}
namespace ${options.ApiControllerNamespace}.Controllers
@@ -168,6 +165,40 @@ $if(replaceDto.ShowBtnTruncate)
}
$end
+$if(replaceDto.ShowBtnImport)
+ ///
+ /// 导入
+ ///
+ ///
+ ///
+ [HttpPost("importData")]
+ [Log(Title = "${genTable.FunctionName}导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false, IsSaveResponseData = true)]
+ [ActionPermissionFilter(Permission = "${replaceDto.PermissionPrefix}:import")]
+ public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile)
+ {
+ List<${replaceDto.ModelTypeName}> list = new();
+ using (var stream = formFile.OpenReadStream())
+ {
+ list = stream.Query<${replaceDto.ModelTypeName}>(startCell: "A1").ToList();
+ }
+
+ return SUCCESS(_${replaceDto.ModelTypeName}Service.Import${replaceDto.ModelTypeName}(list));
+ }
+
+ ///
+ /// ${genTable.FunctionName}导入模板下载
+ ///
+ ///
+ [HttpGet("importTemplate")]
+ [Log(Title = "${genTable.FunctionName}模板", BusinessType = BusinessType.EXPORT, IsSaveRequestData = true, IsSaveResponseData = false)]
+ [AllowAnonymous]
+ public IActionResult ImportTemplateExcel()
+ {
+ var result = DownloadImportTemplate(new List<${replaceDto.ModelTypeName}>() { }, "${replaceDto.ModelTypeName}");
+ return ExportExcel(result.Item2, result.Item1);
+ }
+$end
+
$if(showCustomInput)
///
/// 保存排序
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplIService.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplIService.txt
index 9e4cc3d1..b2ae84b0 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplIService.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplIService.txt
@@ -24,5 +24,9 @@ $end
$if(replaceDto.ShowBtnTruncate)
bool Truncate${replaceDto.ModelTypeName}();
$end
+
+$if(replaceDto.ShowBtnImport)
+ (string, object, object) Import${replaceDto.ModelTypeName}(List<${replaceDto.ModelTypeName}> list);
+$end
}
}
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplService.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplService.txt
index 9a26f934..66c559ef 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplService.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/TplService.txt
@@ -159,5 +159,40 @@ $if(replaceDto.ShowBtnTruncate)
return Truncate();
}
$end
+
+$if(replaceDto.ShowBtnImport)
+ ///
+ /// 导入${genTable.FunctionName}
+ ///
+ ///
+ public (string, object, object) Import${replaceDto.ModelTypeName}(List<${replaceDto.ModelTypeName}> list)
+ {
+ var x = Context.Storageable(list)
+ .SplitInsert(it => !it.Any())
+$foreach(column in genTable.Columns)
+$if(column.IsRequired && column.IsIncrement == false)
+ .SplitError(x => x.Item.${column.CsharpField}.IsEmpty(), "${column.ColumnComment}不能为空")
+$end
+$end
+ //.WhereColumns(it => it.UserName)//如果不是主键可以这样实现(多字段it=>new{it.x1,it.x2})
+ .ToStorage();
+ var result = x.AsInsertable.ExecuteCommand();//插入可插入部分;
+
+ string msg = $"插入{x.InsertList.Count} 更新{x.UpdateList.Count} 错误数据{x.ErrorList.Count} 不计算数据{x.IgnoreList.Count} 删除数据{x.DeleteList.Count} 总共{x.TotalList.Count}";
+ Console.WriteLine(msg);
+
+ //输出错误信息
+ foreach (var item in x.ErrorList)
+ {
+ Console.WriteLine("错误" + item.StorageMessage);
+ }
+ foreach (var item in x.IgnoreList)
+ {
+ Console.WriteLine("忽略" + item.StorageMessage);
+ }
+
+ return (msg, x.ErrorList, x.IgnoreList);
+ }
+$end
}
}
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
index a126b9ce..96eda459 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
@@ -108,6 +108,25 @@ $if(replaceDto.ShowBtnTruncate)
$end
+$if(replaceDto.ShowBtnImport)
+
+
+
+ {{ ${t}t('btn.import') }}
+
+
+
+
+
+
+
+
+
+
+$end
$if(replaceDto.ShowBtnExport)
@@ -136,7 +155,7 @@ $end
$if(sub)
- 详情
+ {{ ${t}t('btn.details') }}
$end
@@ -194,7 +213,7 @@ $end
$else
$if(replaceDto.ShowBtnView)
-
+
$end
$if(replaceDto.ShowBtnEdit)
@@ -426,7 +445,9 @@ from '@/api/${tool.FirstLowerCase(genTable.ModuleName)}/${genTable.BusinessName.
$if(replaceDto.ShowEditor == 1)
import Editor from '@/components/Editor'
$end
-
+$if(replaceDto.ShowBtnImport)
+import importData from '@/components/ImportData'
+$end
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
@@ -746,6 +767,20 @@ function handlePreview(row) {
}
$end
+$if(replaceDto.ShowBtnImport)
+// 导入数据成功处理
+const handleFileSuccess = (response) => {
+ const { item1, item2 } = response.data
+ var error = ''
+ item2.forEach((item) => {
+ error += item.storageMessage + ','
+ })
+ proxy.${alert}alert(item1 + '' + error + '
', '导入结果', {
+ dangerouslyUseHTMLString: true
+ })
+}
+$end
+
$if(replaceDto.ShowBtnExport)
// 导出按钮操作
function handleExport() {
diff --git a/ZR.CodeGenerator/CodeGeneratorTool.cs b/ZR.CodeGenerator/CodeGeneratorTool.cs
index 0495e04e..c4d1947e 100644
--- a/ZR.CodeGenerator/CodeGeneratorTool.cs
+++ b/ZR.CodeGenerator/CodeGeneratorTool.cs
@@ -50,6 +50,7 @@ namespace ZR.CodeGenerator
ShowBtnView = dto.GenTable.Options.CheckedBtn.Any(f => f == 5),
ShowBtnTruncate = dto.GenTable.Options.CheckedBtn.Any(f => f == 6),
ShowBtnMultiDel = dto.GenTable.Options.CheckedBtn.Any(f => f == 7),
+ ShowBtnImport = dto.GenTable.Options.CheckedBtn.Any(f => f == 8),
ViewFileName = dto.GenTable.BusinessName.FirstUpperCase(),
OperBtnStyle = dto.GenTable.Options.OperBtnStyle
};
@@ -586,6 +587,7 @@ namespace ZR.CodeGenerator
options.Data.Set("refs", "$");//特殊标签替换
options.Data.Set("t", "$");//特殊标签替换
options.Data.Set("modal", "$");//特殊标签替换
+ options.Data.Set("alert", "$");//特殊标签替换
options.Data.Set("index", "$");//特殊标签替换
options.Data.Set("confirm", "$");//特殊标签替换
options.Data.Set("nextTick", "$");
diff --git a/ZR.CodeGenerator/Model/ReplaceDto.cs b/ZR.CodeGenerator/Model/ReplaceDto.cs
index e2f974e4..3719e491 100644
--- a/ZR.CodeGenerator/Model/ReplaceDto.cs
+++ b/ZR.CodeGenerator/Model/ReplaceDto.cs
@@ -50,6 +50,7 @@ namespace ZR.CodeGenerator.Model
public bool ShowBtnView { get; set; }
public bool ShowBtnTruncate { get; set; }
public bool ShowBtnMultiDel { get; set; }
+ public bool ShowBtnImport { get; set; }
///
/// 上传URL data
///
diff --git a/ZR.Service/GlobalUsing.cs b/ZR.Service/GlobalUsing.cs
new file mode 100644
index 00000000..57439d9e
--- /dev/null
+++ b/ZR.Service/GlobalUsing.cs
@@ -0,0 +1 @@
+global using System.Collections.Generic;
\ No newline at end of file
diff --git a/ZR.Service/System/IService/ISysMenuService.cs b/ZR.Service/System/IService/ISysMenuService.cs
index 29bd0219..5896af80 100644
--- a/ZR.Service/System/IService/ISysMenuService.cs
+++ b/ZR.Service/System/IService/ISysMenuService.cs
@@ -39,7 +39,7 @@ namespace ZR.Service.System.IService
List BuildMenuTreeSelect(List menus);
- void AddSysMenu(GenTable genTableInfo, string permPrefix, bool showEdit, bool showExport);
+ void AddSysMenu(GenTable genTableInfo, string permPrefix, bool showEdit, bool showExport, bool showImport);
List SelectTreeMenuListByRoles(MenuQueryDto menu, List roles);
List SelectRoleMenuListByRole(MenuQueryDto menu, int roleId);
}
diff --git a/ZR.Service/System/SysMenuService.cs b/ZR.Service/System/SysMenuService.cs
index 2e625764..fbf84c2d 100644
--- a/ZR.Service/System/SysMenuService.cs
+++ b/ZR.Service/System/SysMenuService.cs
@@ -588,7 +588,7 @@ namespace ZR.Service
#endregion
- public void AddSysMenu(GenTable genTableInfo, string permPrefix, bool showEdit, bool showExport)
+ public void AddSysMenu(GenTable genTableInfo, string permPrefix, bool showEdit, bool showExport, bool showImport)
{
var menu = GetFirst(f => f.MenuName == genTableInfo.FunctionName);
if (menu is null)
@@ -671,6 +671,18 @@ namespace ZR.Service
Icon = "",
};
+ SysMenu menuImport = new()
+ {
+ MenuName = "导入",
+ ParentId = menu.MenuId,
+ OrderNum = 5,
+ Perms = $"{permPrefix}:import",
+ MenuType = "F",
+ Visible = "0",
+ Status = "0",
+ Icon = "",
+ };
+
menuList.Add(menuQuery);
menuList.Add(menuAdd);
menuList.Add(menuDel);
@@ -682,6 +694,10 @@ namespace ZR.Service
{
menuList.Add(menuExport);
}
+ if (showImport)
+ {
+ menuList.Add(menuImport);
+ }
//Insert(menuList);
var x = Storageable(menuList)
From 84fb0a0934fb4420bb3776a48ce004c7e320f4f8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Mon, 31 Jul 2023 17:28:06 +0800
Subject: [PATCH 05/20] =?UTF-8?q?:sparkles:=E6=96=B0=E5=A2=9EsqlDiffLog?=
=?UTF-8?q?=E5=BB=BA=E8=A1=A8=E8=84=9A=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
document/mysql/admin-mysql.sql | 20 ++++++++++++
.../admin-sqlserver-表字段说明导入.sql | 31 +++++++++++++++++++
document/sqlserver/admin-sqlserver.sql | 21 +++++++++++--
3 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/document/mysql/admin-mysql.sql b/document/mysql/admin-mysql.sql
index 5b60a344..d5812740 100644
--- a/document/mysql/admin-mysql.sql
+++ b/document/mysql/admin-mysql.sql
@@ -511,3 +511,23 @@ CREATE TABLE `sys_common_lang` (
`addtime` datetime(0) NULL DEFAULT NULL COMMENT '添加时间',
PRIMARY KEY (`Id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
+
+
+
+-- ----------------------------
+-- Table structure for SqlDiffLog
+-- ----------------------------
+DROP TABLE IF EXISTS `SqlDiffLog`;
+CREATE TABLE `SqlDiffLog` (
+ `PId` bigint(20) NOT NULL COMMENT '主键',
+ `TableName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '表名',
+ `BusinessData` varchar(4000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '业务数据内容',
+ `DiffType` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '差异类型insert,update,delete',
+ `Sql` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行sql语句',
+ `BeforeData` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '变更前数据',
+ `AfterData` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '变更后数据',
+ `UserName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '操作用户名',
+ `AddTime` datetime NULL DEFAULT NULL,
+ `ConfigId` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '数据库配置id',
+ PRIMARY KEY (`PId`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '数据差异日志' ROW_FORMAT = Dynamic;
diff --git a/document/sqlserver/admin-sqlserver-表字段说明导入.sql b/document/sqlserver/admin-sqlserver-表字段说明导入.sql
index 83f73966..44a40514 100644
--- a/document/sqlserver/admin-sqlserver-表字段说明导入.sql
+++ b/document/sqlserver/admin-sqlserver-表字段说明导入.sql
@@ -650,3 +650,34 @@ EXEC sp_addextendedproperty
'TABLE', N'gen_demo',
'COLUMN', N'remark'
GO
+
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'主键' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'PId'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'表名' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'TableName'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'业务数据内容' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'BusinessData'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'差异类型insert,update,delete' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'DiffType'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'执行sql语句' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'Sql'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'变更前数据' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'BeforeData'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'变更后数据' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'AfterData'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'操作用户名' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'UserName'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'数据库配置id' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog', @level2type=N'COLUMN',@level2name=N'ConfigId'
+GO
+
+EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'数据差异日志' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'SqlDiffLog'
+GO
diff --git a/document/sqlserver/admin-sqlserver.sql b/document/sqlserver/admin-sqlserver.sql
index d3c984ae..8db47340 100644
--- a/document/sqlserver/admin-sqlserver.sql
+++ b/document/sqlserver/admin-sqlserver.sql
@@ -486,7 +486,7 @@ CREATE TABLE [dbo].[sys_file](
[storeType] [INT] NULL
)
GO
-IF OBJECT_ID(N'sys_common_lang',N'U') is not NULL DROP TABLE sys_common_lang
+IF OBJECT_ID(N'sys_common_lang',N'U') is not NULL DROP TABLE dbo.sys_common_lang
GO
CREATE TABLE sys_common_lang
(
@@ -496,4 +496,21 @@ CREATE TABLE sys_common_lang
lang_name NVARCHAR(2000) NOT NULL, --
addtime DATETIME
)
-GO
\ No newline at end of file
+GO
+
+GO
+IF OBJECT_ID(N'SqlDiffLog',N'U') is not NULL DROP TABLE dbo.SqlDiffLog
+GO
+CREATE TABLE [dbo].[SqlDiffLog](
+ [PId] [BIGINT] NOT NULL PRIMARY KEY,
+ [TableName] [VARCHAR](255) NULL,
+ [BusinessData] [VARCHAR](4000) NULL,
+ [DiffType] [VARCHAR](255) NULL,
+ [Sql] [NVARCHAR](MAX) NULL,
+ [BeforeData] [NVARCHAR](MAX) NULL,
+ [AfterData] [NVARCHAR](MAX) NULL,
+ [UserName] [VARCHAR](255) NULL,
+ [AddTime] [DATETIME] NULL,
+ [ConfigId] [VARCHAR](255) NULL
+)
+GO
From e627ddc60d241fcdec211397e5f5d4aace3f30e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Mon, 31 Jul 2023 18:41:23 +0800
Subject: [PATCH 06/20] =?UTF-8?q?:zap:=E4=BC=98=E5=8C=96=E5=91=BD=E5=90=8D?=
=?UTF-8?q?=E7=A9=BA=E9=97=B4=E5=BC=95=E7=94=A8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ZR.Admin.WebApi/Controllers/BaseController.cs | 4 +---
ZR.Admin.WebApi/Controllers/CommonController.cs | 7 +------
.../System/ArticleCategoryController.cs | 10 ++--------
.../Controllers/System/ArticleController.cs | 6 +-----
.../Controllers/System/CommonLangController.cs | 7 -------
.../Controllers/System/SysConfigController.cs | 7 -------
.../Controllers/System/SysDeptController.cs | 6 +-----
.../Controllers/System/SysDictDataController.cs | 5 +----
.../Controllers/System/SysDictTypeController.cs | 7 +------
.../Controllers/System/SysLoginController.cs | 5 +----
.../Controllers/System/SysMenuController.cs | 7 +------
.../Controllers/System/SysNoticeController.cs | 8 +-------
.../Controllers/System/SysPostController.cs | 8 +-------
.../Controllers/System/SysProfileController.cs | 5 -----
.../Controllers/System/SysRoleController.cs | 17 +++--------------
.../Controllers/System/SysUserController.cs | 4 ----
.../Controllers/System/SysUserRoleController.cs | 4 +---
.../Controllers/System/TasksController.cs | 6 +-----
.../System/monitor/SysLogininforController.cs | 7 +------
.../System/monitor/SysOperlogController.cs | 6 +-----
20 files changed, 19 insertions(+), 117 deletions(-)
diff --git a/ZR.Admin.WebApi/Controllers/BaseController.cs b/ZR.Admin.WebApi/Controllers/BaseController.cs
index 50576ea4..fb72640c 100644
--- a/ZR.Admin.WebApi/Controllers/BaseController.cs
+++ b/ZR.Admin.WebApi/Controllers/BaseController.cs
@@ -1,6 +1,4 @@
-using Infrastructure;
-using Infrastructure.Extensions;
-using Infrastructure.Model;
+using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using Newtonsoft.Json;
diff --git a/ZR.Admin.WebApi/Controllers/CommonController.cs b/ZR.Admin.WebApi/Controllers/CommonController.cs
index 20590bc6..f664c561 100644
--- a/ZR.Admin.WebApi/Controllers/CommonController.cs
+++ b/ZR.Admin.WebApi/Controllers/CommonController.cs
@@ -1,14 +1,9 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Extensions;
-using Infrastructure.Model;
+using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model.System;
using ZR.Service.System;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs b/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs
index 75fd1357..77339a02 100644
--- a/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/ArticleCategoryController.cs
@@ -1,15 +1,9 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Mapster;
using Microsoft.AspNetCore.Mvc;
-using ZR.Model.Dto;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
-using ZR.Service.System.IService;
+using ZR.Model.Dto;
using ZR.Model.System;
+using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers
{
diff --git a/ZR.Admin.WebApi/Controllers/System/ArticleController.cs b/ZR.Admin.WebApi/Controllers/System/ArticleController.cs
index c9a67d13..c71e4acd 100644
--- a/ZR.Admin.WebApi/Controllers/System/ArticleController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/ArticleController.cs
@@ -1,8 +1,4 @@
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Mapster;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
diff --git a/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs b/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs
index eedd9f1c..7e3680de 100644
--- a/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs
@@ -1,13 +1,6 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
using Infrastructure.Extensions;
-using Infrastructure.Model;
-using Mapster;
-using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model;
using ZR.Model.Dto;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysConfigController.cs b/ZR.Admin.WebApi/Controllers/System/SysConfigController.cs
index 1d33ee3a..82a3b448 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysConfigController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysConfigController.cs
@@ -1,15 +1,8 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
using Infrastructure.Extensions;
-using Infrastructure.Model;
-using Mapster;
-using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model.System;
using ZR.Model.System.Dto;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs b/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs
index eeeb8ca7..a1e65115 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysDeptController.cs
@@ -1,11 +1,7 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using System.Collections;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model.System;
using ZR.Model.System.Dto;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs b/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs
index a3cab525..a1f835fd 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysDictDataController.cs
@@ -1,7 +1,4 @@
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Model;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysDictTypeController.cs b/ZR.Admin.WebApi/Controllers/System/SysDictTypeController.cs
index bdfc22f9..543b8e9f 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysDictTypeController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysDictTypeController.cs
@@ -1,11 +1,6 @@
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Mapster;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model;
using ZR.Model.System;
using ZR.Model.System.Dto;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs
index 87892827..2f160a63 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs
@@ -1,8 +1,5 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using IPTools.Core;
+using IPTools.Core;
using Lazy.Captcha.Core;
-using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using UAParser;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs b/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs
index ebfe5380..da54b1b2 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysMenuController.cs
@@ -1,9 +1,4 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Mapster;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Model.System;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs b/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs
index e5a7ec17..c5a5ef04 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysNoticeController.cs
@@ -1,16 +1,10 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Constant;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Mapster;
+using Infrastructure.Constant;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Admin.WebApi.Hubs;
-using ZR.Common;
using ZR.Model;
using ZR.Model.System;
using ZR.Model.System.Dto;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysPostController.cs b/ZR.Admin.WebApi/Controllers/System/SysPostController.cs
index b1e9c916..b99d9e99 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysPostController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysPostController.cs
@@ -1,14 +1,8 @@
-using Aliyun.OSS;
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Extensions;
-using Mapster;
+using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model;
using ZR.Model.System;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs b/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs
index 875538b0..144f2c1b 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysProfileController.cs
@@ -1,8 +1,3 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Mapster;
using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs b/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs
index 10b89d9e..e8fa8bad 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysRoleController.cs
@@ -1,21 +1,10 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Microsoft.AspNetCore.Mvc;
-using ZR.Common;
+using Microsoft.AspNetCore.Mvc;
+using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Model;
using ZR.Model.System;
-using ZR.Service.System.IService;
-using ZR.Admin.WebApi.Extensions;
using ZR.Model.System.Dto;
-using Mapster;
-using ZR.Service;
-using Microsoft.AspNetCore.Authorization;
-using Aliyun.OSS;
-using MiniExcelLibs.OpenXml;
-using MiniExcelLibs;
+using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers.System
{
diff --git a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs
index 0f2e2e3b..e2ad1667 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs
@@ -1,7 +1,3 @@
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using SqlSugar;
diff --git a/ZR.Admin.WebApi/Controllers/System/SysUserRoleController.cs b/ZR.Admin.WebApi/Controllers/System/SysUserRoleController.cs
index 6a145c8f..90fc836b 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysUserRoleController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysUserRoleController.cs
@@ -1,6 +1,4 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Filters;
using ZR.Model.System.Dto;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/TasksController.cs b/ZR.Admin.WebApi/Controllers/System/TasksController.cs
index 67a57529..8f8cf736 100644
--- a/ZR.Admin.WebApi/Controllers/System/TasksController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/TasksController.cs
@@ -1,8 +1,4 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Extensions;
-using Mapster;
+using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc;
using Quartz;
using SqlSugar;
diff --git a/ZR.Admin.WebApi/Controllers/System/monitor/SysLogininforController.cs b/ZR.Admin.WebApi/Controllers/System/monitor/SysLogininforController.cs
index 0b6e61d1..9a935571 100644
--- a/ZR.Admin.WebApi/Controllers/System/monitor/SysLogininforController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/monitor/SysLogininforController.cs
@@ -1,12 +1,7 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model;
using ZR.Model.System;
using ZR.Service.System.IService;
diff --git a/ZR.Admin.WebApi/Controllers/System/monitor/SysOperlogController.cs b/ZR.Admin.WebApi/Controllers/System/monitor/SysOperlogController.cs
index a374833b..7b608480 100644
--- a/ZR.Admin.WebApi/Controllers/System/monitor/SysOperlogController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/monitor/SysOperlogController.cs
@@ -1,10 +1,6 @@
-using Infrastructure.Attribute;
-using Infrastructure.Enums;
-using Infrastructure.Model;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
-using ZR.Common;
using ZR.Model.System.Dto;
using ZR.Service.System.IService;
From 946f4a6de9cf645db308327d32cd336a56912b1a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Mon, 31 Jul 2023 18:42:08 +0800
Subject: [PATCH 07/20] =?UTF-8?q?:bug:fix=E9=83=A8=E9=97=A8=E8=A1=A8?=
=?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=B1=9E=E6=80=A7=E6=9B=B4=E6=94=B9=E5=AF=BC?=
=?UTF-8?q?=E8=87=B4=E6=B7=BB=E5=8A=A0=E5=A4=B1=E8=B4=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ZR.Model/System/UserConstants.cs | 2 +-
ZR.Service/System/SysDeptService.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ZR.Model/System/UserConstants.cs b/ZR.Model/System/UserConstants.cs
index a944b6e2..e023591d 100644
--- a/ZR.Model/System/UserConstants.cs
+++ b/ZR.Model/System/UserConstants.cs
@@ -30,7 +30,7 @@
///
/// 部门正常状态
///
- public static string DEPT_NORMAL = "0";
+ public static int DEPT_NORMAL = 0;
///
/// 部门停用状态
diff --git a/ZR.Service/System/SysDeptService.cs b/ZR.Service/System/SysDeptService.cs
index 78bb0ba7..36693228 100644
--- a/ZR.Service/System/SysDeptService.cs
+++ b/ZR.Service/System/SysDeptService.cs
@@ -67,7 +67,7 @@ namespace ZR.Service.System
{
SysDept info = GetFirst(it => it.DeptId == dept.ParentId);
//如果父节点不为正常状态,则不允许新增子节点
- if (info != null && !UserConstants.DEPT_NORMAL.Equals(info?.Status))
+ if (info != null && UserConstants.DEPT_NORMAL != info?.Status)
{
throw new CustomException("部门停用,不允许新增");
}
From e496d4095ba7ec6ae9d794f457410e2f04866ebc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Wed, 19 Jul 2023 07:29:49 +0800
Subject: [PATCH 08/20] =?UTF-8?q?:sparkles:=E6=96=B0=E5=A2=9E=E5=BE=AE?=
=?UTF-8?q?=E4=BF=A1=E5=85=AC=E4=BC=97=E5=8F=B7=E5=8A=9F=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Infrastructure/Helper/DateTimeHelper.cs | 6 +
.../Controllers/WxOpenController.cs | 43 +++++++
ZR.Admin.WebApi/appsettings.json | 5 +
ZR.Common/Model/WxTokenResult.cs | 13 ++
ZR.Common/WxHelper.cs | 119 ++++++++++++++++++
ZR.Common/WxNoticeHelper.cs | 19 +--
6 files changed, 191 insertions(+), 14 deletions(-)
create mode 100644 ZR.Admin.WebApi/Controllers/WxOpenController.cs
create mode 100644 ZR.Common/Model/WxTokenResult.cs
create mode 100644 ZR.Common/WxHelper.cs
diff --git a/Infrastructure/Helper/DateTimeHelper.cs b/Infrastructure/Helper/DateTimeHelper.cs
index 37aa6b98..72076c4d 100644
--- a/Infrastructure/Helper/DateTimeHelper.cs
+++ b/Infrastructure/Helper/DateTimeHelper.cs
@@ -100,6 +100,12 @@ namespace Infrastructure
long unixTime = ((DateTimeOffset)dt).ToUnixTimeMilliseconds();
return unixTime;
}
+
+ public static long GetUnixTimeSeconds(DateTime dt)
+ {
+ long unixTime = ((DateTimeOffset)dt).ToUnixTimeSeconds();
+ return unixTime;
+ }
#endregion
#region 获取日期天的最小时间
diff --git a/ZR.Admin.WebApi/Controllers/WxOpenController.cs b/ZR.Admin.WebApi/Controllers/WxOpenController.cs
new file mode 100644
index 00000000..2ed49878
--- /dev/null
+++ b/ZR.Admin.WebApi/Controllers/WxOpenController.cs
@@ -0,0 +1,43 @@
+using Infrastructure.Extensions;
+using Microsoft.AspNetCore.Mvc;
+using System.Web;
+
+namespace ZR.Admin.WebApi.Controllers
+{
+ ///
+ /// 微信公众号
+ ///
+ [Route("[controller]/[action]")]
+ [AllowAnonymous]
+ public class WxOpenController : BaseController
+ {
+ private NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
+ public WxOpenController() { }
+
+ ///
+ /// 获取签名
+ ///
+ ///
+ ///
+ [Log(Title = "获取微信签名")]
+ [HttpGet]
+ public IActionResult GetSignature(string url = "")
+ {
+ url = HttpUtility.UrlDecode(url);
+ var appId = AppSettings.App(new string[] { "WxOpen", "AppID" });
+ var noncestr = Guid.NewGuid().ToString().Replace("-", "");
+ var timestamp = DateTimeHelper.GetUnixTimeSeconds(DateTime.Now);
+ var ticketResult = WxHelper.GetTicket();
+ if (appId.IsEmpty()) return ToResponse(ResultCode.CUSTOM_ERROR, "appId未配置");
+ if (ticketResult?.errcode != 0)
+ {
+ return ToResponse(ResultCode.CUSTOM_ERROR, "获取配置失败");
+ }
+
+ var signature = WxHelper.GetSignature(ticketResult.ticket, timestamp.ToString(), noncestr, url);
+
+ return SUCCESS(new { appId, signature, noncestr, timestamp, url });
+ }
+
+ }
+}
diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json
index 17494bab..2a47d0f6 100644
--- a/ZR.Admin.WebApi/appsettings.json
+++ b/ZR.Admin.WebApi/appsettings.json
@@ -56,6 +56,11 @@
"CorpSecret": "",
"SendUser": "@all"
},
+ //微信公众号设置
+ "WxOpen": {
+ "AppID": "",
+ "AppSecret": ""
+ },
//代码生成配置
"gen": {
"autoPre": true, //自动去除表前缀
diff --git a/ZR.Common/Model/WxTokenResult.cs b/ZR.Common/Model/WxTokenResult.cs
new file mode 100644
index 00000000..bea1614b
--- /dev/null
+++ b/ZR.Common/Model/WxTokenResult.cs
@@ -0,0 +1,13 @@
+namespace ZR.Common.Model
+{
+ public class WxTokenResult
+ {
+ ///
+ /// 0、正常
+ ///
+ public int errcode { get; set; }
+ public string errmsg { get; set; }
+ public string access_token { get; set; }
+ public string ticket { get; set; }
+ }
+}
diff --git a/ZR.Common/WxHelper.cs b/ZR.Common/WxHelper.cs
new file mode 100644
index 00000000..5063c8e2
--- /dev/null
+++ b/ZR.Common/WxHelper.cs
@@ -0,0 +1,119 @@
+using Infrastructure;
+using Infrastructure.Extensions;
+using Newtonsoft.Json;
+using System;
+using System.Security.Cryptography;
+using System.Text;
+using ZR.Common.Model;
+
+namespace ZR.Common
+{
+ public class WxHelper
+ {
+ private static readonly string GetTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
+ private static readonly string GetTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
+ private static readonly string AppID = AppSettings.App(new string[] { "WxOpen", "AppID" });
+ private static readonly string AppSECRET = AppSettings.App(new string[] { "WxOpen", "AppSecret" });
+
+ ///
+ /// 获取访问token
+ ///
+ ///
+ /// {"errcode":0,"errmsg":"ok","access_token":"iCbcfE1OjfRhV0_io-CzqTNC0lnrudeW3oF5rhJKfmINaxLClLa1FoqAY_wEXtodYh_DTnrtAwZfzeb-NRXvwiOoqUTHx3i6QKLYcfBtF8y-xd5mvaeaf3e9mvTAPhmX0lkm1cLTwRLmoa1IwzgQ-QZEZcuIcntWdEMGseVYok3BwCGpC87bt6nNdgnekZdFVRp1uuaxoctDGlXpoQlQsA","expires_in":7200}
+ ///
+ private static WxTokenResult GetAccessToken()
+ {
+ if (AppID.IsEmpty() || AppSECRET.IsEmpty())
+ {
+ Console.WriteLine("公众号配置错误");
+ throw new ArgumentException("公众号配置错误");
+ };
+ var Ck = "wx_token";
+ string getTokenUrl = $"{GetTokenUrl}?grant_type=client_credential&appid={AppID}&secret={AppSECRET}";
+ if (CacheHelper.Get(Ck) is WxTokenResult tokenResult)
+ {
+ return tokenResult;
+ }
+ else
+ {
+ string result = HttpHelper.HttpGet(getTokenUrl);
+
+ tokenResult = JsonConvert.DeserializeObject(result);
+
+ if (tokenResult?.errcode == 0)
+ {
+ CacheHelper.SetCache(Ck, tokenResult, 110);
+ }
+ else
+ {
+ Console.WriteLine("GetAccessToken失败,结果=" + result);
+ throw new Exception("获取AccessToken失败");
+ }
+ }
+ return tokenResult;
+ }
+
+ ///
+ /// 获取ticket
+ ///
+ ///
+ public static WxTokenResult GetTicket()
+ {
+ WxTokenResult token = GetAccessToken();
+ string ticket = token?.access_token;
+ var Ck = "wx_ticket";
+ string getTokenUrl = $"{GetTicketUrl}?access_token={ticket}&type=jsapi";
+ if (CacheHelper.Get(Ck) is WxTokenResult tokenResult)
+ {
+ return tokenResult;
+ }
+ else
+ {
+ string result = HttpHelper.HttpGet(getTokenUrl);
+ tokenResult = JsonConvert.DeserializeObject(result);
+
+ if (tokenResult?.errcode == 0)
+ {
+ CacheHelper.SetCache(Ck, tokenResult, 110);
+ }
+ else
+ {
+ Console.WriteLine("GetTicket,结果=" + result);
+ throw new Exception("获取ticket失败");
+ }
+ }
+ return tokenResult;
+ }
+
+ ///
+ /// 返回正确的签名
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static string GetSignature(string jsapi_ticket, string timestamp, string noncestr, string url = null)
+ {
+ if (string.IsNullOrEmpty(jsapi_ticket) || string.IsNullOrEmpty(noncestr) || string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(url))
+ return null;
+
+ //将字段添加到列表中。
+ string[] arr = new[]
+ {
+ string.Format("jsapi_ticket={0}",jsapi_ticket),
+ string.Format("noncestr={0}",noncestr),
+ string.Format("timestamp={0}",timestamp),
+ string.Format("url={0}",url)
+ };
+ //字典排序
+ Array.Sort(arr);
+ //使用URL键值对的格式拼接成字符串
+ var temp = string.Join("&", arr);
+
+ var sha1Arr = SHA1.HashData(Encoding.UTF8.GetBytes(temp));
+
+ return BitConverter.ToString(sha1Arr).Replace("-", "").ToLower();
+ }
+ }
+}
diff --git a/ZR.Common/WxNoticeHelper.cs b/ZR.Common/WxNoticeHelper.cs
index 976feb60..a89ab73b 100644
--- a/ZR.Common/WxNoticeHelper.cs
+++ b/ZR.Common/WxNoticeHelper.cs
@@ -1,6 +1,7 @@
using Infrastructure;
using System.Collections.Generic;
using System.Text.Json;
+using ZR.Common.Model;
namespace ZR.Common
{
@@ -44,7 +45,7 @@ namespace ZR.Common
System.Console.WriteLine("请完成企业微信配置");
return (0, "请完成企业微信通知配置");
}
- GetTokenResult tokenResult = GetAccessToken();
+ WxTokenResult tokenResult = GetAccessToken();
if (tokenResult == null || tokenResult.errcode != 0)
{
@@ -74,7 +75,7 @@ namespace ZR.Common
//返回结果
//{"errcode":0,"errmsg":"ok","invaliduser":""}
string msgResult = HttpHelper.HttpPost(msgUrl, postData, "contentType/json");
- GetTokenResult getTokenResult = JsonSerializer.Deserialize(msgResult);
+ WxTokenResult getTokenResult = JsonSerializer.Deserialize(msgResult);
System.Console.WriteLine(msgResult);
return (getTokenResult?.errcode == 0 ? 100 : 0, getTokenResult?.errmsg);
}
@@ -89,12 +90,12 @@ namespace ZR.Common
///
/// {"errcode":0,"errmsg":"ok","access_token":"iCbcfE1OjfRhV0_io-CzqTNC0lnrudeW3oF5rhJKfmINaxLClLa1FoqAY_wEXtodYh_DTnrtAwZfzeb-NRXvwiOoqUTHx3i6QKLYcfBtF8y-xd5mvaeaf3e9mvTAPhmX0lkm1cLTwRLmoa1IwzgQ-QZEZcuIcntWdEMGseVYok3BwCGpC87bt6nNdgnekZdFVRp1uuaxoctDGlXpoQlQsA","expires_in":7200}
///
- private static GetTokenResult GetAccessToken()
+ private static WxTokenResult GetAccessToken()
{
string getTokenUrl = $"{GetTokenUrl}?corpid={CORPID}&corpsecret={CORPSECRET}";
string getTokenResult = HttpHelper.HttpGet(getTokenUrl);
System.Console.WriteLine(getTokenResult);
- GetTokenResult tokenResult = JsonSerializer.Deserialize(getTokenResult);
+ WxTokenResult tokenResult = JsonSerializer.Deserialize(getTokenResult);
return tokenResult;
}
@@ -146,15 +147,5 @@ namespace ZR.Common
};
return dic;
}
-
- public class GetTokenResult
- {
- ///
- /// 0、正常
- ///
- public int errcode { get; set; }
- public string errmsg { get; set; }
- public string access_token { get; set; }
- }
}
}
From 5f063ad9d38580be2c8add3d66b301a4b3b1b699 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Tue, 1 Aug 2023 11:44:34 +0800
Subject: [PATCH 09/20] =?UTF-8?q?:sparkles:=E4=BB=A3=E7=A0=81=E7=94=9F?=
=?UTF-8?q?=E6=88=90=E6=96=B0=E5=A2=9Eswitch=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Controllers/System/SysUserController.cs | 2 +-
ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs
index e2ad1667..78b8c81b 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysUserController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysUserController.cs
@@ -45,7 +45,7 @@ namespace ZR.Admin.WebApi.Controllers.System
{
var list = UserService.SelectUserList(user, pager);
- return SUCCESS(list, TIME_FORMAT_FULL);
+ return SUCCESS(list);
}
///
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
index 96eda459..88648aaa 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
@@ -262,6 +262,7 @@ $set(labelName = column.ColumnComment)
$if(column.CsharpType == "int" || column.CsharpType == "long")
$set(value = "parseInt(item.dictValue)")
$set(number = ".number")
+ $set(switchType = ":active-value='1' :inactive-value='0'")
$end
$if(column.IsPK || column.IsIncrement)
@@ -353,6 +354,12 @@ $elseif(column.HtmlType == "colorPicker")
+$elseif(column.HtmlType == "switch")
+
+
+
+
+
$else
@@ -386,6 +393,7 @@ $set(columnName = column.CsharpFieldFl)
$if(column.CsharpType == "int" || column.CsharpType == "long")
$set(value = "parseInt(item.dictValue)")
$set(number = ".number")
+$set(switchType = ":active-value='1' :inactive-value='0'")
$end
$if(column.IsList == true)
$if(column.IsPk || column.CsharpField == genTable.SubTableFkName)
@@ -413,6 +421,12 @@ $elseif(column.HtmlType == "radio" || column.HtmlType == "selectRadio" || column
+$elseif(column.HtmlType == "switch")
+
+
+
+
+
$else
From 66a8d5793d99ce787b8ae7677f2e2b7b5d751455 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Wed, 2 Aug 2023 12:25:36 +0800
Subject: [PATCH 10/20] :bug:fix bug
---
ZR.Admin.WebApi/Extensions/DbExtension.cs | 2 +-
ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt | 4 +++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/ZR.Admin.WebApi/Extensions/DbExtension.cs b/ZR.Admin.WebApi/Extensions/DbExtension.cs
index 555fe0ba..54910f98 100644
--- a/ZR.Admin.WebApi/Extensions/DbExtension.cs
+++ b/ZR.Admin.WebApi/Extensions/DbExtension.cs
@@ -125,7 +125,7 @@ namespace ZR.Admin.WebApi.Extensions
SqlDiffLog log = new()
{
BeforeData = pars,
- BusinessData = data.ToString(),
+ BusinessData = data?.ToString(),
DiffType = diffType.ToString(),
Sql = sql,
TableName = item.TableName,
diff --git a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
index 88648aaa..157d2e94 100644
--- a/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
+++ b/ZR.Admin.WebApi/wwwroot/CodeGenTemplate/v3/Vue.txt
@@ -390,6 +390,7 @@ $if(sub)
$foreach(column in genTable.SubTable.Columns)
$set(labelName = column.ColumnComment)
$set(columnName = column.CsharpFieldFl)
+$set(value = "item.dictValue")
$if(column.CsharpType == "int" || column.CsharpType == "long")
$set(value = "parseInt(item.dictValue)")
$set(number = ".number")
@@ -425,7 +426,7 @@ $elseif(column.HtmlType == "switch")
-
+
$else
@@ -792,6 +793,7 @@ const handleFileSuccess = (response) => {
proxy.${alert}alert(item1 + '' + error + '
', '导入结果', {
dangerouslyUseHTMLString: true
})
+ getList()
}
$end
From 78a743d6b7d705a404d02a5039a050e80ae30d25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Wed, 2 Aug 2023 18:43:11 +0800
Subject: [PATCH 11/20] =?UTF-8?q?:sparkles:=E5=A4=9A=E8=AF=AD=E8=A8=80?=
=?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=96=B0=E5=A2=9E=E5=AF=BC=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../System/CommonLangController.cs | 61 +++++++++++++++++-
.../wwwroot/ImportTemplate/lang.xlsx | Bin 0 -> 11606 bytes
ZR.Admin.WebApi/wwwroot/data.xlsx | Bin 36741 -> 36802 bytes
ZR.Service/System/CommonLangService.cs | 34 ++++++++--
.../System/IService/ICommonLangService.cs | 3 +
5 files changed, 90 insertions(+), 8 deletions(-)
create mode 100644 ZR.Admin.WebApi/wwwroot/ImportTemplate/lang.xlsx
diff --git a/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs b/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs
index 7e3680de..092546c3 100644
--- a/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/CommonLangController.cs
@@ -1,8 +1,10 @@
using Infrastructure.Extensions;
using Microsoft.AspNetCore.Mvc;
+using MiniExcelLibs;
using ZR.Admin.WebApi.Filters;
using ZR.Model;
using ZR.Model.Dto;
+using ZR.Model.Models;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Controllers
@@ -128,6 +130,25 @@ namespace ZR.Admin.WebApi.Controllers
return ToResponse(response);
}
+ ///
+ /// 删除多语言配置
+ ///
+ ///
+ [HttpDelete("ByKey")]
+ [ActionPermissionFilter(Permission = "system:lang:delete")]
+ [Log(Title = "多语言配置", BusinessType = BusinessType.DELETE)]
+ public IActionResult DeleteCommonLangByKey(string langkey)
+ {
+ if (langkey.IsEmpty()) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }
+
+ var response = _CommonLangService
+ .Deleteable()
+ .EnableDiffLogEvent()
+ .Where(f => f.LangKey == langkey)
+ .ExecuteCommand();
+ return ToResponse(response);
+ }
+
///
/// 导出多语言配置
///
@@ -138,11 +159,49 @@ namespace ZR.Admin.WebApi.Controllers
public IActionResult Export([FromQuery] CommonLangQueryDto parm)
{
parm.PageSize = 10000;
- var list = _CommonLangService.GetList(parm).Result;
+ var list = _CommonLangService.GetListToPivot(parm);
string sFileName = ExportExcel(list, "CommonLang", "多语言配置");
return SUCCESS(new { path = "/export/" + sFileName, fileName = sFileName });
}
+ ///
+ /// 导入
+ ///
+ ///
+ ///
+ [HttpPost("importData")]
+ [Log(Title = "多语言设置导入", BusinessType = BusinessType.IMPORT, IsSaveRequestData = false, IsSaveResponseData = true)]
+ [ActionPermissionFilter(Permission = "system:lang:import")]
+ public IActionResult ImportData([FromForm(Name = "file")] IFormFile formFile)
+ {
+ List list = new();
+ using (var stream = formFile.OpenReadStream())
+ {
+ var rows = stream.Query(startCell: "A2").ToList();
+
+ foreach (var item in rows)
+ {
+ list.Add(new CommonLang() { LangCode = "zh-cn", LangKey = item.A, LangName = item.B, Addtime = DateTime.Now });
+ list.Add(new CommonLang() { LangCode = "en", LangKey = item.A, LangName = item.C, Addtime = DateTime.Now });
+ list.Add(new CommonLang() { LangCode = "zh-tw", LangKey = item.A, LangName = item.D, Addtime = DateTime.Now });
+ }
+ }
+
+ return SUCCESS(_CommonLangService.ImportCommonLang(list));
+ }
+
+ ///
+ /// 多语言设置导入模板下载
+ ///
+ ///
+ [HttpGet("importTemplate")]
+ [Log(Title = "多语言设置模板", BusinessType = BusinessType.EXPORT, IsSaveRequestData = true, IsSaveResponseData = false)]
+ [AllowAnonymous]
+ public IActionResult ImportTemplateExcel()
+ {
+ var result = DownloadImportTemplate(new List() { }, "lang");
+ return ExportExcel(result.Item2, result.Item1);
+ }
}
}
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/wwwroot/ImportTemplate/lang.xlsx b/ZR.Admin.WebApi/wwwroot/ImportTemplate/lang.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..66de938a4192cc1f0ce12767040fe0b575bc143b
GIT binary patch
literal 11606
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
literal 0
HcmV?d00001
diff --git a/ZR.Admin.WebApi/wwwroot/data.xlsx b/ZR.Admin.WebApi/wwwroot/data.xlsx
index bb86189eb1078bb9dc81ba0f53b1866c987f02ac..a35adecce86a5ef7a3240256db5e3aed156bf033 100644
GIT binary patch
delta 7332
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¨6Yr?yrj
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
Ot{+2#vK#V0)c*sI(ZyW=
delta 7241
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
public PagedInfo GetList(CommonLangQueryDto parm)
{
- //开始拼装查询条件
var predicate = Expressionable.Create();
- //搜索条件查询语法参考Sqlsugar
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangCode), it => it.LangCode == parm.LangCode);
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangKey), it => it.LangKey.Contains(parm.LangKey));
predicate = predicate.AndIF(parm.BeginAddtime != null, it => it.Addtime >= parm.BeginAddtime && it.Addtime <= parm.EndAddtime);
@@ -49,10 +46,8 @@ namespace ZR.Service.System
///
public dynamic GetListToPivot(CommonLangQueryDto parm)
{
- //开始拼装查询条件
var predicate = Expressionable.Create();
- //搜索条件查询语法参考Sqlsugar
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangCode), it => it.LangCode == parm.LangCode);
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangKey), it => it.LangKey.Contains(parm.LangKey));
predicate = predicate.AndIF(parm.BeginAddtime != null, it => it.Addtime >= parm.BeginAddtime && it.Addtime <= parm.EndAddtime);
@@ -64,10 +59,8 @@ namespace ZR.Service.System
public List GetLangList(CommonLangQueryDto parm)
{
- //开始拼装查询条件
var predicate = Expressionable.Create();
- //搜索条件查询语法参考Sqlsugar
predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangCode), it => it.LangCode == parm.LangCode);
//predicate = predicate.AndIF(!string.IsNullOrEmpty(parm.LangKey), it => it.LangKey.Contains(parm.LangKey));
var response = Queryable()
@@ -110,6 +103,33 @@ namespace ZR.Service.System
}
return dic;
}
+
+ ///
+ /// 导入多语言设置
+ ///
+ ///
+ public (string, object, object) ImportCommonLang(List list)
+ {
+ var x = Storageable(list)
+ .WhereColumns(it => new { it.LangKey, it.LangCode })
+ .ToStorage();
+ x.AsInsertable.ExecuteReturnSnowflakeIdList();//插入可插入部分;
+ x.AsUpdateable.UpdateColumns(it => new { it.LangName }).ExecuteCommand();
+
+ string msg = $"插入{x.InsertList.Count} 更新{x.UpdateList.Count} 错误数据{x.ErrorList.Count} 不计算数据{x.IgnoreList.Count} 删除数据{x.DeleteList.Count} 总共{x.TotalList.Count}";
+
+ //输出错误信息
+ foreach (var item in x.ErrorList)
+ {
+ Console.WriteLine("错误" + item.StorageMessage);
+ }
+ foreach (var item in x.IgnoreList)
+ {
+ Console.WriteLine("忽略" + item.StorageMessage);
+ }
+
+ return (msg, x.ErrorList, x.IgnoreList);
+ }
#endregion
}
}
\ No newline at end of file
diff --git a/ZR.Service/System/IService/ICommonLangService.cs b/ZR.Service/System/IService/ICommonLangService.cs
index b8a3f5fe..5af554ae 100644
--- a/ZR.Service/System/IService/ICommonLangService.cs
+++ b/ZR.Service/System/IService/ICommonLangService.cs
@@ -3,6 +3,7 @@ using ZR.Model;
using ZR.Model.Dto;
using ZR.Model.Models;
using System.Collections.Generic;
+using JinianNet.JNTemplate;
namespace ZR.Service.System.IService
{
@@ -19,5 +20,7 @@ namespace ZR.Service.System.IService
dynamic GetListToPivot(CommonLangQueryDto parm);
void StorageCommonLang(CommonLangDto parm);
Dictionary SetLang(List msgList);
+
+ (string, object, object) ImportCommonLang(List list);
}
}
From 2ab26786bafdb0c43a449c73fc1586fe3ddee158 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Thu, 3 Aug 2023 20:27:35 +0800
Subject: [PATCH 12/20] :pencil:update readme
---
README.en.md | 202 ++++++++++++++++++++++++++++++++++++++++
README.md | 29 ++++--
document/images/a1.png | Bin 18072 -> 13855 bytes
document/images/a10.png | Bin 0 -> 96377 bytes
document/images/a7.png | Bin 0 -> 28229 bytes
document/images/a8.png | Bin 21173 -> 17741 bytes
document/images/a9.png | Bin 0 -> 15471 bytes
7 files changed, 224 insertions(+), 7 deletions(-)
create mode 100644 README.en.md
create mode 100644 document/images/a10.png
create mode 100644 document/images/a7.png
create mode 100644 document/images/a9.png
diff --git a/README.en.md b/README.en.md
new file mode 100644
index 00000000..a6a666e1
--- /dev/null
+++ b/README.en.md
@@ -0,0 +1,202 @@
+ ZR.Admin.NET Back-end management system
+base.NET5/.Net7 + vue2.x/vue3.x/uniapp Front-end and back-end separation of .NET rapid development framework
+
+
+
+
+
+
+
+
+---
+
+
+
+---
+
+## 🍟 overview
+
+- This project is suitable for developers with some NetCore and vue foundation
+ -Based on. NET5/. A common rights management platform (RBAC model) implemented by NET7. Integrate the latest technology for efficient and rapid development, front-end and back-end separation mode, out of the box.
+- Less code, simple to learn, easy to understand, powerful, easy to extend, lightweight, make web development faster, simpler and more efficient (say goodbye to 996), solve 70% of repetitive work, focus on your business, easy development from now on!
+- 提供了技术栈(Ant Design Vue)版[Ant Design Vue](https://gitee.com/billzh/mc-dull.git)
+- 七牛云通用云产品优惠券:[点我进入](https://s.qiniu.com/FzEfay)。
+- 腾讯云秒杀场:[☛☛ 点我进入 ☚☚](https://curl.qcloud.com/4yEoRquq)。
+- 腾讯云优惠券:[☛☛ 点我领取 ☚☚](https://curl.qcloud.com/5J4nag8D)。
+- 阿里云特惠专区:[☛☛ 点我进入 ☚☚](https://www.aliyun.com/minisite/goods?userCode=uotn5vt1&share_source=copy_link)
+
+```
+If it helps you, you can click "Star" in the upper right corner to collect it, so that the author has the motivation to continue to go on for free, thank you! ~
+```
+
+## 🍿 Online experience
+
+- Official documentation:http://www.izhaorui.cn/doc
+- Join a group chat:[立即加入](http://www.izhaorui.cn/doc/contact.html)
+- Vue3.x experience:[http://www.izhaorui.cn/vue3](http://www.izhaorui.cn/vue3)
+- Vue2.x experience:[http://www.izhaorui.cn/admin](http://www.izhaorui.cn/admin)
+- Uniapp experience:[http://www.izhaorui.cn/h5](http://www.izhaorui.cn/h5)
+- account/password:admin/123456
+
+| H5 | WeChat mini program |
+| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
+|  |  |
+
+```
+Since it is a personal project, the funds are limited, and the experience server is low-fied, please cherish it, poke it lightly, and appreciate it!!
+```
+
+## 💒 Code repository
+
+| repository | Github | Gitee |
+| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
+| Net7 | [Clone/Download](https://github.com/izhaorui/Zr.Admin.NET) | [Clone/Download](https://gitee.com/izory/ZrAdminNetCore/tree/net7.0/) |
+| Vue3(Hot) | [Clone/Download](https://github.com/izhaorui/ZR.Admin.Vue3) | [Clone/Download](https://gitee.com/izory/ZRAdmin-vue) |
+
+## 🍁 Front-end technology
+
+Vue Front-end technology stack: Based on Vue2.x/Vue3.x/UniApp, Vue, Vue-router, Vue-CLI, AXIOS, Element-UI, Echats, i18N Internationalization, etc., the front-end adopts VSCODE tool development
+
+## 🍀 Back-end technology
+
+- Core Framework: . Net5.0/. Net7.0 + Web API + sqlsugar + swagger + signalR + IpRateLimit + Quartz.net + Redis
+- Scheduled tasks: Quartz.Net component that supports the execution of assemblies or HTTP network requests
+- Security support: filters (data permission filtering), SQL injection, request forgery
+- Log management: NLog, login log, operation log, scheduled task log
+- Tools: Captcha, rich public functions
+- Interface throttling: Supports interface throttling to avoid excessive pressure on the service layer caused by malicious requests
+- Code generation: efficient development, the code generator can generate all front-end and back-end code with one click
+- Data dictionary: Support data dictionary, which can facilitate the management of some states
+- Sharding and sharding: Using ORM SQLSUGAR, you can easily achieve superior sharding and sharding performance
+- Multi-tenant: Support multi-tenancy function
+- Cache data: Built-in memory cache and Redis
+
+## 🍖 Built-in features
+
+1. User management: The user is the system operator, and this function mainly completes the system user configuration.
+2. Department management: configure the system organization (company, department, group), tree structure display.
+3. Job management: configure the position of the system user.
+4. Menu management: configure system menus, operation permissions, button permission identification, etc.
+5. Role Management: Role menu permission assignment.
+6. Dictionary management: maintain some relatively fixed data that is often used in the system.
+7. Operation log: system normal operation log records and queries; System exception information logging and querying.
+8. Logon logon: The system logon log record query contains logon exceptions.
+9. System Interface: Use Swagger to generate relevant API interface documentation.
+10. Service monitoring: Monitor the current system CPU, memory, disk, stack, and other related information.
+11. Online Builder: Drag form elements to generate the corresponding VUE code (only VUE2 supported).
+12. Task system: Based on the Quartz.NET, you can schedule tasks online (add, modify, delete, manually execute) including execution result logs.
+13. Article management: You can write article records.
+14. Code generation: You can generate front-end and back-end code (.cs, .vue, .js, .sql, etc.) with one click, support download, customize the configuration of front-end display controls, and make development faster and more efficient (the strongest in history).
+15. Parameter management: dynamically configure common parameters for the system.
+16. Send Mail: You can send mail to multiple users.
+17. File management: You can manage uploaded files, which currently supports uploading to on-premises and Alibaba Cloud.
+18. Notification management: The system notifies and announces information release and maintenance, and uses SignalR to realize real-time notification to users.
+19. Account Registration: You can register an account to log in to the system.
+20. Multi-language management: support static and back-end dynamic configuration internationalization. Currently only supports Chinese, English, and Traditional characters (only VUE3 is supported)
+
+## 🍻 Project structure
+
+```
+├─ZR.Service ->[服务层类库]:提供WebApi接口调用;
+├─ZR.Repository ->[仓库层类库]:方便提供有执行存储过程的操作;
+├─ZR.Model ->[实体层类库]:提供项目中的数据库表、数据传输对象;
+├─ZR.Admin.WebApi ->[webapi接口]:为Vue版或其他三方系统提供接口服务。
+├─ZR.Tasks ->[定时任务类库]:提供项目定时任务实现功能;
+├─ZR.CodeGenerator ->[代码生成功能]:包含代码生成的模板、方法、代码生成的下载。
+├─ZR.Vue ->[前端UI]:vue2.0版本UI层(已经不再更新推荐使用vue3)。
+├─document ->[文档]:数据库脚本
+```
+
+## 🍎 Storyplate
+
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+
+## Mobile Storyplate
+
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+  |
+
+
+  |
+
+
+
+
+## 🎉 Advantages
+
+1. The front-end system does not need to write login, authorization, and authentication modules; Just write the business module
+2. The background system can be used directly after release without any secondary development
+3. The front-end and back-end systems are separated, and they are separate systems (domain names can be independent)
+4. Unified handling of global exceptions
+5. Custom code generation features
+6. Less dependence, easy to get started
+7. Comprehensive documentation
+
+## 💐 Special thanks
+
+- 👉Ruoyi.vue:[Ruoyi](http://www.ruoyi.vip/)
+- 👉SqlSugar:[SqlSugar](https://gitee.com/dotnetchina/SqlSugar)
+- 👉vue-element-admin:[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
+- 👉Meiam.System:[Meiam.System](https://github.com/91270/Meiam.System)
+
+## 🎀 donation
+
+If you feel that the project has helped you, you can ask the author for a cup of coffee as a sign of encouragement ☕️
+
diff --git a/README.md b/README.md
index ca0122c9..cb92a4a1 100644
--- a/README.md
+++ b/README.md
@@ -5,9 +5,17 @@
-
+
+---
+
+
+
+---
+
## 🍟 概述
- 本项目适合有一定 NetCore 和 vue 基础的开发人员
@@ -37,15 +45,15 @@
|  |  |
```
-由于是个人项目,资金有限,体验服是低配,请大家爱惜,轻戳,不胜感激!!!
+由于是个人项目,资金有限,体验服务器是低配,请大家爱惜,轻戳,不胜感激!!!
```
## 💒 代码仓库
-| 仓库 | Github | Gitee |
-| ---- | ------------------------------------------------------ | ---------------------------------------------------------------- |
-| Net7 | [克隆/下载](https://github.com/izhaorui/Zr.Admin.NET) | [克隆/下载](https://gitee.com/izory/ZrAdminNetCore/tree/net7.0/) |
-| Vue3 | [克隆/下载](https://github.com/izhaorui/ZR.Admin.Vue3) | [克隆/下载](https://gitee.com/izory/ZRAdmin-vue) |
+| 仓库 | Github | Gitee |
+| -------------- | ------------------------------------------------------ | ---------------------------------------------------------------- |
+| Net7 | [克隆/下载](https://github.com/izhaorui/Zr.Admin.NET) | [克隆/下载](https://gitee.com/izory/ZrAdminNetCore/tree/net7.0/) |
+| Vue3(推荐使用) | [克隆/下载](https://github.com/izhaorui/ZR.Admin.Vue3) | [克隆/下载](https://gitee.com/izory/ZRAdmin-vue) |
## 🍁 前端技术
@@ -97,7 +105,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
├─ZR.Admin.WebApi ->[webapi接口]:为Vue版或其他三方系统提供接口服务。
├─ZR.Tasks ->[定时任务类库]:提供项目定时任务实现功能;
├─ZR.CodeGenerator ->[代码生成功能]:包含代码生成的模板、方法、代码生成的下载。
-├─ZR.Vue ->[前端UI]:vue2.0版本UI层。
+├─ZR.Vue ->[前端UI]:vue2.0版本UI层(已经不再更新推荐使用vue3)。
├─document ->[文档]:数据库脚本
```
@@ -160,6 +168,13 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
 |
 |
+
+
+  |
+  |
+
+
+  |
diff --git a/document/images/a1.png b/document/images/a1.png
index 4f2b9343355c93dac5125bf386403ba51b9b20d9..e3e75efa94d75ac9f35e6ff5444cd973f9df832a 100644
GIT binary patch
literal 13855
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
literal 18072
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
ZsBiLnIRP_%Oq}^7Ev_I|En*n_{{i8uEd2lg
diff --git a/document/images/a10.png b/document/images/a10.png
new file mode 100644
index 0000000000000000000000000000000000000000..be3ace9ed7bfd6263062bd6e98b34108dc3e81d3
GIT binary patch
literal 96377
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