commit 5f40d38679be35faf7c1ee7de22755004f9b6194
Author: net <>
Date: Fri Jun 2 21:15:33 2023 +0800
Initial commit
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1ff0c42
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,63 @@
+###############################################################################
+# Set default behavior to automatically normalize line endings.
+###############################################################################
+* text=auto
+
+###############################################################################
+# Set default behavior for command prompt diff.
+#
+# This is need for earlier builds of msysgit that does not have it on by
+# default for csharp files.
+# Note: This is only used by command line
+###############################################################################
+#*.cs diff=csharp
+
+###############################################################################
+# Set the merge driver for project and solution files
+#
+# Merging from the command prompt will add diff markers to the files if there
+# are conflicts (Merging from VS is not affected by the settings below, in VS
+# the diff markers are never inserted). Diff markers may cause the following
+# file extensions to fail to load in VS. An alternative would be to treat
+# these files as binary and thus will always conflict and require user
+# intervention with every merge. To do so, just uncomment the entries below
+###############################################################################
+#*.sln merge=binary
+#*.csproj merge=binary
+#*.vbproj merge=binary
+#*.vcxproj merge=binary
+#*.vcproj merge=binary
+#*.dbproj merge=binary
+#*.fsproj merge=binary
+#*.lsproj merge=binary
+#*.wixproj merge=binary
+#*.modelproj merge=binary
+#*.sqlproj merge=binary
+#*.wwaproj merge=binary
+
+###############################################################################
+# behavior for image files
+#
+# image files are treated as binary by default.
+###############################################################################
+#*.jpg binary
+#*.png binary
+#*.gif binary
+
+###############################################################################
+# diff behavior for common document formats
+#
+# Convert binary document formats to text before diffing them. This feature
+# is only available from the command line. Turn it on by uncommenting the
+# entries below.
+###############################################################################
+#*.doc diff=astextplain
+#*.DOC diff=astextplain
+#*.docx diff=astextplain
+#*.DOCX diff=astextplain
+#*.dot diff=astextplain
+#*.DOT diff=astextplain
+#*.pdf diff=astextplain
+#*.PDF diff=astextplain
+#*.rtf diff=astextplain
+#*.RTF diff=astextplain
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..985e687
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,273 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+/ARW.Admin.WebApi/appsettings.Stage.json
+/CodeGenerate
+/ARW.WebApi/appsettings.Production.json
+/ARW.WebApi/wwwroot/uploads
+/ARW.WebApi/wwwroot/Generatecode
+/ARW.WebApi/wwwroot/export
+/ARW.Vue/src/views/business/Gendemo.vue
+/ARW.WebApi/Properties/launchSettings.json
+/ARW.WebApi/ARWAdmin.xml
+/ARW.WebApi/DataProtection
+/Quartz.NET.WindowsService
+
diff --git a/.net_run.bat b/.net_run.bat
new file mode 100644
index 0000000..bfd85fe
--- /dev/null
+++ b/.net_run.bat
@@ -0,0 +1,10 @@
+"age": 10,
+"classId": "1547502470350114800",
+"className": "1班",
+"sex": "1",
+"studentDescribe": "
啊实打实大苏打实打实实打实上的
",
+"studentId": 1548629251954184200,
+"studentImg": "/url",
+"studentName": "张思1",
+"studentService": [{service_name: "特殊服务", service_price: "999"}],
+"studentTag": "a,v,c"
\ No newline at end of file
diff --git a/ARW.CodeGenerator/ARW.CodeGenerator.csproj b/ARW.CodeGenerator/ARW.CodeGenerator.csproj
new file mode 100644
index 0000000..e03b913
--- /dev/null
+++ b/ARW.CodeGenerator/ARW.CodeGenerator.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net6.0
+ ARW.CodeGenerator
+ ARW.CodeGenerator
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ARW.CodeGenerator/CodeGenerateOption.cs b/ARW.CodeGenerator/CodeGenerateOption.cs
new file mode 100644
index 0000000..b7f4e3f
--- /dev/null
+++ b/ARW.CodeGenerator/CodeGenerateOption.cs
@@ -0,0 +1,52 @@
+namespace ARW.CodeGenerator
+{
+ public class CodeGenerateOption
+ {
+ ///
+ /// 项目命名空间
+ ///
+ public string BaseNamespace { get; set; }
+ ///
+ /// 下级命名空间
+ ///
+ public string SubNamespace { get; set; }
+ ///
+ /// 数据实体命名空间
+ ///
+ public string ModelsNamespace { get; set; }
+ ///
+ /// 输入输出数据实体名称空间
+ ///
+ public string DtosNamespace { get; set; }
+ ///
+ /// 仓储接口命名空间
+ ///
+ public string IRepositoriesNamespace { get; set; }
+ ///
+ /// 仓储实现名称空间
+ ///
+ public string RepositoriesNamespace { get; set; }
+ ///
+ /// 服务接口命名空间
+ ///
+ public string IServicsNamespace { get; set; }
+ ///
+ /// 服务接口实现命名空间
+ ///
+ public string ServicesNamespace { get; set; }
+
+ ///
+ /// Api控制器命名空间
+ ///
+ public string ApiControllerNamespace { get; set; }
+
+ ///
+ /// 去掉的表头字符
+ ///
+ public string ReplaceTableNameStr { get; set; }
+ ///
+ /// 要生数据的表,用“,”分割
+ ///
+ //public string TableList { get; set; }
+ }
+}
diff --git a/ARW.CodeGenerator/CodeGenerateTemplate.cs b/ARW.CodeGenerator/CodeGenerateTemplate.cs
new file mode 100644
index 0000000..319ebf6
--- /dev/null
+++ b/ARW.CodeGenerator/CodeGenerateTemplate.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Linq;
+using System.Text;
+using ARW.Model.System.Generate;
+
+namespace ARW.CodeGenerator
+{
+ ///
+ /// 代码生成模板
+ ///
+ public class CodeGenerateTemplate
+ {
+ //模板调用
+ public static string QueryExp(string propertyName, string queryType)
+ {
+ if (queryType.Equals("EQ"))
+ {
+ return $"it => it.{ propertyName} == parm.{propertyName})";
+ }
+ if (queryType.Equals("LIKE"))
+ {
+ return $"it => it.{propertyName}.Contains(parm.{propertyName}))";
+ }
+ if (queryType.Equals("GTE"))
+ {
+ return $"it => it.{ propertyName} >= parm.{propertyName})";
+ }
+ if (queryType.Equals("GT"))
+ {
+ return $"it => it.{ propertyName} > parm.{propertyName})";
+ }
+ if (queryType.Equals("LT"))
+ {
+ return $"it => it.{ propertyName} < parm.{propertyName})";
+ }
+ if (queryType.Equals("LTE"))
+ {
+ return $"it => it.{ propertyName} <= parm.{propertyName})";
+ }
+ if (queryType.Equals("NE"))
+ {
+ return $"it => it.{ propertyName} != parm.{propertyName})";
+ }
+ if (queryType.Equals("ARWKE"))
+ {
+ return $"it => it.{ propertyName}.Contains(parm.{propertyName}))";
+ }
+ return $"it => it.{ propertyName} == parm.{propertyName})";
+ }
+
+ }
+}
diff --git a/ARW.CodeGenerator/CodeGeneratorTool.cs b/ARW.CodeGenerator/CodeGeneratorTool.cs
new file mode 100644
index 0000000..6f34b58
--- /dev/null
+++ b/ARW.CodeGenerator/CodeGeneratorTool.cs
@@ -0,0 +1,805 @@
+using Infrastructure;
+using Infrastructure.Extensions;
+using JinianNet.JNTemplate;
+using SqlSugar;
+using SqlSugar.IOC;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using ARW.CodeGenerator.Model;
+using ARW.Model.System.Generate;
+
+namespace ARW.CodeGenerator
+{
+ ///
+ /// 代码生成器
+ ///
+ ///
+ public class CodeGeneratorTool
+ {
+ ///
+ /// 代码生成器配置
+ ///
+ private static CodeGenerateOption _option = new CodeGenerateOption();
+
+
+ #region 业务生成
+ ///
+ /// 代码生成器入口方法
+ ///
+ ///
+ public static void Generate(GenerateDto dto)
+ {
+ _option.BaseNamespace = dto.GenTable.BaseNameSpace;
+ _option.SubNamespace = dto.GenTable.ModuleName.FirstUpperCase();
+ _option.DtosNamespace = _option.BaseNamespace + "Model";
+ _option.ModelsNamespace = _option.BaseNamespace + "Model";
+ _option.RepositoriesNamespace = _option.BaseNamespace + "Repository";
+ _option.IRepositoriesNamespace = _option.BaseNamespace + "Repository";
+ _option.IServicsNamespace = _option.BaseNamespace + "Service";
+ _option.ServicesNamespace = _option.BaseNamespace + "Service";
+ _option.ApiControllerNamespace = _option.BaseNamespace + "WebApi";
+
+ if (dto.GenTable.ModuleName.Contains('/')) dto.GenTable.ModuleName = dto.GenTable.ModuleName.Replace('/', '.');
+
+ if (dto.GenType == "1")
+ {
+ var vuePath = AppSettings.GetConfig("gen:vuePath");
+ if (!vuePath.IsEmpty())
+ {
+ dto.VueParentPath = vuePath;
+ }
+ }
+ else
+ {
+ string fullName = Path.Combine(dto.GenCodePath, "vue");
+
+ dto.VueParentPath = fullName;
+ }
+ dto.GenOptions = _option;
+
+ string PKName = "Id";
+ string PKType = "int";
+ ReplaceDto replaceDto = new()
+ {
+ ModelTypeName = dto.GenTable.ClassName,//表名对应C# 实体类名
+ PermissionPrefix = dto.GenTable?.Options?.PermissionPrefix,
+ Author = dto.GenTable.FunctionAuthor,
+ ShowBtnAdd = dto.GenTable.Options.CheckedBtn.Any(f => f == 1),
+ ShowBtnEdit = dto.GenTable.Options.CheckedBtn.Any(f => f == 2),
+ ShowBtnDelete = dto.GenTable.Options.CheckedBtn.Any(f => f == 3),
+ ShowBtnExport = dto.GenTable.Options.CheckedBtn.Any(f => f == 4),
+ ShowBtnView = dto.GenTable.Options.CheckedBtn.Any(f => f == 5),
+ ShowBtnImport = dto.GenTable.Options.CheckedBtn.Any(f => f == 6),
+ ShowBtnAudit = dto.GenTable.Options.CheckedBtn.Any(f => f == 7)
+ };
+
+ //循环表字段信息
+ foreach (GenTableColumn dbFieldInfo in dto.GenTable.Columns.OrderBy(x => x.Sort))
+ {
+ if (dbFieldInfo.IsPk || dbFieldInfo.IsIncrement)
+ {
+ PKName = dbFieldInfo.CsharpField;
+ PKType = dbFieldInfo.CsharpType;
+ }
+ if (dbFieldInfo.HtmlType.Equals(GenConstants.HTML_IMAGE_UPLOAD) || dbFieldInfo.HtmlType.Equals(GenConstants.HTML_FILE_UPLOAD))
+ {
+ replaceDto.UploadFile = 1;
+ }
+ dbFieldInfo.CsharpFieldFl = dbFieldInfo.CsharpField.FirstLowerCase();
+ }
+
+ replaceDto.PKName = PKName;
+ replaceDto.PKType = PKType;
+ replaceDto.FistLowerPk = PKName.FirstLowerCase();
+ InitJntTemplate(dto, replaceDto);
+
+ GenerateModels(replaceDto, dto);
+ GenerateRepository(replaceDto, dto);
+ GenerateService(replaceDto, dto);
+ GenerateControllers(replaceDto, dto);
+ GenerateVue3Views(replaceDto, dto);
+ GenerateVueJs(replaceDto, dto);
+ GenerateSql(replaceDto, dto);
+
+ if (dto.IsPreview) return;
+
+ foreach (var item in dto.GenCodes)
+ {
+ item.Path = Path.Combine(dto.GenCodePath, item.Path);
+ FileHelper.WriteAndSave(item.Path, item.Content);
+ }
+ }
+
+ #region 读取模板
+
+ ///
+ /// 生成实体类Model
+ ///
+ ///
+ /// 替换实体
+ private static void GenerateModels(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+
+
+ string fullPath = Path.Combine(_option.ModelsNamespace, "Models", "Business", _option.SubNamespace, replaceDto.ModelTypeName + ".cs");
+ string fullPathDto = Path.Combine(_option.ModelsNamespace, "Dto", "Business", _option.SubNamespace, $"{replaceDto.ModelTypeName}Dto.cs");
+ string fullPathVo = Path.Combine(_option.ModelsNamespace, "Vo", "Business", _option.SubNamespace, $"{replaceDto.ModelTypeName}Vo.cs");
+
+ var tpl = FileHelper.ReadJtTemplate("TplModel.txt");
+ var tplDto = FileHelper.ReadJtTemplate("TplDto.txt");
+ var tplVo = FileHelper.ReadJtTemplate("TplVo.txt");
+
+ generateDto.GenCodes.Add(new GenCode(1, "Model.cs", fullPath, tpl.Render()));
+ generateDto.GenCodes.Add(new GenCode(2, "Dto.cs", fullPathDto, tplDto.Render()));
+ generateDto.GenCodes.Add(new GenCode(3, "Vo.cs", fullPathVo, tplVo.Render()));
+ }
+
+ ///
+ /// 生成Repository层代码文件
+ ///
+ ///
+ /// 替换实体
+ private static void GenerateRepository(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tpl = FileHelper.ReadJtTemplate("TplRepository.txt");
+ var result = tpl.Render();
+ var fullPath = Path.Combine(_option.RepositoriesNamespace, "Business", _option.SubNamespace, $"{replaceDto.ModelTypeName}Repository.cs");
+
+ generateDto.GenCodes.Add(new GenCode(3, "Repository.cs", fullPath, result));
+ }
+
+ ///
+ /// 生成Service文件
+ ///
+ private static void GenerateService(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tpl = FileHelper.ReadJtTemplate("TplService.txt");
+ var tpl2 = FileHelper.ReadJtTemplate("TplIService.txt");
+ var result = tpl.Render();
+ var result2 = tpl2.Render();
+
+ var fullPath = Path.Combine(_option.ServicesNamespace, "Business", "BusinessService", _option.SubNamespace, $"{replaceDto.ModelTypeName}Service.cs");
+ var fullPath2 = Path.Combine(_option.IServicsNamespace, "Business", "IBusinessService", _option.SubNamespace, $"I{replaceDto.ModelTypeName}Service.cs");
+
+ generateDto.GenCodes.Add(new GenCode(4, "Service.cs", fullPath, result));
+ generateDto.GenCodes.Add(new GenCode(4, "IService.cs", fullPath2, result2));
+ }
+
+ ///
+ /// 生成控制器ApiControllers文件
+ ///
+ private static void GenerateControllers(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tpl = FileHelper.ReadJtTemplate("TplControllers.txt");
+ tpl.Set("QueryCondition", replaceDto.QueryCondition);
+ var result = tpl.Render();
+
+ var fullPath = Path.Combine(_option.ApiControllerNamespace, "Controllers", "Business", _option.SubNamespace, $"{replaceDto.ModelTypeName}Controller.cs");
+ generateDto.GenCodes.Add(new GenCode(5, "Controller.cs", fullPath, result));
+ }
+
+ ///
+ /// 生成Vue页面
+ private static void GenerateVueViews(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ string fileName = string.Empty;
+ switch (generateDto.GenTable.TplCategory)
+ {
+ case "tree":
+ fileName = "TplTreeVue.txt";
+ break;
+ case "crud":
+ fileName = "TplVue.txt";
+ break;
+ case "subNav":
+ fileName = "TplVue.txt";
+ break;
+ case "subNavMore":
+ fileName = "TplVue.txt";
+ break;
+ case "select":
+ fileName = "TplVueSelect.txt";
+ break;
+ default:
+ break;
+ }
+ var tpl = FileHelper.ReadJtTemplate(fileName);
+ tpl.Set("vueQueryFormHtml", replaceDto.VueQueryFormHtml);
+ tpl.Set("VueViewFormContent", replaceDto.VueViewFormHtml);//添加、修改表单
+ tpl.Set("VueViewListContent", replaceDto.VueViewListHtml);//查询 table列
+
+ var result = tpl.Render();
+ var fullPath = Path.Combine("src", "views", generateDto.GenTable.ModuleName.FirstLowerCase(), $"{generateDto.GenTable.BusinessName.FirstUpperCase()}.vue");
+
+ generateDto.GenCodes.Add(new GenCode(6, "index.vue", fullPath, result));
+ }
+
+ ///
+ /// vue3
+ ///
+ ///
+ ///
+ private static void GenerateVue3Views(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ string fileName = generateDto.GenTable.TplCategory switch
+ {
+ "tree" => "TplVueIndex.txt",
+ "crud" => "TplVueIndex.txt",
+ //case "select":
+ // fileName = "TplVueSelect.txt";
+ // break;
+ _ => "Vue.txt",
+ };
+ //fileName = Path.Combine("v3", fileName);
+ var tpl = FileHelper.ReadJtTemplate(fileName);
+ var tplAdd = FileHelper.ReadJtTemplate("Add.txt");
+ var tplEdit = FileHelper.ReadJtTemplate("Edit.txt");
+ var tplDetail = FileHelper.ReadJtTemplate("Detail.txt");
+ var tplUpload = FileHelper.ReadJtTemplate("Upload.txt");
+ //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 Addresult = tplAdd.Render();
+ var Editresult = tplEdit.Render();
+ var Detailresult = tplDetail.Render();
+ var Uploadresult = tplUpload.Render();
+
+
+
+ var fullPath = Path.Combine(generateDto.VueParentPath, "src", "views", "business", _option.SubNamespace, "index.vue");
+ var AddfullPath = Path.Combine(generateDto.VueParentPath, "src", "views", "business", _option.SubNamespace , "components", "AddDialog.vue");
+ var EditfullPath = Path.Combine(generateDto.VueParentPath, "src", "views", "business", _option.SubNamespace , "components", "EditDialog.vue");
+ var DetailfullPath = Path.Combine(generateDto.VueParentPath, "src", "views", "business", _option.SubNamespace , "components", "DetailDialog.vue");
+ if (replaceDto.ShowBtnImport)
+ {
+ var UploadfullPath = Path.Combine(generateDto.VueParentPath, "src", "views", "business", _option.SubNamespace , "components", "UploadDialog.vue");
+ generateDto.GenCodes.Add(new GenCode(16, "UploadDialog.vue", UploadfullPath, Uploadresult));
+
+ }
+ generateDto.GenCodes.Add(new GenCode(16, "index.vue", fullPath, result));
+ generateDto.GenCodes.Add(new GenCode(16, "AddDialog.vue", AddfullPath, Addresult));
+ generateDto.GenCodes.Add(new GenCode(16, "EditDialog.vue", EditfullPath, Editresult));
+ generateDto.GenCodes.Add(new GenCode(16, "DetailDialog.vue", DetailfullPath, Detailresult));
+ }
+ ///
+ /// 生成vue页面api
+ ///
+ ///
+ ///
+ ///
+ public static void GenerateVueJs(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tpl = FileHelper.ReadJtTemplate("TplVueApi.txt");
+ var result = tpl.Render();
+
+ string fileName;
+ if (generateDto.VueVersion == 3)
+ {
+ fileName = generateDto.GenTable.BusinessName.ToLower() + ".js";
+ }
+ else
+ {
+ fileName = generateDto.GenTable.BusinessName.FirstLowerCase() + ".js";
+ }
+ string fullPath = Path.Combine(generateDto.VueParentPath, "src", "api", "business", _option.SubNamespace, fileName);
+
+ generateDto.GenCodes.Add(new GenCode(7, "api.js", fullPath, result));
+
+ }
+
+ ///
+ /// 生成SQL
+ ///
+ ///
+ ///
+ public static void GenerateSql(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var db = DbScoped.SugarScope;
+ //new MySql.Data.MySqlClient.MySqlConnection("server=47.242.159.172;Database=demo;Uid=demo;Pwd=demo;SslMode=none;CharSet=utf8mb4;AllowLoadLocalInfile=true;AllowUserVariables=true;").Open();
+
+ var str = AppSettings.GetConfig("gen:conn");
+
+ SqlSugarClient Db = new SqlSugarClient(new ConnectionConfig()
+ {
+ ConnectionString = str,
+ DbType = DbType.MySqlConnector,
+ IsAutoCloseConnection = true
+ },
+ db =>
+ {
+
+ });
+
+ var tempName = "";
+ switch (generateDto.DbType)
+ {
+ case 8:
+ tempName = "MySqlTemplate";
+ break;
+ case 1:
+ tempName = "SqlTemplate";
+ break;
+ default:
+ break;
+ }
+ var tpl = FileHelper.ReadJtTemplate($"{tempName}.txt");
+ tpl.Set("parentId", generateDto.GenTable?.Options?.ParentMenuId ?? 0);
+ var result = tpl.Render();
+ if (generateDto.GenType == "1")
+ {
+ db.Ado.ExecuteCommand(result);
+ }
+ else
+ {
+ string fullPath = Path.Combine(generateDto.GenCodePath, "sql", generateDto.GenTable.BusinessName + ".sql");
+ generateDto.GenCodes.Add(new GenCode(8, "sql", fullPath, result));
+ }
+ }
+
+ ///
+ /// 生成vue页面查询form
+ ///
+ ///
+ public static string GenerateVueQueryForm()
+ {
+ var tpl = FileHelper.ReadJtTemplate("QueryForm.txt");
+ var result = tpl.Render();
+ return result;
+ }
+ ///
+ /// 生成vue页面table
+ ///
+ ///
+ public static string GenerateVueTableList()
+ {
+ var tpl = FileHelper.ReadJtTemplate("TableList.txt");
+ var result = tpl.Render();
+
+ return result;
+ }
+ ///
+ /// 生成vue表单
+ ///
+ ///
+ public static string GenerateCurdForm()
+ {
+ var tpl = FileHelper.ReadJtTemplate("CurdForm.txt");
+ var result = tpl.Render();
+ return result;
+ }
+ #endregion
+
+ #region 帮助方法
+
+ ///
+ /// 如果有前缀替换将前缀替换成空,替换下划线"_"为空再将首字母大写
+ /// 表名转换成C#类名
+ ///
+ ///
+ ///
+ public static string GetClassName(string tableName)
+ {
+ bool autoRemovePre = AppSettings.GetAppConfig(GenConstants.Gen_autoPre, false);
+ string tablePrefix = AppSettings.GetAppConfig(GenConstants.Gen_tablePrefix);
+
+ if (!string.IsNullOrEmpty(tablePrefix) && autoRemovePre)
+ {
+ string[] prefixList = tablePrefix.Split(",", StringSplitOptions.RemoveEmptyEntries);
+ for (int i = 0; i < prefixList.Length; i++)
+ {
+ if (!string.IsNullOrEmpty(prefixList[i].ToString()))
+ {
+ tableName = tableName.Replace(prefixList[i], "", StringComparison.OrdinalIgnoreCase);
+ }
+ }
+ }
+
+ return tableName.UnderScoreToCamelCase();
+ }
+
+ ///
+ /// 获取前端标签名
+ ///
+ ///
+ ///
+ ///
+ public static string GetLabelName(string columnDescription, string columnName)
+ {
+ return string.IsNullOrEmpty(columnDescription) ? columnName : columnDescription;
+ }
+
+ ///
+ /// 首字母转小写,模板使用(勿删)
+ ///
+ ///
+ ///
+ public static string FirstLowerCase(string str)
+ {
+ try
+ {
+ return string.IsNullOrEmpty(str) ? str : str.Substring(0, 1).ToLower() + str[1..];
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ return "";
+ }
+ }
+
+ ///
+ /// 获取C# 类型
+ ///
+ ///
+ ///
+ public static string GetCSharpDatatype(string sDatatype)
+ {
+ sDatatype = sDatatype.ToLower();
+ string sTempDatatype = sDatatype switch
+ {
+ "int" or "number" or "integer" or "smallint" => "int",
+ "bigint" => "long",
+ "tinyint" => "byte",
+ "numeric" or "real" or "float" => "float",
+ "decimal" or "numer(8,2)" or "numeric" => "decimal",
+ "bit" => "bool",
+ "date" or "datetime" or "datetime2" or "smalldatetime" or "timestamp" => "DateTime",
+ "money" or "smallmoney" => "decimal",
+ _ => "string",
+ };
+ return sTempDatatype;
+ }
+
+ public static bool IsNumber(string tableDataType)
+ {
+ string[] arr = new string[] { "int", "long" };
+ return arr.Any(f => f.Contains(GetCSharpDatatype(tableDataType)));
+ }
+ #endregion
+
+ #region 初始化信息
+
+ ///
+ /// 初始化表信息
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static GenTable InitTable(string dbName, string userName, string tableName, string desc)
+ {
+ GenTable genTable = new()
+ {
+ DbName = dbName,
+ BaseNameSpace = "ARW.",//导入默认命名空间前缀
+ ModuleName = GetClassName(tableName).FirstUpperCase() + "s",//导入默认模块名
+ ClassName = GetClassName(tableName).FirstUpperCase(),
+ BusinessName = GetClassName(tableName).FirstUpperCase(),
+ FunctionAuthor = AppSettings.GetConfig(GenConstants.Gen_author),
+ TableName = tableName,
+ TableComment = desc,
+ FunctionName = desc,
+ Create_by = userName,
+ GenType = "1",
+ GenPath = "",
+ Options = new Options()
+ {
+ SortField = "Update_time",
+ SortType = "Desc",
+ CheckedBtn = new int[] { 1, 2, 3, 5 }
+ }
+ };
+ genTable.Options.PermissionPrefix = $"business:{genTable.ClassName.ToLower()}";//权限
+
+ return genTable;
+ }
+
+ ///
+ /// 初始化列属性字段数据
+ ///
+ ///
+ ///
+ public static List InitGenTableColumn(GenTable genTable, List dbColumnInfos)
+ {
+ List genTableColumns = new();
+ var index = 0;
+ foreach (var column in dbColumnInfos)
+ {
+ index++;
+ genTableColumns.Add(InitColumnField(genTable, column, index));
+ }
+ return genTableColumns;
+ }
+
+ ///
+ /// 初始化表字段数据
+ ///
+ ///
+ ///
+ ///
+ private static GenTableColumn InitColumnField(GenTable genTable, DbColumnInfo column, int index)
+ {
+ GenTableColumn genTableColumn = new()
+ {
+ ColumnName = column.DbColumnName.FirstLowerCase(),
+ ColumnComment = column.ColumnDescription,
+ IsPk = column.IsPrimarykey,
+ ColumnType = column.DataType,
+ TableId = genTable.TableId,
+ TableName = genTable.TableName,
+ CsharpType = GetCSharpDatatype(column.DataType),
+ CsharpField = column.DbColumnName.ConvertToPascal("_"),
+ IsRequired = !column.IsNullable,
+ IsIncrement = column.IsIdentity,
+ Create_by = genTable.Create_by,
+ Create_time = DateTime.Now,
+ IsInsert = !column.IsIdentity || GenConstants.inputDtoNoField.Any(f => f.Contains(column.DbColumnName, StringComparison.OrdinalIgnoreCase)),//非自增字段都需要插入
+ IsInit = GenConstants.inputDtoNoField.Any(f => column.DbColumnName.Contains(f)),
+ IsGuid = column.DbColumnName.Contains("guid"),
+ IsEdit = true,
+ IsQuery = false,
+ HtmlType = GenConstants.HTML_INPUT,
+ Sort = index
+ };
+
+ switch (genTableColumn.CsharpField)
+ {
+ case "CreateBy":
+ genTableColumn.CsharpField = "Create_by";
+ break;
+ case "CreateTime":
+ genTableColumn.CsharpField = "Create_time";
+ break;
+ case "UpdateBy":
+ genTableColumn.CsharpField = "Update_by";
+ break;
+ case "UpdateTime":
+ genTableColumn.CsharpField = "Update_time";
+ break;
+ default:
+ break;
+ }
+
+ if (GenConstants.imageFiled.Any(f => column.DbColumnName.ToLower().Contains(f.ToLower())))
+ {
+ genTableColumn.HtmlType = GenConstants.HTML_IMAGE_UPLOAD;
+ }
+ else if (GenConstants.COLUMNTYPE_TIME.Any(f => genTableColumn.CsharpType.ToLower().Contains(f.ToLower())))
+ {
+ genTableColumn.HtmlType = GenConstants.HTML_DATETIME;
+ }
+ else if (GenConstants.radioFiled.Any(f => column.DbColumnName.EndsWith(f, StringComparison.OrdinalIgnoreCase)) ||
+ GenConstants.radioFiled.Any(f => column.DbColumnName.StartsWith(f, StringComparison.OrdinalIgnoreCase)))
+ {
+ genTableColumn.HtmlType = GenConstants.HTML_RADIO;
+ }
+ else if (GenConstants.selectFiled.Any(f => column.DbColumnName == f) ||
+ GenConstants.selectFiled.Any(f => column.DbColumnName.EndsWith(f, StringComparison.OrdinalIgnoreCase)))
+ {
+ genTableColumn.HtmlType = GenConstants.HTML_SELECT;
+ }
+ else if (column.Length > 500)
+ {
+ genTableColumn.HtmlType = GenConstants.HTML_TEXTAREA;
+ }
+ //编辑字段
+ if (column.IsIdentity || column.IsPrimarykey || GenConstants.COLUMNNAME_NOT_EDIT.Any(f => column.DbColumnName.Contains(f)))
+ {
+ genTableColumn.IsEdit = false;
+ }
+ //列表字段
+ if (!GenConstants.COLUMNNAME_NOT_ARWST.Any(f => column.DbColumnName.Contains(f) && !column.IsPrimarykey))
+ {
+ genTableColumn.IsList = true;
+ }
+ //时间类型初始化between范围查询
+ if (genTableColumn.CsharpType == GenConstants.TYPE_DATE)
+ {
+ genTableColumn.QueryType = "BETWEEN";
+ }
+
+ return genTableColumn;
+ }
+
+ #endregion
+
+ ///
+ /// 初始化Jnt模板
+ ///
+ ///
+ ///
+ private static void InitJntTemplate(GenerateDto dto, ReplaceDto replaceDto)
+ {
+ Engine.Current.Clean();
+ dto.GenTable.Columns = dto.GenTable.Columns.OrderBy(x => x.Sort).ToList();
+ bool showCustomInput = dto.GenTable.Columns.Any(f => f.HtmlType.Equals(GenConstants.HTML_CUSTOM_INPUT, StringComparison.OrdinalIgnoreCase));
+ //jnt模板引擎全局变量
+ Engine.Configure((options) =>
+ {
+ options.TagPrefix = "${";
+ options.TagSuffix = "}";
+ options.TagFlag = '$';
+ options.OutMode = OutMode.Auto;
+ //options.DisableeLogogram = true;//禁用简写
+ options.Data.Set("refs", "$");//特殊标签替换
+ options.Data.Set("t", "$");//特殊标签替换
+ options.Data.Set("modal", "$");//特殊标签替换
+ options.Data.Set("index", "$");//特殊标签替换
+ options.Data.Set("confirm", "$");//特殊标签替换
+ options.Data.Set("nextTick", "$");
+ options.Data.Set("replaceDto", replaceDto);
+ options.Data.Set("options", dto.GenOptions);
+ options.Data.Set("genTable", dto.GenTable);
+ options.Data.Set("btns", dto.CheckedBtn);
+ options.Data.Set("showCustomInput", showCustomInput);
+ options.Data.Set("tool", new CodeGeneratorTool());
+ options.Data.Set("codeTool", new CodeGenerateTemplate());
+ options.EnableCache = true;
+ //...其它数据
+ });
+ }
+
+ #region 模板用
+ ///
+ /// 模板用
+ ///
+ ///
+ ///
+ public static bool CheckInputDtoNoField(string str)
+ {
+ return GenConstants.inputDtoNoField.Any(f => f.Contains(str, StringComparison.OrdinalIgnoreCase));
+ }
+ public static bool CheckTree(GenTable genTable, string csharpField)
+ {
+ return (genTable.TplCategory.Equals("tree", StringComparison.OrdinalIgnoreCase) && genTable?.Options?.TreeParentCode != null && csharpField.Equals(genTable?.Options?.TreeParentCode));
+ }
+ #endregion
+
+ #endregion
+
+
+
+ #region Api接口生成
+
+ ///
+ /// 代码生成器入口方法(Api)
+ ///
+ ///
+ public static void GenerateApi(GenerateDto dto)
+ {
+ _option.BaseNamespace = dto.GenTable.BaseNameSpace;
+ _option.SubNamespace = dto.GenTable.ModuleName.FirstUpperCase();
+ _option.DtosNamespace = _option.BaseNamespace + "Model";
+ _option.ModelsNamespace = _option.BaseNamespace + "Model";
+ _option.RepositoriesNamespace = _option.BaseNamespace + "Repository";
+ _option.IRepositoriesNamespace = _option.BaseNamespace + "Repository";
+ _option.IServicsNamespace = _option.BaseNamespace + "Service";
+ _option.ServicesNamespace = _option.BaseNamespace + "Service";
+ _option.ApiControllerNamespace = _option.BaseNamespace + "WebApi";
+
+ if (dto.GenTable.ModuleName.Contains('/')) dto.GenTable.ModuleName = dto.GenTable.ModuleName.Replace('/', '.');
+
+ if (dto.GenType == "1")
+ {
+ var vuePath = AppSettings.GetConfig("gen:vuePath");
+ if (!vuePath.IsEmpty())
+ {
+ dto.VueParentPath = vuePath;
+ }
+ }
+ else
+ {
+ string fullName = Path.Combine(dto.GenCodePath, "vue");
+
+ dto.VueParentPath = fullName;
+ }
+ dto.GenOptions = _option;
+
+ string PKName = "Id";
+ string PKType = "int";
+ ReplaceDto replaceDto = new()
+ {
+ ModelTypeName = dto.GenTable.ClassName,//表名对应C# 实体类名
+ PermissionPrefix = dto.GenTable?.Options?.PermissionPrefix,
+ Author = dto.GenTable.FunctionAuthor,
+ ShowBtnAdd = dto.GenTable.Options.CheckedBtn.Any(f => f == 1),
+ ShowBtnEdit = dto.GenTable.Options.CheckedBtn.Any(f => f == 2),
+ ShowBtnDelete = dto.GenTable.Options.CheckedBtn.Any(f => f == 3),
+ ShowBtnExport = dto.GenTable.Options.CheckedBtn.Any(f => f == 4),
+ ShowBtnView = dto.GenTable.Options.CheckedBtn.Any(f => f == 5),
+ ShowBtnImport = dto.GenTable.Options.CheckedBtn.Any(f => f == 6)
+ };
+
+ //循环表字段信息
+ foreach (GenTableColumn dbFieldInfo in dto.GenTable.Columns.OrderBy(x => x.Sort))
+ {
+ if (dbFieldInfo.IsPk || dbFieldInfo.IsIncrement)
+ {
+ PKName = dbFieldInfo.CsharpField;
+ PKType = dbFieldInfo.CsharpType;
+ }
+ if (dbFieldInfo.HtmlType.Equals(GenConstants.HTML_IMAGE_UPLOAD) || dbFieldInfo.HtmlType.Equals(GenConstants.HTML_FILE_UPLOAD))
+ {
+ replaceDto.UploadFile = 1;
+ }
+ dbFieldInfo.CsharpFieldFl = dbFieldInfo.CsharpField.FirstLowerCase();
+ }
+
+ replaceDto.PKName = PKName;
+ replaceDto.PKType = PKType;
+ replaceDto.FistLowerPk = PKName.FirstLowerCase();
+ InitJntTemplate(dto, replaceDto);
+
+ GenerateModelsApi(replaceDto, dto);
+ GenerateServiceApi(replaceDto, dto);
+ GenerateControllersApi(replaceDto, dto);
+
+ if (dto.IsPreview) return;
+
+ foreach (var item in dto.GenCodes)
+ {
+ item.Path = Path.Combine(dto.GenCodePath, item.Path);
+ FileHelper.WriteAndSave(item.Path, item.Content);
+ }
+ }
+
+
+ ///
+ /// 生成实体类Model(Api)
+ ///
+ ///
+ /// 替换实体
+ private static void GenerateModelsApi(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tplDto = FileHelper.ReadJtTemplate("TplDtoApi.txt");
+ var tplVo = FileHelper.ReadJtTemplate("TplVoApi.txt");
+
+ string fullPathDto = Path.Combine(_option.ModelsNamespace, "Dto", "Api", _option.SubNamespace, $"{replaceDto.ModelTypeName}ApiDto.cs");
+ string fullPathVo = Path.Combine(_option.ModelsNamespace, "Vo", "Api", _option.SubNamespace, $"{replaceDto.ModelTypeName}ApiVo.cs");
+
+ generateDto.GenCodes.Add(new GenCode(2, "DtoApi.cs", fullPathDto, tplDto.Render()));
+ generateDto.GenCodes.Add(new GenCode(3, "VoApi.cs", fullPathVo, tplVo.Render()));
+ }
+
+
+ ///
+ /// 生成Service文件(Api)
+ ///
+ private static void GenerateServiceApi(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tpl = FileHelper.ReadJtTemplate("TplServiceApi.txt");
+ var tpl2 = FileHelper.ReadJtTemplate("TplIServiceApi.txt");
+ var result = tpl.Render();
+ var result2 = tpl2.Render();
+
+ var fullPath = Path.Combine(_option.ServicesNamespace, "Api", "BusinessService", _option.SubNamespace, $"{replaceDto.ModelTypeName}ServiceApi.cs");
+ var fullPath2 = Path.Combine(_option.IServicsNamespace, "Api", "IBusinessService", _option.SubNamespace, $"I{replaceDto.ModelTypeName}ServiceApi.cs");
+
+ generateDto.GenCodes.Add(new GenCode(4, "ServiceApi.cs", fullPath, result));
+ generateDto.GenCodes.Add(new GenCode(4, "IServiceApi.cs", fullPath2, result2));
+ }
+
+
+ ///
+ /// 生成控制器ApiControllers文件(Api)
+ ///
+ private static void GenerateControllersApi(ReplaceDto replaceDto, GenerateDto generateDto)
+ {
+ var tpl = FileHelper.ReadJtTemplate("TplControllersApi.txt");
+ tpl.Set("QueryCondition", replaceDto.QueryCondition);
+ var result = tpl.Render();
+
+ var fullPath = Path.Combine(_option.ApiControllerNamespace, "Controllers", "Api", _option.SubNamespace, $"{replaceDto.ModelTypeName}ApiController.cs");
+ generateDto.GenCodes.Add(new GenCode(5, "Controller.cs", fullPath, result));
+ }
+
+ #endregion
+
+
+ }
+}
diff --git a/ARW.CodeGenerator/DbProvider.cs b/ARW.CodeGenerator/DbProvider.cs
new file mode 100644
index 0000000..2ebf84a
--- /dev/null
+++ b/ARW.CodeGenerator/DbProvider.cs
@@ -0,0 +1,70 @@
+using Infrastructure;
+using Infrastructure.Extensions;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace ARW.CodeGenerator
+{
+ ///
+ /// 代码生成数据库连接
+ ///
+ public class DbProvider
+ {
+ protected static SqlSugarClient CodeDb;
+
+ ///
+ /// 获取动态连接字符串
+ ///
+ /// 数据库名
+ ///
+ public SqlSugarClient GetSugarDbContext(string dbName = "")
+ {
+ string connStr = AppSettings.GetConfig(GenConstants.Gen_conn);
+ int dbType = AppSettings.GetAppConfig(GenConstants.Gen_conn_dbType, 0);
+
+ if (!string.IsNullOrEmpty(dbName))
+ {
+ string replaceStr = GetValue(connStr, "Database=", ";");
+ string replaceStr2 = GetValue(connStr, "Initial Catalog=", ";");
+ if (replaceStr.IsNotEmpty())
+ {
+ connStr = connStr.Replace(replaceStr, dbName, StringComparison.OrdinalIgnoreCase);
+ }
+ if (replaceStr2.IsNotEmpty())
+ {
+ connStr = connStr.Replace(replaceStr2, dbName, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+ var db = new SqlSugarClient(new List()
+ {
+ new ConnectionConfig(){
+ ConnectionString = connStr,
+ DbType = (DbType)dbType,
+ IsAutoCloseConnection = true,//开启自动释放模式和EF原理一样
+ InitKeyType = InitKeyType.Attribute,//从特性读取主键和自增列信息
+ },
+ });
+
+ CodeDb = db;
+ return db;
+ }
+
+ ///
+ /// 获得字符串中开始和结束字符串中间得值
+ ///
+ /// 字符串
+ /// 开始
+ /// 结束
+ ///
+ public static string GetValue(string str, string s, string e)
+ {
+ Regex rg = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
+ return rg.Match(str).Value;
+ }
+ }
+}
diff --git a/ARW.CodeGenerator/FileHelper.cs b/ARW.CodeGenerator/FileHelper.cs
new file mode 100644
index 0000000..d6ca974
--- /dev/null
+++ b/ARW.CodeGenerator/FileHelper.cs
@@ -0,0 +1,190 @@
+using JinianNet.JNTemplate;
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Runtime.InteropServices;
+
+namespace ARW.CodeGenerator
+{
+ public class FileHelper
+ {
+ ///
+ /// 创建文件夹
+ ///
+ ///
+ ///
+ public static bool CreateDirectory(string path)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ path = path.Replace("\\", "/").Replace("//", "/");
+ }
+ try
+ {
+ if (!Directory.Exists(path))
+ {
+ DirectoryInfo info = Directory.CreateDirectory(path);
+ Console.WriteLine("不存在创建文件夹" + info);
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"创建文件夹出错了,{ex.Message}");
+ return false;
+ }
+ return true;
+ }
+
+ ///
+ /// 写文件
+ ///
+ /// 完整路径带扩展名的
+ ///
+ public static void WriteAndSave(string path, string content)
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ {
+ path = path.Replace("\\", "/").Replace("//", "/");
+ }
+ if (!Directory.Exists(Path.GetDirectoryName(path)))
+ {
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+ }
+ Console.WriteLine("写入文件:" + path);
+ try
+ {
+ //实例化一个文件流--->与写入文件相关联
+ using var fs = new FileStream(path, FileMode.Create, FileAccess.Write);
+ //实例化一个StreamWriter-->与fs相关联
+ using var sw = new StreamWriter(fs);
+ //开始写入
+ sw.Write(content);
+ //清空缓冲区
+ sw.Flush();
+ //关闭流
+ sw.Close();
+ fs.Close();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("写入文件出错了:" + ex.Message);
+ }
+ }
+
+
+ ///
+ /// 从代码模板中读取内容
+ ///
+ /// 模板名称,应包括文件扩展名称。比如:template.txt
+ ///
+ public static string ReadTemplate(string tplName)
+ {
+ string path = Environment.CurrentDirectory;
+ string fullName = Path.Combine(path, "wwwroot", "CodeGenTemplate", tplName);
+
+ Console.WriteLine("开始读取模板=" + fullName);
+ string temp = fullName;
+ string str = "";
+ if (!File.Exists(temp))
+ {
+ return str;
+ }
+ StreamReader sr = null;
+ try
+ {
+ sr = new StreamReader(temp);
+ str = sr.ReadToEnd(); // 读取文件
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"读取模板出错了{ex.Message}");
+ }
+ sr?.Close();
+ sr?.Dispose();
+ return str;
+ }
+
+ public static ITemplate ReadJtTemplate(string tplName)
+ {
+ string path = Environment.CurrentDirectory;
+ string fullName = Path.Combine(path, "wwwroot", "CodeGenTemplate", tplName);
+ if (File.Exists(fullName))
+ {
+ return Engine.LoadTemplate(fullName);
+ }
+ return null;
+ }
+
+ ///
+ /// 压缩代码
+ ///
+ ///
+ ///
+ /// 压缩后的文件名
+ ///
+ public static bool ZipGenCode(string zipPath, string genCodePath,string zipFileName)
+ {
+ if (string.IsNullOrEmpty(zipPath)) return false;
+ try
+ {
+ CreateDirectory(genCodePath);
+ string zipFileFullName = Path.Combine(zipPath, zipFileName);
+ if (File.Exists(zipFileFullName))
+ {
+ File.Delete(zipFileFullName);
+ }
+
+ ZipFile.CreateFromDirectory(genCodePath, zipFileFullName);
+ DeleteDirectory(genCodePath);
+
+ return true;
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("压缩文件出错。" + ex.Message);
+ return false;
+ }
+ }
+
+ ///
+ /// 删除指定目录下的所有文件及文件夹(保留目录)
+ ///
+ /// 文件目录
+ public static void DeleteDirectory(string file)
+ {
+ try
+ {
+ //判断文件夹是否还存在
+ if (Directory.Exists(file))
+ {
+ DirectoryInfo fileInfo = new DirectoryInfo(file);
+ //去除文件夹的只读属性
+ fileInfo.Attributes = FileAttributes.Normal & FileAttributes.Directory;
+ foreach (string f in Directory.GetFileSystemEntries(file))
+ {
+ if (File.Exists(f))
+ {
+ //去除文件的只读属性
+ File.SetAttributes(file, FileAttributes.Normal);
+ //如果有子文件删除文件
+ File.Delete(f);
+ }
+ else
+ {
+ //循环递归删除子文件夹
+ DeleteDirectory(f);
+ }
+ }
+ //删除空文件夹
+ Directory.Delete(file);
+ }
+
+ }
+ catch (Exception ex) // 异常处理
+ {
+ Console.WriteLine("代码生成异常" + ex.Message);
+ }
+ }
+
+ }
+}
diff --git a/ARW.CodeGenerator/GenConstants.cs b/ARW.CodeGenerator/GenConstants.cs
new file mode 100644
index 0000000..87362b0
--- /dev/null
+++ b/ARW.CodeGenerator/GenConstants.cs
@@ -0,0 +1,144 @@
+
+
+namespace ARW.CodeGenerator
+{
+ ///
+ /// 代码生成常量
+ ///
+ public class GenConstants
+ {
+ public static string Gen_conn = "gen:conn";
+ public static string Gen_conn_dbType = "gen:dbType";
+ public static string Gen_author = "gen:author";
+ public static string Gen_autoPre = "gen:autoPre";
+ public static string Gen_tablePrefix = "gen:tablePrefix";
+
+ ///
+ /// InputDto输入实体是不包含字段
+ ///
+ public static readonly string[] inputDtoNoField = new string[] { "IsDelete", "create_time", "update_time", "create_by", "update_by" };
+ ///
+ /// 图片字段
+ ///
+ public static readonly string[] imageFiled = new string[] { "icon", "img", "image", "url", "pic", "photo", "avatar" };
+ ///
+ /// 下拉框字段
+ ///
+ public static readonly string[] selectFiled = new string[] { "status", "type", "state", "sex", "gender" };
+ ///
+ /// 单选按钮字段
+ ///
+ public static readonly string[] radioFiled = new string[] { "status", "state", "is"};
+
+
+ /** 单表(增删改查) */
+ public static string TPL_CRUD = "crud";
+
+ /** 树表(增删改查) */
+ public static string TPL_TREE = "tree";
+
+ /** 主子表(增删改查) */
+ public static string TPL_SUB = "sub";
+
+ /** 树编码字段 */
+ public static string TREE_CODE = "treeCode";
+
+ /** 树父编码字段 */
+ public static string TREE_PARENT_CODE = "treeParentCode";
+
+ /** 树名称字段 */
+ public static string TREE_NAME = "treeName";
+
+ /** 上级菜单ID字段 */
+ public static string PARENT_MENU_ID = "parentMenuId";
+
+ /** 上级菜单名称字段 */
+ public static string PARENT_MENU_NAME = "parentMenuName";
+
+ /** 数据库字符串类型 */
+ public static string[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
+
+ /** 数据库文本类型 */
+ public static string[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
+
+ /** 数据库时间类型 */
+ public static string[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
+
+ /** 页面不需要编辑字段 */
+ public static string[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "delFlag" };
+
+ /** 页面不需要显示的列表字段 */
+ public static string[] COLUMNNAME_NOT_ARWST = { "create_by", "create_time", "delFlag", "update_by",
+ "update_time" , "password"};
+
+ /** 页面不需要查询字段 */
+ public static string[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "delFlag", "update_by",
+ "update_time", "remark" };
+
+ /** Entity基类字段 */
+ public static string[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
+
+ /** Tree基类字段 */
+ public static string[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
+
+ /** 文本框 */
+ public static string HTML_INPUT = "input";
+ /** 数字框 */
+ public static string HTML_INPUT_NUMBER = "inputNumber";
+
+ /** 文本域 */
+ public static string HTML_TEXTAREA = "textarea";
+
+ /** 下拉框 */
+ public static string HTML_SELECT = "select";
+
+ /** 单选框 */
+ public static string HTML_RADIO = "radio";
+
+ /** 复选框 */
+ public static string HTML_CHECKBOX = "checkbox";
+
+ /** 日期控件 */
+ public static string HTML_DATETIME = "datetime";
+
+ /** 图片上传控件 */
+ public static string HTML_IMAGE_UPLOAD = "imageUpload";
+
+ /** 文件上传控件 */
+ public static string HTML_FILE_UPLOAD = "fileUpload";
+
+ /** 富文本控件 */
+ public static string HTML_EDITOR = "editor";
+ // 自定义排序
+ public static string HTML_SORT = "sort";
+ ///
+ /// 自定义输入框
+ ///
+ public static string HTML_CUSTOM_INPUT = "customInput";
+ //颜色选择器
+ public static string HTML_COLORPICKER = "colorPicker";
+ //switch开关
+ public static string HTML_SWITCH { get; set; }
+
+ /** 字符串类型 */
+ public static string TYPE_STRING = "string";
+
+ /** 整型 */
+ public static string TYPE_INT = "int";
+
+ /** 长整型 */
+ public static string TYPE_LONG = "long";
+
+ /** 浮点型 */
+ public static string TYPE_DOUBLE = "Double";
+
+ /** 时间类型 */
+ public static string TYPE_DATE = "DateTime";
+
+ /** 模糊查询 */
+ public static string QUERY_ARWKE = "ARWKE";
+
+ /** 需要 */
+ public static string REQUIRE = "1";
+ }
+}
\ No newline at end of file
diff --git a/ARW.CodeGenerator/Model/GenerateDto.cs b/ARW.CodeGenerator/Model/GenerateDto.cs
new file mode 100644
index 0000000..029f8e7
--- /dev/null
+++ b/ARW.CodeGenerator/Model/GenerateDto.cs
@@ -0,0 +1,71 @@
+using System.Collections.Generic;
+using ARW.Model.System.Generate;
+
+namespace ARW.CodeGenerator.Model
+{
+ public class GenerateDto
+ {
+ ///
+ /// vue版本
+ ///
+ public int VueVersion { get; set; }
+ public long TableId { get; set; }
+ ///
+ /// 是否预览代码
+ ///
+ public bool IsPreview { get; set; }
+ ///
+ /// 生成代码的数据库类型 0、mysql 1、sqlserver
+ ///
+ public int DbType { get; set; }
+ ///
+ /// 生成的按钮功能
+ ///
+ public int[] CheckedBtn { get; set; } = System.Array.Empty();
+ public GenTable GenTable { get; set; }
+ public CodeGenerateOption GenOptions { get; set; }
+ #region 存储路径
+ ///
+ /// 代码模板预览存储路径存放
+ ///
+ public List GenCodes { get; set; } = new List();
+ ///
+ /// 代码生成路径
+ ///
+ public string GenCodePath { get; set; } = string.Empty;
+ ///
+ /// 代码生成压缩包路径
+ ///
+ public string ZipPath { get; set; }
+ ///
+ /// 代码生成压缩包名称
+ ///
+ public string ZipFileName { get; set; }
+ ///
+ /// 生成代码方式(0zip压缩包 1自定义路径)
+ ///
+ public string GenType { get; set; }
+ public string GenPath { get; set; } = "";
+ ///
+ /// vue代码路径
+ ///
+ public string VueParentPath { get; set; }
+ #endregion
+ }
+
+ public class GenCode
+ {
+ public int Type { get; set; }
+ public string Title { get; set; }
+ public string Path { get; set; }
+ public string Content { get; set; }
+
+ public GenCode(int type, string title, string path, string content)
+ {
+ Type = type;
+ Title = title;
+ Path = path;
+ Content = content;
+ }
+ }
+}
diff --git a/ARW.CodeGenerator/Model/ReplaceDto.cs b/ARW.CodeGenerator/Model/ReplaceDto.cs
new file mode 100644
index 0000000..9d5479c
--- /dev/null
+++ b/ARW.CodeGenerator/Model/ReplaceDto.cs
@@ -0,0 +1,61 @@
+using System;
+
+namespace ARW.CodeGenerator.Model
+{
+ public class ReplaceDto
+ {
+ ///
+ /// 主键字段
+ ///
+ public string PKName { get; set; }
+ ///
+ /// 首字母小写主键
+ ///
+ public string FistLowerPk{ get; set; }
+ ///
+ /// 主键类型
+ ///
+ public string PKType { get; set; }
+ ///
+ /// 控制器权限
+ ///
+ public string PermissionPrefix { get; set; }
+ ///
+ /// C#类名
+ ///
+ public string ModelTypeName { get; set; }
+ //vue、api
+ //public string VueViewFormResetHtml { get; set; }
+ ///
+ /// 前端列表查询html
+ ///
+ public string VueViewListHtml { get; set; }
+ ///
+ /// 前端添加、编辑表格html
+ ///
+ public string VueViewFormHtml { get; set; }
+ ///
+ /// 前端搜索表单html
+ ///
+ public string VueQueryFormHtml { get; set; }
+
+ ///
+ /// 查询条件
+ ///
+ public string QueryCondition { get; set; } = "";
+ public bool ShowBtnExport { get; set; }
+ public bool ShowBtnImport { get; set; }
+ public bool ShowBtnAudit { get; set; }
+ public bool ShowBtnAdd { get; set; }
+ public bool ShowBtnEdit { get; set; }
+ public bool ShowBtnDelete { get; set; }
+ public bool ShowBtnView { get; set; }
+ ///
+ /// 上传URL data
+ ///
+ //public string VueUploadUrl { get; set; }
+ public int UploadFile { get; set; } = 0;
+ public string Author { get; set; }
+ public string AddTime { get; set; } = DateTime.Now.ToString("yyyy-MM-dd");
+ }
+}
diff --git a/ARW.CodeGenerator/Service/CodeGeneraterService.cs b/ARW.CodeGenerator/Service/CodeGeneraterService.cs
new file mode 100644
index 0000000..c820795
--- /dev/null
+++ b/ARW.CodeGenerator/Service/CodeGeneraterService.cs
@@ -0,0 +1,68 @@
+using SqlSugar;
+using System.Collections.Generic;
+using System.Linq;
+using ARW.Model;
+
+namespace ARW.CodeGenerator.Service
+{
+ public class CodeGeneraterService : DbProvider
+ {
+ ///
+ /// 获取所有数据库名
+ ///
+ ///
+ public List GetAllDataBases()
+ {
+ var db = GetSugarDbContext();
+ var templist = db.DbMaintenance.GetDataBaseList(db);
+
+ return templist;
+ }
+
+ ///
+ /// 获取所有表
+ ///
+ ///
+ ///
+ ///
+ ///
+ public List GetAllTables(string dbName, string tableName, PagerInfo pager)
+ {
+ var tableList = GetSugarDbContext(dbName).DbMaintenance.GetTableInfoList(true);
+ if (!string.IsNullOrEmpty(tableName))
+ {
+ tableList = tableList.Where(f => f.Name.ToLower().Contains(tableName.ToLower())).ToList();
+ }
+ //tableList = tableList.Where(f => !new string[] { "gen", "sys_" }.Contains(f.Name)).ToList();
+ pager.TotalNum = tableList.Count;
+ return tableList.Skip(pager.PageSize * (pager.PageNum - 1)).Take(pager.PageSize).OrderBy(f => f.Name).ToList();
+ }
+
+ ///
+ /// 获取单表数据
+ ///
+ ///
+ ///
+ ///
+ public DbTableInfo GetTableInfo(string dbName, string tableName)
+ {
+ var tableList = GetSugarDbContext(dbName).DbMaintenance.GetTableInfoList(true);
+ if (!string.IsNullOrEmpty(tableName))
+ {
+ return tableList.Where(f => f.Name.Equals(tableName, System.StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
+ }
+
+ return null;
+ }
+ ///
+ /// 获取列信息
+ ///
+ ///
+ ///
+ ///
+ public List GetColumnInfo(string dbName, string tableName)
+ {
+ return GetSugarDbContext(dbName).DbMaintenance.GetColumnInfosByTableName(tableName, true);
+ }
+ }
+}
diff --git a/ARW.Common/ARW.Common.csproj b/ARW.Common/ARW.Common.csproj
new file mode 100644
index 0000000..e773da7
--- /dev/null
+++ b/ARW.Common/ARW.Common.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net6.0
+ ARW.Common
+ ARW.Common
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ARW.Common/AliyunMsgHelper.cs b/ARW.Common/AliyunMsgHelper.cs
new file mode 100644
index 0000000..7b4b863
--- /dev/null
+++ b/ARW.Common/AliyunMsgHelper.cs
@@ -0,0 +1,65 @@
+using Aliyun.OSS.Common;
+using Aliyun.OSS;
+using Org.BouncyCastle.Asn1.Ocsp;
+using System;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Aliyun.Acs.Core.Exceptions;
+using Aliyun.Acs.Core.Http;
+using Aliyun.Acs.Core.Profile;
+using Aliyun.Acs.Core;
+using ClientException = Aliyun.Acs.Core.Exceptions.ClientException;
+using Infrastructure;
+using System.Collections.Generic;
+
+namespace ARW.Common
+{
+ public class AliyunMsgHelper
+ {
+
+ public static void SendMsgCode(string phone)
+ {
+ var accessKeyId = AppSettings.GetConfig("AARWYUN_MSG:accessKeyId");
+ var accessSecret = AppSettings.GetConfig("AARWYUN_MSG:accessSecret");
+ var signName = AppSettings.GetConfig("AARWYUN_MSG:signName");
+ var templateCode = AppSettings.GetConfig("AARWYUN_MSG:templateCode");
+
+ /*这里的*"cn-hangzhou":不需要更改, "":就是上面要求记录到本地的accessKeyId, "::就是上面要求记录到本地的accessSecret"*/
+ IClientProfile profile = DefaultProfile.GetProfile("cn-hongkong", accessKeyId, accessSecret);
+ DefaultAcsClient client = new DefaultAcsClient(profile);
+ CommonRequest request = new CommonRequest();
+ request.Method = MethodType.POST;
+ request.Domain = "dysmsapi.aliyuncs.com";
+ request.Version = "2017-05-25";
+ request.Action = "SendSms";
+ // request.Protocol = ProtocolType.HTTP;1
+
+ request.AddQueryParameters("PhoneNumbers", phone);
+ request.AddQueryParameters("SignName", signName);
+ request.AddQueryParameters("TemplateCode", templateCode);
+
+ Dictionary pairs = new Dictionary();
+ pairs.Add("code", new Random().Next(100000, 1000000).ToString());
+ string json = Newtonsoft.Json.JsonConvert.SerializeObject(pairs);
+ request.AddQueryParameters("TemplateParam", json);
+
+ try
+ {
+ CommonResponse response = client.GetCommonResponse(request);
+ var status = response.HttpResponse;
+ }
+ catch (ServerException e)
+ {
+ Console.WriteLine(e);
+ }
+ catch (ClientException e)
+ {
+ Console.WriteLine(e);
+ }
+
+ }
+ }
+
+}
+
diff --git a/ARW.Common/AliyunOssHelper.cs b/ARW.Common/AliyunOssHelper.cs
new file mode 100644
index 0000000..9d774aa
--- /dev/null
+++ b/ARW.Common/AliyunOssHelper.cs
@@ -0,0 +1,67 @@
+using Aliyun.OSS;
+using Aliyun.OSS.Common;
+using Infrastructure;
+using System;
+using System.IO;
+
+namespace ARW.Common
+{
+ public class AliyunOssHelper
+ {
+ static string accessKeyId = AppSettings.GetConfig("AARWYUN_OSS:KEY");
+ static string accessKeySecret = AppSettings.GetConfig("AARWYUN_OSS:SECRET");
+ static string endpoint = AppSettings.GetConfig("AARWYUN_OSS:REGIONID");
+ static string bucketName1 = AppSettings.GetConfig("AARWYUN_OSS:bucketName");
+
+ ///
+ /// 上传到阿里云
+ ///
+ ///
+ /// 存储路径 eg: upload/2020/01/01/xxx.png
+ /// 存储桶 如果为空默认取配置文件
+ public static System.Net.HttpStatusCode PutObjectFromFile(Stream filestreams, string dirPath, string bucketName = "")
+ {
+ OssClient client = new(endpoint, accessKeyId, accessKeySecret);
+ if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; }
+ try
+ {
+ dirPath = dirPath.Replace("\\", "/");
+ PutObjectResult putObjectResult = client.PutObject(bucketName, dirPath, filestreams);
+ // Console.WriteLine("Put object:{0} succeeded", directory);
+
+ return putObjectResult.HttpStatusCode;
+ }
+ catch (OssException ex)
+ {
+ Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
+ ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine("Failed with error info: {0}", ex.Message);
+ }
+ return System.Net.HttpStatusCode.BadRequest;
+ }
+
+ ///
+ /// 删除资源
+ ///
+ ///
+ ///
+ ///
+ public static System.Net.HttpStatusCode DeleteFile(string dirPath, string bucketName = "")
+ {
+ if (string.IsNullOrEmpty(bucketName)) { bucketName = bucketName1; }
+ try
+ {
+ OssClient client = new(endpoint, accessKeyId, accessKeySecret);
+ DeleteObjectResult putObjectResult = client.DeleteObject(bucketName, dirPath);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ }
+ return System.Net.HttpStatusCode.BadRequest;
+ }
+ }
+}
diff --git a/ARW.Common/Cache/CacheHelper.cs b/ARW.Common/Cache/CacheHelper.cs
new file mode 100644
index 0000000..8efe630
--- /dev/null
+++ b/ARW.Common/Cache/CacheHelper.cs
@@ -0,0 +1,111 @@
+using Microsoft.Extensions.Caching.Memory;
+using System;
+
+namespace ARW.Common
+{
+ public class CacheHelper
+ {
+ public static MemoryCache Cache { get; set; }
+ static CacheHelper()
+ {
+ Cache = new MemoryCache(new MemoryCacheOptions
+ {
+ //SizeLimit = 1024
+ });
+ }
+
+ ///
+ /// 获取缓存
+ ///
+ ///
+ ///
+ ///
+ public static T GetCache(string key) where T : class
+ {
+ if (key == null)
+ throw new ArgumentNullException(nameof(key));
+ //return Cache.Get(key) as T; //或者
+ return Cache.Get(key);
+ }
+
+ ///
+ /// 获取缓存
+ ///
+ ///
+ ///
+ public static object GetCache(string CacheKey)
+ {
+ return Cache.Get(CacheKey);
+ }
+
+ public static object Get(string CacheKey)
+ {
+ return Cache.Get(CacheKey);
+ }
+
+ ///
+ /// 设置缓存,永久缓存
+ ///
+ /// key
+ /// 值
+ public static object SetCache(string CacheKey, object objObject)
+ {
+ return Cache.Set(CacheKey, objObject);
+ }
+
+ ///
+ /// 设置缓存
+ ///
+ /// key
+ /// 值
+ /// 过期时间(分钟)
+ public static object SetCache(string CacheKey, object objObject, int Timeout)
+ {
+ return Cache.Set(CacheKey, objObject, DateTime.Now.AddMinutes(Timeout));
+ }
+
+ ///
+ /// 设置缓存(秒)
+ ///
+ /// key
+ /// 值
+ /// 过期时间(秒)
+ public static void SetCaches(string CacheKey, object objObject, int Timeout)
+ {
+ Cache.Set(CacheKey, objObject, DateTime.Now.AddSeconds(Timeout));
+ }
+
+ ///
+ /// 设置缓存
+ ///
+ /// key
+ /// 值
+ /// 过期时间
+ /// 过期时间间隔
+ public static object SetCache(string CacheKey, object objObject, DateTime absoluteExpiration, TimeSpan slidingExpiration)
+ {
+ return Cache.Set(CacheKey, objObject, absoluteExpiration);
+ }
+
+ ///
+ /// 设定绝对的过期时间
+ ///
+ ///
+ ///
+ /// 超过多少秒后过期
+ public static void SetCacheDateTime(string CacheKey, object objObject, long Seconds)
+ {
+ Cache.Set(CacheKey, objObject, DateTime.Now.AddSeconds(Seconds));
+ }
+
+ ///
+ /// 删除缓存
+ ///
+ /// key
+ public static void Remove(string key)
+ {
+ Cache.Remove(key);
+ }
+ }
+}
+
diff --git a/ARW.Common/Cache/RedisServer.cs b/ARW.Common/Cache/RedisServer.cs
new file mode 100644
index 0000000..ce58b10
--- /dev/null
+++ b/ARW.Common/Cache/RedisServer.cs
@@ -0,0 +1,17 @@
+using CSRedis;
+using Infrastructure;
+
+namespace ARW.Common.Cache
+{
+ public class RedisServer
+ {
+ public static CSRedisClient Cache;
+ public static CSRedisClient Session;
+
+ public static void Initalize()
+ {
+ Cache = new CSRedisClient(AppSettings.GetConfig("RedisServer:Cache"));
+ Session = new CSRedisClient(AppSettings.GetConfig("RedisServer:Session"));
+ }
+ }
+}
diff --git a/ARW.Common/Common.cs b/ARW.Common/Common.cs
new file mode 100644
index 0000000..b2fb4d7
--- /dev/null
+++ b/ARW.Common/Common.cs
@@ -0,0 +1,415 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Text.RegularExpressions; //引用正则表达式
+
+namespace ARW.Common
+{
+ ///
+ /// 常用公共类
+ ///
+ public class Common
+ {
+ public static object _lock = new object();
+
+ public static int count = 1;
+
+
+ #region Stopwatch计时器
+ ///
+ /// 计时器开始
+ ///
+ ///
+ public static Stopwatch TimerStart()
+ {
+ Stopwatch watch = new Stopwatch();
+ watch.Reset();
+ watch.Start();
+ return watch;
+ }
+ ///
+ /// 计时器结束
+ ///
+ ///
+ ///
+ public static string TimerEnd(Stopwatch watch)
+ {
+ watch.Stop();
+ double costtime = watch.ElapsedMilliseconds;
+ return costtime.ToString();
+ }
+ #endregion
+
+ #region 删除数组中的重复项
+ ///
+ /// 删除数组中的重复项
+ ///
+ ///
+ ///
+ public static string[] RemoveDup(string[] values)
+ {
+ List list = new List();
+ for (int i = 0; i < values.Length; i++)//遍历数组成员
+ {
+ if (!list.Contains(values[i]))
+ {
+ list.Add(values[i]);
+ };
+ }
+ return list.ToArray();
+ }
+ #endregion
+
+ #region 自动生成编号
+ ///
+ /// 表示全局唯一标识符 (GUID)。
+ ///
+ ///
+ public static string GuId()
+ {
+ return Guid.NewGuid().ToString();
+ }
+ ///
+ /// 自动生成编号 201008251145409865
+ ///
+ ///
+ public static string CreateNo()
+ {
+ Random random = new Random();
+ string strRandom = random.Next(1000, 10000).ToString(); //生成编号
+ string code = DateTime.Now.ToString("yyyyMMddHHmmss") + strRandom;//形如
+ return code;
+ }
+
+ ///
+ /// 生成不重复的订单,净水器
+ ///
+ ///
+ public static string CreateNo2()
+ {
+ lock (_lock)
+ {
+ if (count >= 10000)
+ {
+ count = 1;
+ }
+
+ var number = DateTime.Now.ToString("yyMMddHHmmssfff") + count.ToString("0000");
+
+ count++;
+
+ return number;
+ }
+ }
+
+ ///
+ /// 生成不重复的订单,送芯
+ ///
+ ///
+ public static string CreateNo3()
+ {
+ lock (_lock)
+ {
+ if (count >= 10000)
+ {
+ count = 1;
+ }
+
+ var number = "C" + DateTime.Now.ToString("yyMMddHHmmssfff") + count.ToString("0000");
+
+ count++;
+
+ return number;
+ }
+ }
+
+ ///
+ /// 退款订单号生成
+ ///
+ ///
+ public static string CreateNo_Recharge()
+ {
+ lock (_lock)
+ {
+ if (count >= 10000)
+ {
+ count = 1;
+ }
+
+ var number = "R" + DateTime.Now.ToString("yyMMddHHmmssfff") + count.ToString("0000");
+
+ count++;
+
+ return number;
+ }
+ }
+
+ ///
+ /// 生成订单号
+ ///
+ ///
+ public static string CreateNoQuery()
+ {
+ lock (_lock)
+ {
+ if (count >= 10000)
+ {
+ count = 1;
+ }
+
+ var number = "Q" + DateTime.Now.ToString("yyMMddHHmmssfff") + count.ToString("0000");
+
+ count++;
+
+ return number;
+ }
+ }
+
+
+ #endregion
+
+ #region 生成0-9随机数
+ ///
+ /// 生成0-9随机数
+ ///
+ /// 生成长度
+ ///
+ public static string RndNum(int codeNum)
+ {
+ StringBuilder sb = new StringBuilder(codeNum);
+ Random rand = new Random();
+ for (int i = 1; i < codeNum + 1; i++)
+ {
+ int t = rand.Next(9);
+ sb.AppendFormat("{0}", t);
+ }
+ return sb.ToString();
+
+ }
+ #endregion
+
+ #region 生成随机数
+ ///
+ /// 生成随机数
+ ///
+ /// 数据长度
+ /// 生成类型,0:纯数字,1:纯字母, 2:数据字+字母
+ ///
+ public static string GetRandomNo(int length, int CreateType)
+ {
+ char[] charlist = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'h', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
+ string result = "";
+
+ Random rd = new Random();
+ switch (CreateType)
+ {
+ case 0: //纯数字
+ for (int i = 0; i < length; i++)
+ {
+ result = result + charlist[rd.Next(0, 10)];
+ }
+ break;
+ case 1://纯字母
+ for (int i = 0; i < length; i++)
+ {
+ result = result + charlist[rd.Next(10, 36)];
+ }
+ break;
+ case 2://数据字+字母
+ for (int i = 0; i < length; i++)
+ {
+ result = result + charlist[rd.Next(0, 36)];
+ }
+ break;
+ }
+
+ return result;
+ }
+ #endregion
+
+
+ #region 删除最后一个字符之后的字符
+ ///
+ /// 删除最后结尾的一个逗号
+ ///
+ public static string DelLastComma(string str)
+ {
+ return str.Substring(0, str.LastIndexOf(","));
+ }
+ ///
+ /// 删除最后结尾的指定字符后的字符
+ ///
+ public static string DelLastChar(string str, string strchar)
+ {
+ return str.Substring(0, str.LastIndexOf(strchar));
+ }
+ ///
+ /// 删除最后结尾的长度
+ ///
+ ///
+ ///
+ ///
+ public static string DelLastLength(string str, int Length)
+ {
+ if (string.IsNullOrEmpty(str))
+ return "";
+ str = str.Substring(0, str.Length - Length);
+ return str;
+ }
+ #endregion
+
+
+ #region 小写转大写
+ ///
+ /// 转换人民币大小金额
+ ///
+ /// 金额
+ /// 返回大写形式
+ public static string CmycurD(decimal num)
+ {
+ string str1 = "零壹贰叁肆伍陆柒捌玖"; //0-9所对应的汉字
+ string str2 = "万仟佰拾亿仟佰拾万仟佰拾元角分"; //数字位所对应的汉字
+ string str3 = ""; //从原num值中取出的值
+ string str4 = ""; //数字的字符串形式
+ string str5 = ""; //人民币大写金额形式
+ int i; //循环变量
+ int j; //num的值乘以100的字符串长度
+ string ch1 = ""; //数字的汉语读法
+ string ch2 = ""; //数字位的汉字读法
+ int nzero = 0; //用来计算连续的零值是几个
+ int temp; //从原num值中取出的值
+
+ num = Math.Round(Math.Abs(num), 2); //将num取绝对值并四舍五入取2位小数
+ str4 = ((long)(num * 100)).ToString(); //将num乘100并转换成字符串形式
+ j = str4.Length; //找出最高位
+ if (j > 15) { return "溢出"; }
+ str2 = str2.Substring(15 - j); //取出对应位数的str2的值。如:200.55,j为5所以str2=佰拾元角分
+
+ //循环取出每一位需要转换的值
+ for (i = 0; i < j; i++)
+ {
+ str3 = str4.Substring(i, 1); //取出需转换的某一位的值
+ temp = Convert.ToInt32(str3); //转换为数字
+ if (i != (j - 3) && i != (j - 7) && i != (j - 11) && i != (j - 15))
+ {
+ //当所取位数不为元、万、亿、万亿上的数字时
+ if (str3 == "0")
+ {
+ ch1 = "";
+ ch2 = "";
+ nzero = nzero + 1;
+ }
+ else
+ {
+ if (str3 != "0" && nzero != 0)
+ {
+ ch1 = "零" + str1.Substring(temp * 1, 1);
+ ch2 = str2.Substring(i, 1);
+ nzero = 0;
+ }
+ else
+ {
+ ch1 = str1.Substring(temp * 1, 1);
+ ch2 = str2.Substring(i, 1);
+ nzero = 0;
+ }
+ }
+ }
+ else
+ {
+ //该位是万亿,亿,万,元位等关键位
+ if (str3 != "0" && nzero != 0)
+ {
+ ch1 = "零" + str1.Substring(temp * 1, 1);
+ ch2 = str2.Substring(i, 1);
+ nzero = 0;
+ }
+ else
+ {
+ if (str3 != "0" && nzero == 0)
+ {
+ ch1 = str1.Substring(temp * 1, 1);
+ ch2 = str2.Substring(i, 1);
+ nzero = 0;
+ }
+ else
+ {
+ if (str3 == "0" && nzero >= 3)
+ {
+ ch1 = "";
+ ch2 = "";
+ nzero = nzero + 1;
+ }
+ else
+ {
+ if (j >= 11)
+ {
+ ch1 = "";
+ nzero = nzero + 1;
+ }
+ else
+ {
+ ch1 = "";
+ ch2 = str2.Substring(i, 1);
+ nzero = nzero + 1;
+ }
+ }
+ }
+ }
+ }
+ if (i == (j - 11) || i == (j - 3))
+ {
+ //如果该位是亿位或元位,则必须写上
+ ch2 = str2.Substring(i, 1);
+ }
+ str5 = str5 + ch1 + ch2;
+
+ if (i == j - 1 && str3 == "0")
+ {
+ //最后一位(分)为0时,加上“整”
+ str5 = str5 + '整';
+ }
+ }
+ if (num == 0)
+ {
+ str5 = "零元整";
+ }
+ return str5;
+ }
+
+ #endregion
+
+ #region 获取html所有Img标签src地址
+ public static string[] GetHtmlImageUrlList(string sHtmlText)
+ {
+ // 定义正则表达式用来匹配 img 标签
+ Regex regImg = new Regex(@" ]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase);
+
+ // 搜索匹配的字符串
+ MatchCollection matches = regImg.Matches(sHtmlText);
+ int i = 0;
+ string[] sUrlList = new string[matches.Count];
+
+ // 取得匹配项列表
+ foreach (Match match in matches)
+ sUrlList[i++] = match.Groups["imgUrl"].Value;
+ return sUrlList;
+ }
+
+ #endregion
+
+ #region 删除html标签
+ public static string ReplaceHtmlTag(string html, int length = 0)
+ {
+ string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", "");
+ strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", "");
+
+ if (length > 0 && strText.Length > length)
+ return strText.Substring(0, length);
+
+ return strText;
+ }
+ #endregion
+ }
+}
diff --git a/ARW.Common/CrawlerHelper.cs b/ARW.Common/CrawlerHelper.cs
new file mode 100644
index 0000000..3d9b33e
--- /dev/null
+++ b/ARW.Common/CrawlerHelper.cs
@@ -0,0 +1,829 @@
+///
+/// 类说明:HttpHelper类,用来实现Http访问,Post或者Get方式的,直接访问,带Cookie的,带证书的等方式,可以设置代理
+/// 重要提示:请不要自行修改本类,如果因为你自己修改后将无法升级到新版本。如果确实有什么问题请到官方网站提建议,
+/// 我们一定会及时修改
+/// 编码日期:2011-09-20
+/// 编 码 人:苏飞
+/// 联系方式:361983679
+/// 官方网址:http://www.sufeinet.com/thread-3-1-1.html
+/// 修改日期:2018-11-06
+/// 版 本 号:1.9.9
+///
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Net;
+using System.IO;
+using System.Text.RegularExpressions;
+using System.IO.Compression;
+using System.Security.Cryptography.X509Certificates;
+using System.Net.Security;
+using System.Linq;
+using System.Net.Cache;
+
+namespace ARW.Common
+{
+ ///
+ /// Http连接操作帮助类
+ ///
+ public class CrawlerHelper
+ {
+
+ #region 预定义方变量
+ //默认的编码
+ private Encoding encoding = Encoding.Default;
+ //Post数据编码
+ private Encoding postencoding = Encoding.Default;
+ //HttpWebRequest对象用来发起请求
+ private HttpWebRequest request = null;
+ //获取影响流的数据对象
+ private HttpWebResponse response = null;
+ //设置本地的出口ip和端口
+ private IPEndPoint _IPEndPoint = null;
+ #endregion
+
+ #region Public
+
+ ///
+ /// 根据相传入的数据,得到相应页面数据
+ ///
+ /// 参数类对象
+ /// 返回HttpResult类型
+ public HttpResult GetHtml(HttpItem item)
+ {
+ //返回参数
+ HttpResult result = new HttpResult();
+ try
+ {
+ //准备参数
+ SetRequest(item);
+ }
+ catch (Exception ex)
+ {
+ //配置参数时出错
+ return new HttpResult() { Cookie = string.Empty, Header = null, Html = ex.Message, StatusDescription = "配置参数时出错:" + ex.Message };
+ }
+ try
+ {
+ //请求数据
+ using (response = (HttpWebResponse)request.GetResponse())
+ {
+ GetData(item, result);
+ }
+ }
+ catch (WebException ex)
+ {
+ if (ex.Response != null)
+ {
+ using (response = (HttpWebResponse)ex.Response)
+ {
+ GetData(item, result);
+ }
+ }
+ else
+ {
+ result.Html = ex.Message;
+ }
+ }
+ catch (Exception ex)
+ {
+ result.Html = ex.Message;
+ }
+ if (item.IsToLower) result.Html = result.Html.ToLower();
+ //重置request,response为空
+ if (item.IsReset)
+ {
+ request = null;
+ response = null;
+ }
+ return result;
+ }
+ #endregion
+
+ #region GetData
+
+ ///
+ /// 获取数据的并解析的方法
+ ///
+ ///
+ ///
+ private void GetData(HttpItem item, HttpResult result)
+ {
+ if (response == null)
+ {
+ return;
+ }
+ #region base
+ //获取StatusCode
+ result.StatusCode = response.StatusCode;
+ //获取StatusDescription
+ result.StatusDescription = response.StatusDescription;
+ //获取Headers
+ result.Header = response.Headers;
+ //获取最后访问的URl
+ result.ResponseUri = response.ResponseUri.ToString();
+ //获取CookieCollection
+ if (response.Cookies != null) result.CookieCollection = response.Cookies;
+ //获取set-cookie
+ if (response.Headers["set-cookie"] != null) result.Cookie = response.Headers["set-cookie"];
+ #endregion
+
+ #region byte
+
+ //处理网页Byte
+ byte[] ResponseByte = GetByte();
+
+ #endregion
+
+ #region Html
+ if (ResponseByte != null && ResponseByte.Length > 0)
+ {
+ //设置编码
+ SetEncoding(item, result, ResponseByte);
+ //得到返回的HTML
+ result.Html = encoding.GetString(ResponseByte);
+ }
+ else
+ {
+ //没有返回任何Html代码
+ result.Html = string.Empty;
+ }
+ #endregion
+ }
+ ///
+ /// 设置编码
+ ///
+ /// HttpItem
+ /// HttpResult
+ /// byte[]
+ private void SetEncoding(HttpItem item, HttpResult result, byte[] ResponseByte)
+ {
+ //是否返回Byte类型数据
+ if (item.ResultType == ResultType.Byte) result.ResultByte = ResponseByte;
+ //从这里开始我们要无视编码了
+ if (encoding == null)
+ {
+ Match meta = Regex.Match(Encoding.Default.GetString(ResponseByte), " 0)
+ {
+ c = meta.Groups[1].Value.ToLower().Trim();
+ }
+ if (c.Length > 2)
+ {
+ try
+ {
+ encoding = Encoding.GetEncoding(c.Replace("\"", string.Empty).Replace("'", "").Replace(";", "").Replace("iso-8859-1", "gbk").Trim());
+ }
+ catch
+ {
+ if (string.IsNullOrEmpty(response.CharacterSet))
+ {
+ encoding = Encoding.UTF8;
+ }
+ else
+ {
+ encoding = Encoding.GetEncoding(response.CharacterSet);
+ }
+ }
+ }
+ else
+ {
+ if (string.IsNullOrEmpty(response.CharacterSet))
+ {
+ encoding = Encoding.UTF8;
+ }
+ else
+ {
+ encoding = Encoding.GetEncoding(response.CharacterSet);
+ }
+ }
+ }
+ }
+ ///
+ /// 提取网页Byte
+ ///
+ ///
+ private byte[] GetByte()
+ {
+ byte[] ResponseByte = null;
+ using (MemoryStream _stream = new MemoryStream())
+ {
+ //GZIIP处理
+ if (response.ContentEncoding != null && response.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase))
+ {
+ //开始读取流并设置编码方式
+ new GZipStream(response.GetResponseStream(), CompressionMode.Decompress).CopyTo(_stream, 10240);
+ }
+ else
+ {
+ //开始读取流并设置编码方式
+ response.GetResponseStream().CopyTo(_stream, 10240);
+ }
+ //获取Byte
+ ResponseByte = _stream.ToArray();
+ }
+ return ResponseByte;
+ }
+
+
+ #endregion
+
+ #region SetRequest
+
+ ///
+ /// 为请求准备参数
+ ///
+ /// 参数列表
+ private void SetRequest(HttpItem item)
+ {
+
+ // 验证证书
+ SetCer(item);
+ if (item.IPEndPoint != null)
+ {
+ _IPEndPoint = item.IPEndPoint;
+ //设置本地的出口ip和端口
+ request.ServicePoint.BindIPEndPointDelegate = new BindIPEndPoint(BindIPEndPointCallback);
+ }
+ //设置Header参数
+ if (item.Header != null && item.Header.Count > 0) foreach (string key in item.Header.AllKeys)
+ {
+ request.Headers.Add(key, item.Header[key]);
+ }
+ // 设置代理
+ SetProxy(item);
+ if (item.ProtocolVersion != null) request.ProtocolVersion = item.ProtocolVersion;
+ request.ServicePoint.Expect100Continue = item.Expect100Continue;
+ //请求方式Get或者Post
+ request.Method = item.Method;
+ request.Timeout = item.Timeout;
+ request.KeepAlive = item.KeepAlive;
+ request.ReadWriteTimeout = item.ReadWriteTimeout;
+ if (!string.IsNullOrWhiteSpace(item.Host))
+ {
+ request.Host = item.Host;
+ }
+ if (item.IfModifiedSince != null) request.IfModifiedSince = Convert.ToDateTime(item.IfModifiedSince);
+ //Accept
+ request.Accept = item.Accept;
+ //ContentType返回类型
+ request.ContentType = item.ContentType;
+ //UserAgent客户端的访问类型,包括浏览器版本和操作系统信息
+ request.UserAgent = item.UserAgent;
+ // 编码
+ encoding = item.Encoding;
+ //设置安全凭证
+ request.Credentials = item.ICredentials;
+ //设置Cookie
+ SetCookie(item);
+ //来源地址
+ request.Referer = item.Referer;
+ //是否执行跳转功能
+ request.AllowAutoRedirect = item.Allowautoredirect;
+ if (item.MaximumAutomaticRedirections > 0)
+ {
+ request.MaximumAutomaticRedirections = item.MaximumAutomaticRedirections;
+ }
+ //设置Post数据
+ SetPostData(item);
+ //设置最大连接
+ if (item.Connectionlimit > 0) request.ServicePoint.ConnectionLimit = item.Connectionlimit;
+ }
+ ///
+ /// 设置证书
+ ///
+ ///
+ private void SetCer(HttpItem item)
+ {
+ if (!string.IsNullOrWhiteSpace(item.CerPath))
+ {
+ //这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。
+ ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
+ //初始化对像,并设置请求的URL地址
+ request = (HttpWebRequest)WebRequest.Create(item.URL);
+ SetCerList(item);
+ //将证书添加到请求里
+ request.ClientCertificates.Add(new X509Certificate(item.CerPath));
+ }
+ else
+ {
+ //初始化对像,并设置请求的URL地址
+ request = (HttpWebRequest)WebRequest.Create(item.URL);
+ SetCerList(item);
+ }
+ }
+ ///
+ /// 设置多个证书
+ ///
+ ///
+ private void SetCerList(HttpItem item)
+ {
+ if (item.ClentCertificates != null && item.ClentCertificates.Count > 0)
+ {
+ foreach (X509Certificate c in item.ClentCertificates)
+ {
+ request.ClientCertificates.Add(c);
+ }
+ }
+ }
+ ///
+ /// 设置Cookie
+ ///
+ /// Http参数
+ private void SetCookie(HttpItem item)
+ {
+ if (!string.IsNullOrEmpty(item.Cookie)) request.Headers[HttpRequestHeader.Cookie] = item.Cookie;
+ //设置CookieCollection
+ if (item.ResultCookieType == ResultCookieType.CookieCollection)
+ {
+ request.CookieContainer = new CookieContainer();
+ if (item.CookieCollection != null && item.CookieCollection.Count > 0)
+ request.CookieContainer.Add(item.CookieCollection);
+ }
+ }
+ ///
+ /// 设置Post数据
+ ///
+ /// Http参数
+ private void SetPostData(HttpItem item)
+ {
+ //验证在得到结果时是否有传入数据
+ if (!request.Method.Trim().ToLower().Contains("get"))
+ {
+ if (item.PostEncoding != null)
+ {
+ postencoding = item.PostEncoding;
+ }
+ byte[] buffer = null;
+ //写入Byte类型
+ if (item.PostDataType == PostDataType.Byte && item.PostdataByte != null && item.PostdataByte.Length > 0)
+ {
+ //验证在得到结果时是否有传入数据
+ buffer = item.PostdataByte;
+ }//写入文件
+ else if (item.PostDataType == PostDataType.FilePath && !string.IsNullOrWhiteSpace(item.Postdata))
+ {
+ StreamReader r = new StreamReader(item.Postdata, postencoding);
+ buffer = postencoding.GetBytes(r.ReadToEnd());
+ r.Close();
+ } //写入字符串
+ else if (!string.IsNullOrWhiteSpace(item.Postdata))
+ {
+ buffer = postencoding.GetBytes(item.Postdata);
+ }
+ if (buffer != null)
+ {
+ request.ContentLength = buffer.Length;
+ request.GetRequestStream().Write(buffer, 0, buffer.Length);
+ }
+ else
+ {
+ request.ContentLength = 0;
+ }
+ }
+ }
+ ///
+ /// 设置代理
+ ///
+ /// 参数对象
+ private void SetProxy(HttpItem item)
+ {
+ bool isIeProxy = false;
+ if (!string.IsNullOrWhiteSpace(item.ProxyIp))
+ {
+ isIeProxy = item.ProxyIp.ToLower().Contains("ieproxy");
+ }
+ if (!string.IsNullOrWhiteSpace(item.ProxyIp) && !isIeProxy)
+ {
+ //设置代理服务器
+ if (item.ProxyIp.Contains(":"))
+ {
+ string[] plist = item.ProxyIp.Split(':');
+ WebProxy myProxy = new WebProxy(plist[0].Trim(), Convert.ToInt32(plist[1].Trim()));
+ //建议连接
+ myProxy.Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd);
+ //给当前请求对象
+ request.Proxy = myProxy;
+ }
+ else
+ {
+ WebProxy myProxy = new WebProxy(item.ProxyIp, false);
+ //建议连接
+ myProxy.Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd);
+ //给当前请求对象
+ request.Proxy = myProxy;
+ }
+ }
+ else if (isIeProxy)
+ {
+ //设置为IE代理
+ }
+ else
+ {
+ request.Proxy = item.WebProxy;
+ }
+ }
+
+
+ #endregion
+
+ #region private main
+ ///
+ /// 回调验证证书问题
+ ///
+ /// 流对象
+ /// 证书
+ /// X509Chain
+ /// SslPolicyErrors
+ /// bool
+ private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; }
+
+ ///
+ /// 通过设置这个属性,可以在发出连接的时候绑定客户端发出连接所使用的IP地址。
+ ///
+ ///
+ ///
+ ///
+ ///
+ private IPEndPoint BindIPEndPointCallback(ServicePoint servicePoint, IPEndPoint remoteEndPoint, int retryCount)
+ {
+ return _IPEndPoint;//端口号
+ }
+ #endregion
+ }
+
+ #region public calss
+ ///
+ /// Http请求参考类
+ ///
+ public class HttpItem
+ {
+ ///
+ /// 请求URL必须填写
+ ///
+ public string URL { get; set; }
+ string _Method = "GET";
+ ///
+ /// 请求方式默认为GET方式,当为POST方式时必须设置Postdata的值
+ ///
+ public string Method
+ {
+ get { return _Method; }
+ set { _Method = value; }
+ }
+ int _Timeout = 100000;
+ ///
+ /// 默认请求超时时间
+ ///
+ public int Timeout
+ {
+ get { return _Timeout; }
+ set { _Timeout = value; }
+ }
+ int _ReadWriteTimeout = 30000;
+ ///
+ /// 默认写入Post数据超时间
+ ///
+ public int ReadWriteTimeout
+ {
+ get { return _ReadWriteTimeout; }
+ set { _ReadWriteTimeout = value; }
+ }
+ ///
+ /// 设置Host的标头信息
+ ///
+ public string Host { get; set; }
+ Boolean _KeepAlive = true;
+ ///
+ /// 获取或设置一个值,该值指示是否与 Internet 资源建立持久性连接默认为true。
+ ///
+ public Boolean KeepAlive
+ {
+ get { return _KeepAlive; }
+ set { _KeepAlive = value; }
+ }
+ string _Accept = "text/html, application/xhtml+xml, */*";
+ ///
+ /// 请求标头值 默认为text/html, application/xhtml+xml, */*
+ ///
+ public string Accept
+ {
+ get { return _Accept; }
+ set { _Accept = value; }
+ }
+ string _ContentType = "text/html";
+ ///
+ /// 请求返回类型默认 text/html
+ ///
+ public string ContentType
+ {
+ get { return _ContentType; }
+ set { _ContentType = value; }
+ }
+ string _UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
+ ///
+ /// 客户端访问信息默认Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
+ ///
+ public string UserAgent
+ {
+ get { return _UserAgent; }
+ set { _UserAgent = value; }
+ }
+ ///
+ /// 返回数据编码默认为NUll,可以自动识别,一般为utf-8,gbk,gb2312
+ ///
+ public Encoding Encoding { get; set; }
+ private PostDataType _PostDataType = PostDataType.String;
+ ///
+ /// Post的数据类型
+ ///
+ public PostDataType PostDataType
+ {
+ get { return _PostDataType; }
+ set { _PostDataType = value; }
+ }
+ ///
+ /// Post请求时要发送的字符串Post数据
+ ///
+ public string Postdata { get; set; }
+ ///
+ /// Post请求时要发送的Byte类型的Post数据
+ ///
+ public byte[] PostdataByte { get; set; }
+ ///
+ /// Cookie对象集合
+ ///
+ public CookieCollection CookieCollection { get; set; }
+ ///
+ /// 请求时的Cookie
+ ///
+ public string Cookie { get; set; }
+ ///
+ /// 来源地址,上次访问地址
+ ///
+ public string Referer { get; set; }
+ ///
+ /// 证书绝对路径
+ ///
+ public string CerPath { get; set; }
+ ///
+ /// 设置代理对象,不想使用IE默认配置就设置为Null,而且不要设置ProxyIp
+ ///
+ public WebProxy WebProxy { get; set; }
+ private Boolean isToLower = false;
+ ///
+ /// 是否设置为全文小写,默认为不转化
+ ///
+ public Boolean IsToLower
+ {
+ get { return isToLower; }
+ set { isToLower = value; }
+ }
+ private Boolean allowautoredirect = false;
+ ///
+ /// 支持跳转页面,查询结果将是跳转后的页面,默认是不跳转
+ ///
+ public Boolean Allowautoredirect
+ {
+ get { return allowautoredirect; }
+ set { allowautoredirect = value; }
+ }
+ private int connectionlimit = 1024;
+ ///
+ /// 最大连接数
+ ///
+ public int Connectionlimit
+ {
+ get { return connectionlimit; }
+ set { connectionlimit = value; }
+ }
+ ///
+ /// 代理Proxy 服务器用户名
+ ///
+ public string ProxyUserName { get; set; }
+ ///
+ /// 代理 服务器密码
+ ///
+ public string ProxyPwd { get; set; }
+ ///
+ /// 代理 服务IP,如果要使用IE代理就设置为ieproxy
+ ///
+ public string ProxyIp { get; set; }
+ private ResultType resulttype = ResultType.String;
+ ///
+ /// 设置返回类型String和Byte
+ ///
+ public ResultType ResultType
+ {
+ get { return resulttype; }
+ set { resulttype = value; }
+ }
+ private WebHeaderCollection header = new WebHeaderCollection();
+ ///
+ /// header对象
+ ///
+ public WebHeaderCollection Header
+ {
+ get { return header; }
+ set { header = value; }
+ }
+ ///
+ // 获取或设置用于请求的 HTTP 版本。返回结果:用于请求的 HTTP 版本。默认为 System.Net.HttpVersion.Version11。
+ ///
+ public Version ProtocolVersion { get; set; }
+ private Boolean _expect100continue = false;
+ ///
+ /// 获取或设置一个 System.Boolean 值,该值确定是否使用 100-Continue 行为。如果 POST 请求需要 100-Continue 响应,则为 true;否则为 false。默认值为 true。
+ ///
+ public Boolean Expect100Continue
+ {
+ get { return _expect100continue; }
+ set { _expect100continue = value; }
+ }
+ ///
+ /// 设置509证书集合
+ ///
+ public X509CertificateCollection ClentCertificates { get; set; }
+ ///
+ /// 设置或获取Post参数编码,默认的为Default编码
+ ///
+ public Encoding PostEncoding { get; set; }
+ private ResultCookieType _ResultCookieType = ResultCookieType.String;
+ ///
+ /// Cookie返回类型,默认的是只返回字符串类型
+ ///
+ public ResultCookieType ResultCookieType
+ {
+ get { return _ResultCookieType; }
+ set { _ResultCookieType = value; }
+ }
+ private ICredentials _ICredentials = CredentialCache.DefaultCredentials;
+ ///
+ /// 获取或设置请求的身份验证信息。
+ ///
+ public ICredentials ICredentials
+ {
+ get { return _ICredentials; }
+ set { _ICredentials = value; }
+ }
+ ///
+ /// 设置请求将跟随的重定向的最大数目
+ ///
+ public int MaximumAutomaticRedirections { get; set; }
+ private DateTime? _IfModifiedSince = null;
+ ///
+ /// 获取和设置IfModifiedSince,默认为当前日期和时间
+ ///
+ public DateTime? IfModifiedSince
+ {
+ get { return _IfModifiedSince; }
+ set { _IfModifiedSince = value; }
+ }
+ #region ip-port
+ private IPEndPoint _IPEndPoint = null;
+ ///
+ /// 设置本地的出口ip和端口
+ /// ]
+ ///
+ ///item.IPEndPoint = new IPEndPoint(IPAddress.Parse("192.168.1.1"),80);
+ ///
+ public IPEndPoint IPEndPoint
+ {
+ get { return _IPEndPoint; }
+ set { _IPEndPoint = value; }
+ }
+ #endregion
+
+ private bool _isReset = false;
+ ///
+ /// 是否重置request,response的值,默认不重置,当设置为True时request,response将被设置为Null
+ ///
+ public bool IsReset
+ {
+ get { return _isReset; }
+ set { _isReset = value; }
+ }
+ }
+ ///
+ /// Http返回参数类
+ ///
+ public class HttpResult
+ {
+ ///
+ /// Http请求返回的Cookie
+ ///
+ public string Cookie { get; set; }
+ ///
+ /// Cookie对象集合
+ ///
+ public CookieCollection CookieCollection { get; set; }
+ private string _html = string.Empty;
+ ///
+ /// 返回的String类型数据 只有ResultType.String时才返回数据,其它情况为空
+ ///
+ public string Html
+ {
+ get { return _html; }
+ set { _html = value; }
+ }
+ ///
+ /// 返回的Byte数组 只有ResultType.Byte时才返回数据,其它情况为空
+ ///
+ public byte[] ResultByte { get; set; }
+ ///
+ /// header对象
+ ///
+ public WebHeaderCollection Header { get; set; }
+ ///
+ /// 返回状态说明
+ ///
+ public string StatusDescription { get; set; }
+ ///
+ /// 返回状态码,默认为OK
+ ///
+ public HttpStatusCode StatusCode { get; set; }
+ ///
+ /// 最后访问的URl
+ ///
+ public string ResponseUri { get; set; }
+ ///
+ /// 获取重定向的URl
+ ///
+ public string RedirectUrl
+ {
+ get
+ {
+ try
+ {
+ if (Header != null && Header.Count > 0)
+ {
+ if (Header.AllKeys.Any(k => k.ToLower().Contains("location")))
+ {
+ string baseurl = Header["location"].ToString().Trim();
+ string locationurl = baseurl.ToLower();
+ if (!string.IsNullOrWhiteSpace(locationurl))
+ {
+ bool b = locationurl.StartsWith("http://") || locationurl.StartsWith("https://");
+ if (!b)
+ {
+ baseurl = new Uri(new Uri(ResponseUri), baseurl).AbsoluteUri;
+ }
+ }
+ return baseurl;
+ }
+ }
+ }
+ catch { }
+ return string.Empty;
+ }
+ }
+ }
+ ///
+ /// 返回类型
+ ///
+ public enum ResultType
+ {
+ ///
+ /// 表示只返回字符串 只有Html有数据
+ ///
+ String,
+ ///
+ /// 表示返回字符串和字节流 ResultByte和Html都有数据返回
+ ///
+ Byte
+ }
+ ///
+ /// Post的数据格式默认为string
+ ///
+ public enum PostDataType
+ {
+ ///
+ /// 字符串类型,这时编码Encoding可不设置
+ ///
+ String,
+ ///
+ /// Byte类型,需要设置PostdataByte参数的值编码Encoding可设置为空
+ ///
+ Byte,
+ ///
+ /// 传文件,Postdata必须设置为文件的绝对路径,必须设置Encoding的值
+ ///
+ FilePath
+ }
+ ///
+ /// Cookie返回类型
+ ///
+ public enum ResultCookieType
+ {
+ ///
+ /// 只返回字符串类型的Cookie
+ ///
+ String,
+ ///
+ /// CookieCollection格式的Cookie集合同时也返回String类型的cookie
+ ///
+ CookieCollection
+ }
+ #endregion
+}
\ No newline at end of file
diff --git a/ARW.Common/ExcelHelper.cs b/ARW.Common/ExcelHelper.cs
new file mode 100644
index 0000000..e245f69
--- /dev/null
+++ b/ARW.Common/ExcelHelper.cs
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using OfficeOpenXml;
+namespace ARW.Common
+{
+ public class ExcelHelper where T : new()
+ {
+ ///
+ /// 导入数据
+ ///
+ ///
+ ///
+ public static IEnumerable ImportData(Stream stream)
+ {
+ using ExcelPackage package = new(stream);
+ ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
+ ExcelWorksheet worksheet = package.Workbook.Worksheets[0];//读取第1个sheet
+ //获取表格的列数和行数
+
+ int colStart = worksheet.Dimension.Start.Column;
+ int colEnd = worksheet.Dimension.End.Column;
+ int rowStart = worksheet.Dimension.Start.Row;
+ int rowEnd = worksheet.Dimension.End.Row;
+ //int rowCount = worksheet.Dimension.Rows;
+ //int ColCount = worksheet.Dimension.Columns;
+
+ List resultList = new();
+ List propertyInfos = new();// new(typeof(T).GetProperties());
+ Dictionary dictHeader = new();
+ for (int i = colStart; i <= colEnd; i++)
+ {
+ var name = worksheet.Cells[rowStart, i].Value.ToString();
+ dictHeader[name] = i;
+
+ PropertyInfo propertyInfo = MapPropertyInfo(name);
+ if (propertyInfo != null)
+ {
+ propertyInfos.Add(propertyInfo);
+ }
+ }
+ for (int row = rowStart + 1; row <= rowEnd; row++)
+ {
+ T result = new();
+
+ foreach (PropertyInfo p in propertyInfos)
+ {
+ try
+ {
+ foreach (var i in p.CustomAttributes)
+ {
+ foreach (var i2 in i.NamedArguments)
+ {
+ ExcelRange cell = worksheet.Cells[row, dictHeader[i2.TypedValue.Value.ToString()]];
+ if (cell.Value == null)
+ {
+ continue;
+ }
+ switch (p.PropertyType.Name.ToLower())
+ {
+ case "string":
+ p.SetValue(result, cell.GetValue());
+ break;
+ case "int16":
+ p.SetValue(result, cell.GetValue()); break;
+ case "int32":
+ p.SetValue(result, cell.GetValue()); break;
+ case "int64":
+ p.SetValue(result, cell.GetValue()); break;
+ case "decimal":
+ p.SetValue(result, cell.GetValue());
+ break;
+ case "double":
+ p.SetValue(result, cell.GetValue()); break;
+ case "datetime":
+ p.SetValue(result, cell.GetValue()); break;
+ case "boolean":
+ p.SetValue(result, cell.GetValue()); break;
+ case "char":
+ p.SetValue(result, cell.GetValue()); break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ catch (KeyNotFoundException ex)
+ {
+ Console.WriteLine("未找到该列将继续循环," + ex.Message);
+ continue;
+ }
+ }
+ resultList.Add(result);
+ }
+
+ return resultList;
+ }
+
+ ///
+ /// 查找Excel列名对应的实体属性
+ ///
+ ///
+ ///
+ public static PropertyInfo MapPropertyInfo(string columnName)
+ {
+ PropertyInfo[] propertyList = GetProperties(typeof(T));
+ //PropertyInfo propertyInfo = propertyList.Where(p => p.Name == columnName).FirstOrDefault();
+
+ foreach (var item in propertyList)
+ {
+ foreach (var i in item.CustomAttributes)
+ {
+ if (i.AttributeType.Name == "EpplusTableColumnAttribute")
+ {
+ foreach (var i2 in i.NamedArguments)
+ {
+ if (columnName == i2.TypedValue.Value.ToString())
+ {
+ return item;
+ }
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ ///
+ /// 得到类里面的属性集合
+ ///
+ ///
+ ///
+ ///
+ public static PropertyInfo[] GetProperties(Type type, string[] columns = null)
+ {
+ PropertyInfo[] properties = null;
+ properties = type.GetProperties();
+
+ if (columns != null && columns.Length > 0)
+ {
+ // 按columns顺序返回属性
+ var columnPropertyList = new List();
+ foreach (var column in columns)
+ {
+ var columnProperty = properties.Where(p => p.Name == column).FirstOrDefault();
+ if (columnProperty != null)
+ {
+ columnPropertyList.Add(columnProperty);
+ }
+ }
+ return columnPropertyList.ToArray();
+ }
+ else
+ {
+ return properties;
+ }
+ }
+ }
+}
diff --git a/ARW.Common/MailHelper.cs b/ARW.Common/MailHelper.cs
new file mode 100644
index 0000000..4b69f51
--- /dev/null
+++ b/ARW.Common/MailHelper.cs
@@ -0,0 +1,174 @@
+using Infrastructure;
+using MailKit.Net.Smtp;
+using MimeKit;
+using MimeKit.Text;
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace ARW.Common
+{
+ public class MailHelper
+ {
+ ///
+ /// 发送人邮箱
+ ///
+ public string FromEmail { get; set; } = "";
+ ///
+ /// 发送人密码
+ ///
+ public string FromPwd { get; set; } = "";
+ ///
+ /// 发送协议
+ ///
+ public string Smtp { get; set; } = "smtp.qq.com";
+ ///
+ /// 协议端口
+ ///
+ public int Port { get; set; } = 587;
+ ///
+ /// 邮件签名
+ ///
+ public string Signature { get; set; }
+ ///
+ /// 是否使用SSL协议
+ ///
+ public bool UseSsl { get; set; } = false;
+ private readonly MailOptions mailOptions = new();
+
+ public MailHelper()
+ {
+ AppSettings.Bind("MailOptions", mailOptions);
+ FromEmail = mailOptions.From;
+ Smtp = mailOptions.Smtp;
+ FromPwd = mailOptions.Password;
+ Port = mailOptions.Port;
+ }
+ public MailHelper(string fromEmail, string smtp, int port, string fromPwd)
+ {
+ FromEmail = fromEmail;
+ Smtp = smtp;
+ FromPwd = fromPwd;
+ Port = port;
+ }
+
+ public MailHelper(string fromEmail, string fromPwd)
+ {
+ FromEmail = fromEmail;
+ FromPwd = fromPwd;
+ }
+
+ ///
+ /// 发送一个
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendMail(string toAddress, string subject, string text, string path = "", string html = "")
+ {
+ IEnumerable mailboxes = new List() {
+ new MailboxAddress(toAddress, toAddress)
+ };
+
+ SendMail(mailboxes, subject, text, path, html);
+ }
+
+ ///
+ /// 发送多个邮箱
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendMail(string[] toAddress, string subject, string text, string path = "", string html = "")
+ {
+ IList mailboxes = new List() { };
+ foreach (var item in toAddress)
+ {
+ mailboxes.Add(new MailboxAddress(item, item));
+ }
+
+ SendMail(mailboxes, subject, text, path, html);
+ }
+
+ ///
+ /// 发送邮件
+ ///
+ ///
+ /// 主题
+ ///
+ /// 附件url地址
+ /// 网页HTML内容
+ private void SendMail(IEnumerable toAddress, string subject, string text, string path = "", string html = "")
+ {
+ MimeMessage message = new MimeMessage();
+ //发件人
+ message.From.Add(new MailboxAddress(FromEmail, FromEmail));
+ //收件人
+ message.To.AddRange(toAddress);
+ message.Subject = subject;
+ message.Date = DateTime.Now;
+
+ //创建附件Multipart
+ Multipart multipart = new Multipart("mixed");
+ var alternative = new MultipartAlternative();
+ //html内容
+ if (!string.IsNullOrEmpty(html))
+ {
+ var Html = new TextPart(TextFormat.Html)
+ {
+ Text = html
+ };
+ alternative.Add(Html);
+ }
+ //文本内容
+ //if (!string.IsNullOrEmpty(text))
+ //{
+ var plain = new TextPart(TextFormat.Plain)
+ {
+ Text = text + "\r\n\n\n" + mailOptions.Signature
+ };
+ alternative.Add(plain);
+ //}
+
+ //附件
+ if (!string.IsNullOrEmpty(path))
+ {
+ string[] files = path.Split(",");
+ foreach (var file in files)
+ {
+ MimePart attachment = new()
+ {
+ Content = new MimeContent(File.OpenRead(file), ContentEncoding.Default),
+ //读取文件,只能用绝对路径
+ ContentDisposition = new ContentDisposition(ContentDisposition.Attachment),
+ ContentTransferEncoding = ContentEncoding.Base64,
+ //文件名字
+ FileName = Path.GetFileName(path)
+ };
+ alternative.Add(attachment);
+ }
+ }
+ multipart.Add(alternative);
+ //赋值邮件内容
+ message.Body = multipart;
+
+ //开始发送
+ using var client = new SmtpClient();
+ client.ServerCertificateValidationCallback = (s, c, h, e) => true;
+
+ //Smtp服务器
+ //client.Connect("smtp.qq.com", 587, false);
+ client.Connect(Smtp, Port, true);
+ //登录,发送
+ //特别说明,对于服务器端的中文相应,Exception中有编码问题,显示乱码了
+ client.Authenticate(FromEmail, FromPwd);
+
+ client.Send(message);
+ //断开
+ client.Disconnect(true);
+ Console.WriteLine($"发送邮件成功{DateTime.Now}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Common/Tools.cs b/ARW.Common/Tools.cs
new file mode 100644
index 0000000..947ac4a
--- /dev/null
+++ b/ARW.Common/Tools.cs
@@ -0,0 +1,191 @@
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Linq;
+
+namespace ARW.Common
+{
+ public class Tools
+ {
+ ///
+ /// 要分割的字符串 eg: 1,3,10,00
+ ///
+ ///
+ /// 分割的字符串
+ ///
+ public static long[] SpitLongArrary(string str, char split = ',')
+ {
+ if (string.IsNullOrEmpty(str)) { return Array.Empty(); }
+ str = str.TrimStart(split).TrimEnd(split);
+ string[] strIds = str.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
+ long[] infoIdss = Array.ConvertAll(strIds, s => long.Parse(s));
+ return infoIdss;
+ }
+
+ public static int[] SpitIntArrary(string str, char split = ',')
+ {
+ if (string.IsNullOrEmpty(str)) { return Array.Empty(); }
+ string[] strIds = str.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
+ int[] infoIdss = Array.ConvertAll(strIds, s => int.Parse(s));
+ return infoIdss;
+ }
+
+ public static string[] SpitStringArrary(string str, char split = ',')
+ {
+ if (string.IsNullOrEmpty(str)) { return Array.Empty(); }
+ string[] strIds = str.Split(split, (char)StringSplitOptions.RemoveEmptyEntries);
+ return strIds;
+ }
+
+ ///
+ /// 根据日期获取星期几
+ ///
+ public static string GetWeekByDate(DateTime dt)
+ {
+ var day = new[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
+ return day[Convert.ToInt32(dt.DayOfWeek.ToString("d"))];
+ }
+
+ ///
+ /// 得到这个月的第几周
+ ///
+ /// 年月日
+ /// 传递过来的时间是第几周
+ public static int GetWeekNumInMonth(DateTime daytime)
+ {
+ int dayInMonth = daytime.Day;
+ //本月第一天
+ DateTime firstDay = daytime.AddDays(1 - daytime.Day);
+ //本月第一天是周几
+ int weekday = (int)firstDay.DayOfWeek == 0 ? 7 : (int)firstDay.DayOfWeek;
+ //本月第一周有几天
+ int firstWeekEndDay = 7 - (weekday - 1);
+ //当前日期和第一周之差
+ int diffday = dayInMonth - firstWeekEndDay;
+ diffday = diffday > 0 ? diffday : 1;
+ //当前是第几周,如果整除7就减一天
+ int weekNumInMonth = ((diffday % 7) == 0
+ ? (diffday / 7 - 1)
+ : (diffday / 7)) + 1 + (dayInMonth > firstWeekEndDay ? 1 : 0);
+ return weekNumInMonth;
+ }
+ ///
+ /// 判断一个字符串是否为url
+ ///
+ ///
+ ///
+ public static bool IsUrl(string str)
+ {
+ try
+ {
+ string Url = @"^http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?$";
+ return Regex.IsMatch(str, Url);
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ return false;
+ }
+ }
+
+ ///
+ /// 计算密码强度
+ ///
+ /// 密码字符串
+ ///
+ public static bool PasswordStrength(string password)
+ {
+ //空字符串强度值为0
+ if (string.IsNullOrEmpty(password)) return false;
+
+ //字符统计
+ int iNum = 0, iLtt = 0, iSym = 0;
+ foreach (char c in password)
+ {
+ if (c >= '0' && c <= '9') iNum++;
+ else if (c >= 'a' && c <= 'z') iLtt++;
+ else if (c >= 'A' && c <= 'Z') iLtt++;
+ else iSym++;
+ }
+
+ if (iLtt == 0 && iSym == 0) return false; //纯数字密码
+ if (iNum == 0 && iLtt == 0) return false; //纯符号密码
+ if (iNum == 0 && iSym == 0) return false; //纯字母密码
+
+ if (password.Length >= 6 && password.Length < 16) return true;//长度不大于6的密码
+
+ if (iLtt == 0) return true; //数字和符号构成的密码
+ if (iSym == 0) return true; //数字和字母构成的密码
+ if (iNum == 0) return true; //字母和符号构成的密码
+
+ return true; //由数字、字母、符号构成的密码
+ }
+
+
+ public static string GetNumCode(int lenght)
+ {
+ Random random = new Random();
+ StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < lenght; i++)
+ {
+ stringBuilder.Append(random.Next(1, 10));
+ }
+ return stringBuilder.ToString();
+ }
+
+ // 通过地址获取经纬度
+ public static (double? lng, double? lat, string country, string province, string city, string area, string addr) GetXY(string address, System.Net.Http.HttpClient client)
+ {
+ string gdkey = "ec7484f53ba7b557eac7efc6687e5c0d";//高德key
+ string bdkey = "bnPWCosxo6QwUC7DsfkGiunf4zBZ3ogy";//百度key
+ //高德API会把地址拆分成省市区和坐标返回,百度只返回坐标
+ string url = String.Format("https://restapi.amap.com/v3/geocode/geo?address={0}&output=json&key={1}", address, gdkey);
+ //结果
+ string result = client.GetStringAsync(url).Result;
+ var locationResult = (JObject)JsonConvert.DeserializeObject(result);
+ if (locationResult["status"].ToString() == "1" && locationResult["geocodes"].Count() > 0)
+ {
+ var coordinate = locationResult["geocodes"][0]["location"].ToString().Split(",");
+ var country = locationResult["geocodes"][0]["country"].ToString().Replace("[]", "");
+ var province = locationResult["geocodes"][0]["province"].ToString().Replace("[]", "");
+ var city = locationResult["geocodes"][0]["city"].ToString().Replace("[]", "");
+ var district = locationResult["geocodes"][0]["district"].ToString().Replace("[]", "");
+ var street = locationResult["geocodes"][0]["street"].ToString().Replace("[]", "");
+ var number = locationResult["geocodes"][0]["number"].ToString().Replace("[]", "");
+ double? lng = null, lat = null;
+ if (coordinate.Length == 2)
+ {
+ string lngStr = coordinate[0];
+ string latStr = coordinate[1];
+ lng = double.Parse(lngStr);
+ lat = double.Parse(latStr);
+
+ }
+ return (lng, lat, country, province, city, district, street + number);
+ }
+ else
+ {
+ //百度API
+ url = String.Format("http://api.map.baidu.com/geocoding/v3/?address={0}&output=json&ak={1}", address, bdkey);
+ result = client.GetStringAsync(url).Result;
+ locationResult = (JObject)JsonConvert.DeserializeObject(result);
+ if (locationResult["status"].ToString() == "0")
+ {
+ string lngStr = locationResult["result"]["location"]["lng"].ToString();
+ string latStr = locationResult["result"]["location"]["lat"].ToString();
+ double lng = double.Parse(lngStr);
+ double lat = double.Parse(latStr);
+ return (lng, lat, "", "", "", "", "");
+ }
+ else
+ {
+ return (null, null, "", "", "", "", "");
+ }
+ }
+ }
+
+ }
+}
diff --git a/ARW.Model/ARW.Model.csproj b/ARW.Model/ARW.Model.csproj
new file mode 100644
index 0000000..ddbc471
--- /dev/null
+++ b/ARW.Model/ARW.Model.csproj
@@ -0,0 +1,31 @@
+
+
+
+ net6.0
+ ARW.Model
+ ARW.Model
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ARW.Model/Dto/Business/Customers/CustomerDto.cs b/ARW.Model/Dto/Business/Customers/CustomerDto.cs
new file mode 100644
index 0000000..0fb54dd
--- /dev/null
+++ b/ARW.Model/Dto/Business/Customers/CustomerDto.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using ARW.Model.Models.Business.Customers;
+
+namespace ARW.Model.Dto.Business.Customers
+{
+ ///
+ /// 小程序客户输入对象
+ ///
+ public class CustomerDto
+ {
+ public int CustomerId { get; set; }
+ public long CustomerGuid { get; set; }
+ public string CustomerName { get; set; }
+ public string CustomerBirth { get; set; }
+ public string CustomerImg { get; set; }
+ public int? CustomerSex { get; set; }
+ public string CustomerPhone { get; set; }
+ public string CustomerXcxOpenid { get; set; }
+ public string CustomerXcxName { get; set; }
+ public string CustomerXcxImg { get; set; }
+ }
+
+
+ ///
+ /// 小程序客户查询对象
+ ///
+ public class CustomerQueryDto : PagerInfo
+ {
+ public string CustomerName { get; set; }
+ public string CustomerXcxName { get; set; }
+ }
+}
diff --git a/ARW.Model/Dto/Business/Payments/PaymentDto.cs b/ARW.Model/Dto/Business/Payments/PaymentDto.cs
new file mode 100644
index 0000000..e3f983a
--- /dev/null
+++ b/ARW.Model/Dto/Business/Payments/PaymentDto.cs
@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using ARW.Model.Models.Business.Payments;
+
+namespace ARW.Model.Dto.Business.Payments
+{
+ ///
+ /// 支付订单输入对象
+ ///
+ public class PaymentDto
+ {
+ public int PaymentId { get; set; }
+ public long PaymentGuid { get; set; }
+ public string PaymentOvertimeNumber { get; set; }
+ [Required(ErrorMessage = "操作状态(1待支付 |2已支付 | 3已取消 | 4已退款)不能为空")]
+ public int PaymentStatus { get; set; }
+ public decimal PaymentMoney { get; set; }
+ public decimal PaymentBeforeMoney { get; set; }
+ public string PaymentRefundNumber { get; set; }
+ public string PaymentWeixinNumber { get; set; }
+ [Required(ErrorMessage = "系统订单号不能为空")]
+ public string PaymentNumber { get; set; }
+ [Required(ErrorMessage = "操作客户guid(外键)不能为空")]
+ public string CustomerGuid { get; set; }
+ public long? PaymentBusinessGuid { get; set; }
+ [Required(ErrorMessage = "购买类型(1| )不能为空")]
+ public int PaymentBuytype { get; set; }
+ }
+
+
+ ///
+ /// 支付订单查询对象
+ ///
+ public class PaymentQueryDto : PagerInfo
+ {
+ public int? PaymentStatus { get; set; }
+ }
+}
diff --git a/ARW.Model/Dto/Business/SubscribeTasks/SubscribeTaskDto.cs b/ARW.Model/Dto/Business/SubscribeTasks/SubscribeTaskDto.cs
new file mode 100644
index 0000000..a9b13b4
--- /dev/null
+++ b/ARW.Model/Dto/Business/SubscribeTasks/SubscribeTaskDto.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using ARW.Model.Models.Business.SubscribeTasks;
+
+namespace ARW.Model.Dto.Business.SubscribeTasks
+{
+ ///
+ /// 订阅推送任务输入对象
+ ///
+ public class SubscribeTaskDto
+ {
+ public int SubscribeTaskId { get; set; }
+ public long SubscribeTaskGuid { get; set; }
+ public long? CustomerGuid { get; set; }
+ public long? SubscribeTaskBusinessGuid { get; set; }
+ public int? SubscribeTaskType { get; set; }
+ public string TemplateId { get; set; }
+ public int? SubscribeTaskStatus { get; set; }
+ public string SubscribeTaskErrorMsg { get; set; }
+ }
+
+
+ ///
+ /// 订阅推送任务查询对象
+ ///
+ public class SubscribeTaskQueryDto : PagerInfo
+ {
+ }
+}
diff --git a/ARW.Model/Models/Business/BusinessBase.cs b/ARW.Model/Models/Business/BusinessBase.cs
new file mode 100644
index 0000000..6943b7c
--- /dev/null
+++ b/ARW.Model/Models/Business/BusinessBase.cs
@@ -0,0 +1,52 @@
+using System;
+using Newtonsoft.Json;
+using SqlSugar;
+using OfficeOpenXml.Attributes;
+
+namespace ARW.Model.Models.Business
+{
+
+ [EpplusTable(PrintHeaders = true, AutofitColumns = true, AutoCalculate = true, ShowTotal = true)]
+ public class BusinessBase
+ {
+ [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnName = "create_by", ColumnDescription = "创建者")]//设置后修改不会有此字段
+ [JsonProperty(propertyName: "CreateBy")]
+ [EpplusIgnore]
+ public string Create_by { get; set; }
+
+ [SugarColumn(IsOnlyIgnoreUpdate = true, IsNullable = true, ColumnName = "create_time", ColumnDescription = "创建时间")]//设置后修改不会有此字段
+ [JsonProperty(propertyName: "CreateTime")]
+ [EpplusTableColumn(NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime Create_time { get; set; } = DateTime.Now;
+
+ [JsonIgnore]
+ [JsonProperty(propertyName: "UpdateBy")]
+ [SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true, ColumnName = "update_by", ColumnDescription = "更新者")]
+ [EpplusIgnore]
+ public string Update_by { get; set; }
+
+ //[JsonIgnore]
+ [SugarColumn(IsOnlyIgnoreInsert = true, IsNullable = true, ColumnName = "update_time", ColumnDescription = "更新时间")]//设置后插入数据不会有此字段
+ [JsonProperty(propertyName: "UpdateTime")]
+ [EpplusIgnore]
+ public DateTime? Update_time { get; set; }
+
+ [SugarColumn(IsIgnore = true)]
+ [JsonIgnore]
+ [EpplusIgnore]
+ public DateTime? BeginTime { get; set; }
+
+ ///
+ /// 用于搜索使用
+ ///
+ [SugarColumn(IsIgnore = true)]
+ [JsonIgnore]
+ [EpplusIgnore]
+ public DateTime? EndTime { get; set; }
+
+ [JsonProperty(propertyName: "IsDelete")]
+ [SugarColumn(IsNullable = true, ColumnDescription = "是否删除")]
+ [EpplusIgnore]
+ public bool IsDelete { get; set; }
+ }
+}
diff --git a/ARW.Model/Models/Business/Crawler/Crawl.cs b/ARW.Model/Models/Business/Crawler/Crawl.cs
new file mode 100644
index 0000000..5cc5fda
--- /dev/null
+++ b/ARW.Model/Models/Business/Crawler/Crawl.cs
@@ -0,0 +1,66 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ARW.Model.Models.Business.Crawler
+{
+ [SugarTable("crawl")]
+ public class Crawl: BusinessBase
+ {
+ [SugarColumn(IsPrimaryKey = true,IsIdentity =true)]
+ public int Id { get; set; }
+
+ [SugarColumn(ColumnDescription = "名称", IsNullable = true)]
+ public string Name { get; set; }
+
+ [SugarColumn(ColumnDescription = "简介", IsNullable = true)]
+ public string Intro { get; set; }
+
+ [SugarColumn(ColumnDescription = "图片", IsNullable = true)]
+ public string Cover { get; set; }
+
+ [SugarColumn(ColumnDescription = "链接", IsNullable = true)]
+ public string Link { get; set; }
+
+ [SugarColumn(ColumnDescription = "类型", IsNullable = true)]
+ public string Type { get; set; }
+
+ [SugarColumn(ColumnDescription = "上传时间", IsNullable = true)]
+ public DateTime PublishTime { get; set; }
+
+ [JsonIgnore]
+ [SugarColumn(IsIgnore = true)]
+ public List DownResources { get; set; }
+
+ [SugarColumn(ColumnDescription = "下载资源", IsNullable = true)]
+ public string Resources
+ {
+ get
+ {
+ if (this.DownResources != null)
+ {
+ return JToken.FromObject(this.DownResources).ToString();
+ }
+ else
+ {
+ return "[]";
+ }
+
+ }
+ }
+ }
+
+ public class Resource
+ {
+ public string Description { get; set; }
+
+ public string Link { get; set; }
+ }
+
+}
diff --git a/ARW.Model/Models/Business/Customers/Customer.cs b/ARW.Model/Models/Business/Customers/Customer.cs
new file mode 100644
index 0000000..5b23b64
--- /dev/null
+++ b/ARW.Model/Models/Business/Customers/Customer.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using SqlSugar;
+using OfficeOpenXml.Attributes;
+using Newtonsoft.Json;
+
+namespace ARW.Model.Models.Business.Customers
+{
+ ///
+ /// 小程序客户,数据实体对象
+ ///
+ /// @author admin
+ /// @date 2022-12-06
+ ///
+ [SugarTable("tb_customer")]
+ public class Customer : BusinessBase
+ {
+
+ ///
+ /// 描述 :
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "CustomerId")]
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "customer_id")]
+ public int CustomerId { get; set; }
+
+ ///
+ /// 描述 :
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "CustomerGuid")]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = false, ColumnName = "customer_guid")]
+ public long CustomerGuid { get; set; }
+
+ ///
+ /// 描述 :客户姓名
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "客户姓名")]
+ [SugarColumn(ColumnName = "customer_name")]
+ public string CustomerName { get; set; }
+
+ ///
+ /// 描述 :客户生日
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "客户生日")]
+ [SugarColumn(ColumnName = "customer_birth")]
+ public string CustomerBirth { get; set; }
+
+ ///
+ /// 描述 :客户头像 (人脸识别)
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "客户头像 (人脸识别)")]
+ [SugarColumn(ColumnName = "customer_img")]
+ public string CustomerImg { get; set; }
+
+ ///
+ /// 描述 :客户性别 1: 男 2: 女
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "客户性别 1: 男 2: 女")]
+ [SugarColumn(ColumnName = "customer_sex")]
+ public int? CustomerSex { get; set; }
+
+ ///
+ /// 描述 :客户电话
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "客户电话")]
+ [SugarColumn(ColumnName = "customer_phone")]
+ public string CustomerPhone { get; set; }
+
+ ///
+ /// 描述 :小程序openid
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "小程序openid")]
+ [SugarColumn(ColumnName = "customer_xcx_openid")]
+ public string CustomerXcxOpenid { get; set; }
+
+ ///
+ /// 描述 :小程序名称
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "小程序名称")]
+ [SugarColumn(ColumnName = "customer_xcx_name")]
+ public string CustomerXcxName { get; set; }
+
+ ///
+ /// 描述 :小程序头像
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "小程序头像")]
+ [SugarColumn(ColumnName = "customer_xcx_img")]
+ public string CustomerXcxImg { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Model/Models/Business/Payments/Payment.cs b/ARW.Model/Models/Business/Payments/Payment.cs
new file mode 100644
index 0000000..af8ff0c
--- /dev/null
+++ b/ARW.Model/Models/Business/Payments/Payment.cs
@@ -0,0 +1,118 @@
+using System;
+using System.Collections.Generic;
+using SqlSugar;
+using OfficeOpenXml.Attributes;
+using Newtonsoft.Json;
+
+namespace ARW.Model.Models.Business.Payments
+{
+ ///
+ /// 支付订单,数据实体对象
+ ///
+ /// @author admin
+ /// @date 2022-12-15
+ ///
+ [SugarTable("tb_payment")]
+ public class Payment : BusinessBase
+ {
+
+ ///
+ /// 描述 :
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "PaymentId")]
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "payment_id")]
+ public int PaymentId { get; set; }
+
+ ///
+ /// 描述 :支付订单guid
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "支付订单guid")]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = false, ColumnName = "payment_guid")]
+ public long PaymentGuid { get; set; }
+
+ ///
+ /// 描述 :超时付款订单号
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "超时付款订单号")]
+ [SugarColumn(ColumnName = "payment_overtime_number")]
+ public string PaymentOvertimeNumber { get; set; }
+
+ ///
+ /// 描述 :操作状态(1待支付 |2已支付 | 3已取消 | 4已退款)
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "操作状态(1待支付 |2已支付 | 3已取消 | 4已退款)")]
+ [SugarColumn(ColumnName = "payment_status")]
+ public int PaymentStatus { get; set; }
+
+ ///
+ /// 描述 :核销后价格/操作金额
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "核销后价格/操作金额")]
+ [SugarColumn(ColumnName = "payment_money")]
+ public decimal PaymentMoney { get; set; }
+
+ ///
+ /// 描述 :核销前价格
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "核销前价格")]
+ [SugarColumn(ColumnName = "payment_before_money")]
+ public decimal PaymentBeforeMoney { get; set; }
+
+ ///
+ /// 描述 :退款订单号
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "退款订单号")]
+ [SugarColumn(ColumnName = "payment_refund_number")]
+ public string PaymentRefundNumber { get; set; }
+
+ ///
+ /// 描述 :微信支付订单号
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "微信支付订单号")]
+ [SugarColumn(ColumnName = "payment_weixin_number")]
+ public string PaymentWeixinNumber { get; set; }
+
+ ///
+ /// 描述 :系统订单号
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "系统订单号")]
+ [SugarColumn(ColumnName = "payment_number")]
+ public string PaymentNumber { get; set; }
+
+ ///
+ /// 描述 :操作客户guid(外键)
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "操作客户guid(外键)")]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(ColumnName = "customer_guid")]
+ public long? CustomerGuid { get; set; }
+
+ ///
+ /// 描述 :业务订单guid(外键)
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "业务订单guid(外键)")]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(ColumnName = "payment_business_guid")]
+ public long? PaymentBusinessGuid { get; set; }
+
+ ///
+ /// 描述 :购买类型(1| )
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "购买类型(1| )")]
+ [SugarColumn(ColumnName = "payment_buytype")]
+ public int PaymentBuytype { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Model/Models/Business/SubscribeTasks/SubscribeTask.cs b/ARW.Model/Models/Business/SubscribeTasks/SubscribeTask.cs
new file mode 100644
index 0000000..a5ac25a
--- /dev/null
+++ b/ARW.Model/Models/Business/SubscribeTasks/SubscribeTask.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using SqlSugar;
+using OfficeOpenXml.Attributes;
+using Newtonsoft.Json;
+
+namespace ARW.Model.Models.Business.SubscribeTasks
+{
+ ///
+ /// 订阅推送任务,数据实体对象
+ ///
+ /// @author admin
+ /// @date 2022-12-21
+ ///
+ [SugarTable("tb_subscribe_task")]
+ public class SubscribeTask : BusinessBase
+ {
+
+ ///
+ /// 描述 :推送任务id
+ /// 空值 : false
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "subscribe_task_id")]
+ public int SubscribeTaskId { get; set; }
+
+ ///
+ /// 描述 :推送任务guid
+ /// 空值 : false
+ ///
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = false, ColumnName = "subscribe_task_guid")]
+ public long SubscribeTaskGuid { get; set; }
+
+ ///
+ /// 描述 :订阅客户guid(外键)
+ /// 空值 : true
+ ///
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(ColumnName = "customer_guid")]
+ public long? CustomerGuid { get; set; }
+
+ ///
+ /// 描述 :订阅业务guid(外键)
+ /// 空值 : true
+ ///
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(ColumnName = "subscribe_task_business_guid")]
+ public long? SubscribeTaskBusinessGuid { get; set; }
+
+ ///
+ /// 描述 :订阅类型( 1 | 预约门店健身提醒 )
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "subscribe_task_type")]
+ public int? SubscribeTaskType { get; set; }
+
+ ///
+ /// 描述 :订阅推送模板ID
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "template_id")]
+ public string TemplateId { get; set; }
+
+ ///
+ /// 描述 :推送状态 (0 未推送 | 1 已推送 | 2 推送失败 )
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "subscribe_task_status")]
+ public int? SubscribeTaskStatus { get; set; }
+
+ ///
+ /// 描述 :推送失败原因
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "subscribe_task_error_msg")]
+ public string SubscribeTaskErrorMsg { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Model/PagedInfo.cs b/ARW.Model/PagedInfo.cs
new file mode 100644
index 0000000..d696216
--- /dev/null
+++ b/ARW.Model/PagedInfo.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model
+{
+ ///
+ /// 分页参数
+ ///
+ public class PagedInfo
+ {
+ ///
+ /// 每页行数
+ ///
+ public int PageSize { get; set; } = 10;
+ ///
+ /// 当前页
+ ///
+ public int PageIndex { get; set; } = 1;
+ ///
+ /// 总记录数
+ ///
+ public int TotalNum { get; set; }
+ ///
+ /// 总页数
+ ///
+ public int TotalPage
+ {
+ get
+ {
+ if (TotalNum > 0)
+ {
+ return TotalNum % this.PageSize == 0 ? TotalNum / this.PageSize : TotalNum / this.PageSize + 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+ set { }
+ }
+ public List Result { get; set; }
+ public Dictionary Extra { get; set; } = new Dictionary();
+ public PagedInfo()
+ {
+ }
+ }
+}
diff --git a/ARW.Model/PagerInfo.cs b/ARW.Model/PagerInfo.cs
new file mode 100644
index 0000000..b185410
--- /dev/null
+++ b/ARW.Model/PagerInfo.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model
+{
+ public class PagerInfo
+ {
+ ///
+ /// 当前页码
+ ///
+ public int PageNum { get; set; }
+ public int PageSize { get; set; }
+ ///
+ /// 总记录数
+ ///
+ public int TotalNum { get; set; }
+ ///
+ /// 总页码
+ ///
+ ///
+ /// 总页数
+ ///
+ public int TotalPage
+ {
+ get
+ {
+ return TotalNum > 0 ? TotalNum % PageSize == 0 ? TotalNum / PageSize : TotalNum / PageSize + 1 : 0;
+ }
+ }
+
+ ///
+ /// 排序字段
+ ///
+ public string Sort { get; set; } = string.Empty;
+ ///
+ /// 排序类型,前端传入的是"ascending","descending"
+ ///
+ public string SortType { get; set; } = string.Empty;
+ public PagerInfo()
+ {
+ PageNum = 1;
+ PageSize = 10;
+ }
+
+ public PagerInfo(int page = 1, int pageSize = 20)
+ {
+ PageNum = page;
+ PageSize = pageSize;
+ }
+ }
+}
diff --git a/ARW.Model/System/CommonLang.cs b/ARW.Model/System/CommonLang.cs
new file mode 100644
index 0000000..d5fd9c7
--- /dev/null
+++ b/ARW.Model/System/CommonLang.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using SqlSugar;
+using OfficeOpenXml.Attributes;
+using Newtonsoft.Json;
+
+namespace ARW.Model.Models
+{
+ ///
+ /// 多语言配置,数据实体对象
+ ///
+ /// @author
+ ///
+ /// @date 2022-05-06
+ ///
+ [Tenant("0")]
+ [SugarTable("sys_common_lang")]
+ public class CommonLang
+ {
+ ///
+ /// 描述 : id
+ /// 空值 : false
+ ///
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [EpplusTableColumn(Header = "id")]
+ [SugarColumn(IsPrimaryKey = true)]
+ public long Id { get; set; }
+
+ ///
+ /// 描述 : 语言code
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "语言code")]
+ [SugarColumn(ColumnName = "lang_code")]
+ public string LangCode { get; set; }
+
+ ///
+ /// 描述 : 语言key
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "语言key")]
+ [SugarColumn(ColumnName = "lang_key")]
+ public string LangKey { get; set; }
+
+ ///
+ /// 描述 : 名称
+ /// 空值 : false
+ ///
+ [EpplusTableColumn(Header = "名称")]
+ [SugarColumn(ColumnName = "lang_name")]
+ public string LangName { get; set; }
+
+ ///
+ /// 描述 : 添加时间
+ /// 空值 : true
+ ///
+ [EpplusTableColumn(Header = "添加时间", NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime? Addtime { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Model/System/Dto/CommonLangDto.cs b/ARW.Model/System/Dto/CommonLangDto.cs
new file mode 100644
index 0000000..9f28e07
--- /dev/null
+++ b/ARW.Model/System/Dto/CommonLangDto.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+
+namespace ARW.Model.Dto
+{
+ ///
+ /// 多语言配置输入对象
+ ///
+ public class CommonLangDto
+ {
+ //[Required(ErrorMessage = "id不能为空")]
+ public long Id { get; set; }
+ //[Required(ErrorMessage = "语言code不能为空")]
+ public string LangCode { get; set; }
+ public string LangKey { get; set; }
+ //[Required(ErrorMessage = "名称不能为空")]
+ public string LangName { get; set; }
+ public List LangList { get; set; }
+ }
+
+ ///
+ /// 多语言配置查询对象
+ ///
+ public class CommonLangQueryDto : PagerInfo
+ {
+ public string LangCode { get; set; }
+ public string LangKey { get; set; }
+ public DateTime? BeginAddtime { get; set; }
+ public DateTime? EndAddtime { get; set; }
+ public int ShowMode { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/GenTableDto.cs b/ARW.Model/System/Dto/GenTableDto.cs
new file mode 100644
index 0000000..514b7e5
--- /dev/null
+++ b/ARW.Model/System/Dto/GenTableDto.cs
@@ -0,0 +1,81 @@
+using System.Collections.Generic;
+using ARW.Model.System.Generate;
+
+namespace ARW.Model.System.Dto
+{
+ public class GenTableDto
+ {
+ public int TableId { get; set; }
+ public string TableName { get; set; }
+ public string TableComment { get; set; }
+ public string SubTableName { get; set; }
+ public string SubTableFkName { get; set; }
+ public string ClassName { get; set; }
+ public string TplCategory { get; set; }
+ public string BaseNameSpace { get; set; }
+ public string ModuleName { get; set; }
+ public string BusinessName { get; set; }
+ public string FunctionName { get; set; }
+ public string FunctionAuthor { get; set; }
+ public string GenType { get; set; }
+ public string GenPath { get; set; }
+ //public string PermissionPrefix { get; set; }
+ public string Remark { get; set; }
+ ///
+ /// 额外参数
+ ///
+ public Options Params { get; set; }
+ public List Columns { get; set; }
+ }
+
+ ///
+ /// 额外参数
+ /// ****注意里面参数统一首字母小写*****
+ ///
+ 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; }
+ ///
+ /// 额外参数字符串
+ ///
+ public string CheckedBtn { get; set; }
+ public string PermissionPrefix { get; set; }
+ }
+ public class GenTableColumnDto
+ {
+ public int ColumnId { get; set; }
+ public int TableId { get; set; }
+ public string ColumnComment { get; set; }
+ public string CsharpType { get; set; }
+ public string CsharpField { get; set; }
+ public bool IsInsert { get; set; }
+ public bool IsEdit { get; set; }
+ public bool IsList { get; set; }
+ public bool IsQuery { get; set; }
+ public bool IsSort { get; set; }
+ public bool IsRequired { get; set; }
+ ///
+ /// 显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)
+ ///
+ public string HtmlType { get; set; }
+ ///
+ /// 查询类型(等于、不等于、大于、小于、范围)
+ ///
+ public string QueryType { get; set; } = "EQ";
+ public int Sort { get; set; }
+ ///
+ /// 字典类型
+ ///
+ public string DictType { get; set; }
+ ///
+ /// 备注
+ ///
+ public string Remark { get; set; }
+ }
+
+}
diff --git a/ARW.Model/System/Dto/LoginBodyDto.cs b/ARW.Model/System/Dto/LoginBodyDto.cs
new file mode 100644
index 0000000..00d06c1
--- /dev/null
+++ b/ARW.Model/System/Dto/LoginBodyDto.cs
@@ -0,0 +1,45 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace ARW.Model.System.Dto
+{
+ public class LoginBodyDto
+ {
+ ///
+ /// 用户名
+ ///
+ [Required(ErrorMessage = "用户名不能为空")]
+ public string Username { get; set; }
+
+ ///
+ /// 用户密码
+ ///
+ [Required(ErrorMessage = "密码不能为空")]
+ public string Password { get; set; }
+
+ /**
+ * 验证码
+ */
+ public string Code { get; set; }
+
+ /**
+ * 唯一标识
+ */
+ public string Uuid { get; set; } = "";
+ public string LoginIP { get; set; }
+ }
+
+ public class PostEmailDto
+ {
+ public string Email { get; set; }
+ }
+
+ public class ChangePwByEmailDto
+ {
+ public string Email { get; set; }
+
+ public string code { get; set; }
+
+ public string Password { get; set; }
+
+ }
+}
diff --git a/ARW.Model/System/Dto/MenuDto.cs b/ARW.Model/System/Dto/MenuDto.cs
new file mode 100644
index 0000000..58e0c5d
--- /dev/null
+++ b/ARW.Model/System/Dto/MenuDto.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ public class MenuDto
+ {
+ //{"parentId":0,"menuName":"aaa","icon":"documentation","menuType":"M","orderNum":999,"visible":0,"status":0,"path":"aaa"}
+ [Required(ErrorMessage = "菜单id不能为空")]
+ public int MenuId { get; set; }
+ public string MenuName { get; set; }
+ ///
+ /// 父菜单ID
+ ///
+ public long? parentId { get; set; }
+
+ ///
+ /// 显示顺序
+ ///
+ public int orderNum { get; set; }
+
+ ///
+ /// 路由地址
+ ///
+ public string path { get; set; } = "#";
+
+ ///
+ /// 组件路径
+ ///
+ public string component { get; set; }
+
+ ///
+ /// 是否缓存(1缓存 0不缓存)
+ ///
+ [Required(ErrorMessage = "是否缓存不能为空")]
+ public string isCache { get; set; }
+ ///
+ /// 是否外链 1、是 0、否
+ ///
+ public string isFrame { get; set; }
+
+ ///
+ /// 类型(M目录 C菜单 F按钮 L链接)
+ ///
+ [Required(ErrorMessage = "菜单类型不能为空")]
+ public string menuType { get; set; }
+
+ ///
+ /// 显示状态(0显示 1隐藏)
+ ///
+ [Required(ErrorMessage = "显示状态不能为空")]
+ public string visible { get; set; }
+
+ ///
+ /// 菜单状态(0正常 1停用)
+ ///
+ [Required(ErrorMessage = "菜单状态不能为空")]
+ public string status { get; set; }
+
+ ///
+ /// 权限字符串
+ ///
+ public string perms { get; set; }
+
+ ///
+ /// 菜单图标
+ ///
+ public string icon { get; set; } = string.Empty;
+ ///
+ /// 翻译key
+ ///
+ public string MenuNameKey { get; set; }
+ }
+
+ public class MenuQueryDto
+ {
+ public string MenuName { get; set; }
+ public string Visible { get; set; }
+ public string Status { get; set; }
+ public string MenuTypeIds { get; set; } = string.Empty;
+ public int? ParentId { get; set; }
+ public string[] MenuTypeIdArr
+ {
+ get
+ {
+ return MenuTypeIds.Split(',', StringSplitOptions.RemoveEmptyEntries);
+ }
+ }
+ }
+}
diff --git a/ARW.Model/System/Dto/RegisterDto.cs b/ARW.Model/System/Dto/RegisterDto.cs
new file mode 100644
index 0000000..38159c2
--- /dev/null
+++ b/ARW.Model/System/Dto/RegisterDto.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ public class RegisterDto
+ {
+ ///
+ /// 用户名
+ ///
+ [Required(ErrorMessage = "用户名不能为空")]
+ public string Username { get; set; }
+
+ ///
+ /// 用户密码
+ ///
+ [Required(ErrorMessage = "密码不能为空")]
+ public string Password { get; set; }
+ [Required(ErrorMessage = "确认密码不能为空")]
+ public string ConfirmPassword { get; set; }
+ /**
+ * 验证码
+ */
+ public string Code { get; set; }
+
+ /**
+ * 唯一标识
+ */
+ public string Uuid { get; set; } = "";
+ }
+}
diff --git a/ARW.Model/System/Dto/RoleUserDto.cs b/ARW.Model/System/Dto/RoleUserDto.cs
new file mode 100644
index 0000000..f8b9e35
--- /dev/null
+++ b/ARW.Model/System/Dto/RoleUserDto.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ public class RoleUserQueryDto : PagerInfo
+ {
+ public long RoleId { get; set; }
+
+ public string UserName { get; set; }
+ }
+
+ public class RoleUsersCreateDto
+ {
+ ///
+ /// 描述 : 角色id
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "角色id")]
+ [Required(ErrorMessage = "roleId 不能为空")]
+ public long RoleId { get; set; }
+
+ ///
+ /// 描述 : 用户编码 [1,2,3,4]
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "用户编码 [1,2,3,4]")]
+ public List UserIds { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysConfigDto.cs b/ARW.Model/System/Dto/SysConfigDto.cs
new file mode 100644
index 0000000..4c985ef
--- /dev/null
+++ b/ARW.Model/System/Dto/SysConfigDto.cs
@@ -0,0 +1,30 @@
+using System;
+
+namespace ARW.Model.System.Dto
+{
+ ///
+ /// 参数配置输入对象模型
+ ///
+ public class SysConfigDto
+ {
+ public int ConfigId { get; set; }
+ public string ConfigName { get; set; }
+ public string ConfigKey { get; set; }
+ public string ConfigValue { get; set; }
+ public string ConfigType { get; set; }
+ public string Remark { get; set; }
+ }
+
+ ///
+ /// 参数配置查询对象模型
+ ///
+ public class SysConfigQueryDto : PagerInfo
+ {
+ public string ConfigName { get; set; }
+ public string ConfigKey { get; set; }
+ public string ConfigValue { get; set; }
+ public string ConfigType { get; set; }
+ public DateTime? BeginTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysFileQueryDto.cs b/ARW.Model/System/Dto/SysFileQueryDto.cs
new file mode 100644
index 0000000..879e612
--- /dev/null
+++ b/ARW.Model/System/Dto/SysFileQueryDto.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ ///
+ /// 文件存储输入对象
+ ///
+ public class SysFileDto
+ {
+ public long Id { get; set; }
+ ///
+ /// 文件原名
+ ///
+ public string RealName { get; set; }
+ ///
+ /// 文件类型
+ ///
+ public string FileType { get; set; }
+ ///
+ /// 描述 : 存储文件名
+ /// 空值 : true
+ ///
+ public string FileName { get; set; }
+ ///
+ /// 描述 : 文件存储地址 eg:/uploads/20220202
+ /// 空值 : true
+ ///
+ public string FileUrl { get; set; }
+ ///
+ /// 描述 : 仓库位置 eg:/uploads
+ /// 空值 : true
+ ///
+ public string StorePath { get; set; }
+ ///
+ /// 描述 : 文件大小
+ /// 空值 : true
+ ///
+ public string FileSize { get; set; }
+ ///
+ /// 描述 : 文件扩展名
+ /// 空值 : true
+ ///
+ public string FileExt { get; set; }
+ ///
+ /// 描述 : 创建人
+ /// 空值 : true
+ ///
+ public string Create_by { get; set; }
+ ///
+ /// 描述 : 上传时间
+ /// 空值 : true
+ ///
+ public DateTime? Create_time { get; set; }
+ ///
+ /// 描述 : 存储类型
+ /// 空值 : true
+ ///
+ public int? StoreType { get; set; }
+ ///
+ /// 描述 : 访问路径
+ /// 空值 : true
+ ///
+ public string AccessUrl { get; set; }
+
+ public SysFileDto() { }
+ public SysFileDto(string originFileName, string fileName, string ext, string fileSize, string storePath, string accessUrl, string create_by)
+ {
+ StorePath = storePath;
+ RealName = originFileName;
+ FileName = fileName;
+ FileExt = ext;
+ FileSize = fileSize;
+ AccessUrl = accessUrl;
+ Create_by = create_by;
+ Create_time = DateTime.Now;
+ }
+ }
+ public class SysFileQueryDto : PagerInfo
+ {
+ public DateTime? BeginCreate_time { get; set; }
+ public DateTime? EndCreate_time { get; set; }
+ public int? StoreType { get; set; }
+ public long? FileId { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysLogininfoDto.cs b/ARW.Model/System/Dto/SysLogininfoDto.cs
new file mode 100644
index 0000000..5a0f25d
--- /dev/null
+++ b/ARW.Model/System/Dto/SysLogininfoDto.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ARW.Model.System;
+
+namespace ARW.Model.System.Dto
+{
+ public class SysLogininfoDto : SysBase
+ {
+ public int pageNum { get; set; }
+ ///
+ /// IP 地址
+ ///
+ public string Ipaddr { get; set; }
+ ///
+ /// 登录状态 0成功 1失败
+ ///
+ public string Status { get; set; }
+ ///
+ /// 用户名
+ ///
+ public string UserName { get; set; }
+
+ }
+}
diff --git a/ARW.Model/System/Dto/SysNoticeDto.cs b/ARW.Model/System/Dto/SysNoticeDto.cs
new file mode 100644
index 0000000..7fef20f
--- /dev/null
+++ b/ARW.Model/System/Dto/SysNoticeDto.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using Newtonsoft.Json;
+using ARW.Model.Models;
+
+namespace ARW.Model.System.Dto
+{
+ ///
+ /// 通知公告表输入对象
+ ///
+ public class SysNoticeDto
+ {
+ public int NoticeId { get; set; }
+ public string NoticeTitle { get; set; }
+ public string NoticeType { get; set; }
+ public string NoticeContent { get; set; }
+ public string Status { get; set; }
+ public string Remark { get; set; }
+ }
+
+ ///
+ /// 通知公告表查询对象
+ ///
+ public class SysNoticeQueryDto : PagerInfo
+ {
+ public string NoticeTitle { get; set; }
+ public string NoticeType { get; set; }
+ public string CreateBy { get; set; }
+ public string Status { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysOperLogDto.cs b/ARW.Model/System/Dto/SysOperLogDto.cs
new file mode 100644
index 0000000..9cccbcd
--- /dev/null
+++ b/ARW.Model/System/Dto/SysOperLogDto.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ARW.Model.System;
+
+namespace ARW.Model.System.Dto
+{
+ public class SysOperLogDto : SysBase
+ {
+ ///
+ /// 页码
+ ///
+ public int pageNum { get; set; }
+ public int PageSize { get; set; }
+ ///
+ /// 操作人员
+ ///
+ public string operName { get; set; }
+ ///
+ /// 业务类型 0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据
+ ///
+ public int BusinessType { get; set; } = -1;
+ ///
+ /// 状态
+ ///
+ public int Status { get; set; } = -1;
+ ///
+ /// 操作模块
+ ///
+ public string Title { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysRoleDto.cs b/ARW.Model/System/Dto/SysRoleDto.cs
new file mode 100644
index 0000000..59df3e9
--- /dev/null
+++ b/ARW.Model/System/Dto/SysRoleDto.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ARW.Model.System;
+
+namespace ARW.Model.System.Dto
+{
+ public class SysRoleDto: SysBase
+ {
+ public long RoleId { get; set; }
+ ///
+ /// 角色分配菜单
+ ///
+ public List MenuIds { get; set; } = new List();
+ public string RoleName { get; set; }
+ public string RoleKey { get; set; }
+ public int RoleSort { get; set; }
+ public string Status { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysUserDto.cs b/ARW.Model/System/Dto/SysUserDto.cs
new file mode 100644
index 0000000..ddcacc4
--- /dev/null
+++ b/ARW.Model/System/Dto/SysUserDto.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ARW.Model.System;
+
+namespace ARW.Model.System.Dto
+{
+ public class SysUserDto
+ {
+ public long UserId { get; set; }
+ public string UserName { get; set; }
+ public string NickName { get; set; }
+ public string Email { get; set; }
+ public string Remark { get; set; }
+ public string Phonenumber { get; set; }
+ ///
+ /// '用户性别(0男 1女 2未知)',
+ ///
+ public int Sex { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/SysdictDataDto.cs b/ARW.Model/System/Dto/SysdictDataDto.cs
new file mode 100644
index 0000000..3490829
--- /dev/null
+++ b/ARW.Model/System/Dto/SysdictDataDto.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ public class SysdictDataDto
+ {
+ public string DictType { get; set; }
+ public string ColumnName { get; set; }
+ public List List { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/TasksDto.cs b/ARW.Model/System/Dto/TasksDto.cs
new file mode 100644
index 0000000..95811ad
--- /dev/null
+++ b/ARW.Model/System/Dto/TasksDto.cs
@@ -0,0 +1,233 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ public class TasksQueryDto
+ {
+ ///
+ /// 描述 : 查询字符串
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "查询字符串")]
+ public string QueryText { get; set; }
+ }
+
+ ///
+ /// 添加任务
+ ///
+ public class TasksCreateDto
+ {
+ ///
+ /// 描述 : 任务名称
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务名称")]
+ [Required(ErrorMessage = "任务名称不能为空")]
+ public string Name { get; set; }
+
+ ///
+ /// 描述 : 任务分组
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务分组")]
+ [Required(ErrorMessage = "任务分组不能为空")]
+ public string JobGroup { get; set; }
+
+ ///
+ /// 描述 : 运行时间表达式
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "运行时间表达式")]
+ public string Cron { get; set; }
+
+ ///
+ /// 描述 : 程序集名称
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "程序集名称")]
+ //[Required(ErrorMessage = "程序集名称不能为空")]
+ public string AssemblyName { get; set; }
+
+ ///
+ /// 描述 : 任务所在类
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务所在类")]
+ //[Required(ErrorMessage = "任务所在类不能为空")]
+ public string ClassName { get; set; }
+
+ ///
+ /// 描述 : 任务描述
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "任务描述")]
+ public string Remark { get; set; }
+
+ ///
+ /// 描述 : 开始时间
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "开始时间")]
+ public DateTime? BeginTime { get; set; }
+
+ ///
+ /// 描述 : 结束时间
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "结束时间")]
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 描述 : 触发器类型(0、simple 1、cron)
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "触发器类型(0、simple 1、cron)")]
+ public int TriggerType { get; set; }
+
+ ///
+ /// 描述 : 执行间隔时间(单位:秒)
+ /// 空值 : False
+ /// 默认 : 0
+ ///
+ [Display(Name = "执行间隔时间(单位:秒)")]
+ public int IntervalSecond { get; set; }
+
+ ///
+ /// 描述 : 传入参数
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "传入参数")]
+ public string JobParams { get; set; }
+ public string ApiUrl { get; set; }
+ ///
+ /// 1、程序集任务 2、apiUrl任务
+ ///
+ public int TaskType { get; set; }
+ }
+
+ ///
+ /// 更新任务
+ ///
+ public class TasksUpdateDto
+ {
+ ///
+ /// 描述 : UID
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "UID")]
+ [Required(ErrorMessage = "UID不能为空")]
+ public string ID { get; set; }
+
+ ///
+ /// 描述 : 任务名称
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务名称")]
+ [Required(ErrorMessage = "任务名称不能为空")]
+ public string Name { get; set; }
+
+ ///
+ /// 描述 : 任务分组
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务分组")]
+ [Required(ErrorMessage = "任务分组不能为空")]
+ public string JobGroup { get; set; }
+
+ ///
+ /// 描述 : 运行时间表达式
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "运行时间表达式")]
+ public string Cron { get; set; }
+
+ ///
+ /// 描述 : 程序集名称
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "程序集名称")]
+ [Required(ErrorMessage = "程序集名称不能为空")]
+ public string AssemblyName { get; set; }
+
+ ///
+ /// 描述 : 任务所在类
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务所在类")]
+ [Required(ErrorMessage = "任务所在类不能为空")]
+ public string ClassName { get; set; }
+
+ ///
+ /// 描述 : 任务描述
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "任务描述")]
+ public string Remark { get; set; }
+
+ ///
+ /// 描述 : 开始时间
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "开始时间")]
+ public DateTime? BeginTime { get; set; }
+
+ ///
+ /// 描述 : 结束时间
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "结束时间")]
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 描述 : 触发器类型(0、simple 1、cron)
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "触发器类型(0、simple 1、cron)")]
+ public int TriggerType { get; set; }
+
+ ///
+ /// 描述 : 执行间隔时间(单位:秒)
+ /// 空值 : False
+ /// 默认 : 0
+ ///
+ [Display(Name = "执行间隔时间(单位:秒)")]
+ public int IntervalSecond { get; set; }
+
+ ///
+ /// 描述 : 传入参数
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "传入参数")]
+ public string JobParams { get; set; }
+ public string ApiUrl { get; set; }
+ ///
+ /// 1、程序集任务 2、apiUrl任务
+ ///
+ public int TaskType { get; set; }
+ }
+}
diff --git a/ARW.Model/System/Dto/TasksLogDto.cs b/ARW.Model/System/Dto/TasksLogDto.cs
new file mode 100644
index 0000000..9899216
--- /dev/null
+++ b/ARW.Model/System/Dto/TasksLogDto.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System.Dto
+{
+ public class TasksLogQueryDto
+ {
+ ///
+ /// 描述 : 查询字符串
+ /// 空值 : False
+ /// 默认 :
+ ///
+ //[Display(Name = "查询字符串")]
+ public string Name{ get; set; }
+ public string JobName { get; set; }
+ public string JobId { get; set; }
+ public string JobGroup { get; set; }
+ public string Status { get; set; }
+ public DateTime? BeginTime { get; set; }
+ public DateTime? EndTime { get; set; }
+ }
+
+ public class TasksLogDto
+ {
+
+ }
+}
diff --git a/ARW.Model/System/Generate/GenTable.cs b/ARW.Model/System/Generate/GenTable.cs
new file mode 100644
index 0000000..db2dc81
--- /dev/null
+++ b/ARW.Model/System/Generate/GenTable.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System.Generate
+{
+ ///
+ /// 代码生成表
+ ///
+ [SqlSugar.SugarTable("gen_table")]
+ [SqlSugar.Tenant("0")]
+ public class GenTable : SysBase
+ {
+ ///
+ /// 表id
+ ///
+ [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public int TableId { get; set; }
+ ///
+ /// 数据库名
+ ///
+ public string DbName { get; set; }
+ ///
+ /// 表名
+ ///
+ public string TableName { get; set; }
+ ///
+ /// 表描述
+ ///
+ public string TableComment { get; set; }
+ ///
+ /// 关联父表的表名
+ ///
+ public string SubTableName { get; set; }
+ ///
+ /// 本表关联父表的外键名
+ ///
+ public string SubTableFkName { get; set; }
+ ///
+ /// csharp类名
+ ///
+ public string ClassName { get; set; }
+ ///
+ /// 使用的模板(crud单表操作 tree树表操作 sub主子表操作)
+ ///
+ public string TplCategory { get; set; }
+ ///
+ /// 基本命名空间前缀
+ ///
+ public string BaseNameSpace { get; set; }
+ ///
+ /// 生成模块名
+ ///
+ public string ModuleName { get; set; }
+ ///
+ /// 生成业务名
+ ///
+ public string BusinessName { get; set; }
+ ///
+ /// 生成功能名
+ ///
+ public string FunctionName { get; set; }
+ ///
+ /// 生成作者名
+ ///
+ public string FunctionAuthor { get; set; }
+ ///
+ /// 生成代码方式(0zip压缩包 1自定义路径)
+ ///
+ public string GenType { get; set; }
+ public string GenPath { get; set; }
+ ///
+ /// 其他生成选项
+ ///
+ [SqlSugar.SugarColumn(IsJson = true, ColumnDataType = "nvarchar(4000)")]
+ public Options Options { get; set; }
+
+ #region 表额外字段
+ /** 表列信息 */
+ [SqlSugar.SugarColumn(IsIgnore = true)]
+ public List Columns { get; set; }
+
+ ///
+ /// 字表信息
+ ///
+ [SqlSugar.SugarColumn(IsIgnore = true)]
+ public GenTable SubTable { get; set; }
+ #endregion
+ }
+
+ public class Options
+ {
+ public long ParentMenuId { get; set; } = 0;
+ public string SortType { get; set; } = "asc";
+ public string SortField { get; set; } = string.Empty;
+ public string TreeCode { get; set; } = string.Empty;
+ public string TreeName { get; set; } = string.Empty;
+ public string TreeParentCode { get; set; } = string.Empty;
+ public string PermissionPrefix { get; set; }= string.Empty;
+ ///
+ /// 额外参数字符串
+ ///
+ public int[] CheckedBtn { get; set; } = new int[] { 1, 2, 3 };
+ ///
+ /// 列大小 12,24
+ ///
+ public int ColNum { get; set; } = 12;
+ }
+}
diff --git a/ARW.Model/System/Generate/GenTableColumn.cs b/ARW.Model/System/Generate/GenTableColumn.cs
new file mode 100644
index 0000000..36b60c7
--- /dev/null
+++ b/ARW.Model/System/Generate/GenTableColumn.cs
@@ -0,0 +1,139 @@
+using SqlSugar;
+using System;
+using System.Linq;
+
+namespace ARW.Model.System.Generate
+{
+ ///
+ /// 代码生成表字段
+ ///
+ [SugarTable("gen_table_column")]
+ [Tenant("0")]
+ public class GenTableColumn : SysBase
+ {
+ [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
+ public int ColumnId { get; set; }
+ ///
+ /// 导入代码生成表列名 首字母转了小写
+ ///
+ public string ColumnName { get; set; }
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]
+ public int TableId { get; set; }
+
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]
+ public string TableName { get; set; }
+ ///
+ /// 列说明
+ ///
+ public string ColumnComment { get; set; } = string.Empty;
+ ///
+ /// 数据库列类型
+ ///
+
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]
+ public string ColumnType { get; set; }
+ ///
+ /// C#类型
+ ///
+ public string CsharpType { get; set; }
+ ///
+ /// C# 字段名 首字母大写
+ ///
+ public string CsharpField { get; set; }
+ ///
+ /// 是否主键(1是)
+ ///
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]
+ public bool IsPk { get; set; }
+ ///
+ /// 是否必填(1是)
+ ///
+ public bool IsRequired { get; set; }
+ ///
+ /// 是否自增(1是)
+ ///
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]
+ public bool IsIncrement { get; set; }
+ ///
+ /// 是否插入(1是)
+ ///
+ public bool IsInsert { get; set; }
+ ///
+ /// 是否需要编辑(1是)
+ ///
+ public bool IsEdit { get; set; }
+ ///
+ /// 是否显示列表(1是)
+ ///
+ public bool IsList { get; set; }
+ ///
+ /// 是否查询(1是)
+ ///
+ public bool IsQuery { get; set; }
+ ///
+ /// 是否排序(1是)
+ ///
+ public bool IsSort { get; set; }
+ ///
+ /// 是否初始化字段(1是)
+ ///
+ public bool IsInit { get; set; }
+ ///
+ /// 是否Guid(1是)
+ ///
+ public bool IsGuid { get; set; }
+ ///
+ /// 显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)
+ ///
+ public string HtmlType { get; set; }
+ ///
+ /// 查询类型(等于、不等于、大于、小于、范围)
+ ///
+ public string QueryType { get; set; } = "EQ";
+ public int Sort { get; set; }
+ ///
+ /// 字典类型
+ ///
+ public string DictType { get; set; } = "";
+
+ #region 额外字段
+ [SugarColumn(IsIgnore = true)]
+ public string RequiredStr
+ {
+ get
+ {
+ string[] arr = new string[] { "int", "long" };
+ return (!IsRequired && (arr.Any(f => f.Contains(CsharpType))) || typeof(DateTime).Name == CsharpType) ? "?" : "";
+ }
+ }
+ ///
+ /// 前端排序字符串
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public string SortStr
+ {
+ get
+ {
+ return IsSort ? " sortable" : "";
+ }
+ }
+ ///
+ /// C# 字段名 首字母小写,用于前端
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public string CsharpFieldFl { get; set; }
+ ///
+ /// 前端 只读字段
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public string DisabledStr
+ {
+ get
+ {
+ return (((!IsInsert && !IsEdit) || IsPk) && !IsRequired) ? " :disabled=\"true\"" : "";
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/ARW.Model/System/LoginUser.cs b/ARW.Model/System/LoginUser.cs
new file mode 100644
index 0000000..75b8f4d
--- /dev/null
+++ b/ARW.Model/System/LoginUser.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 登录用户信息存储
+ ///
+ public class LoginUser
+ {
+ public long UserId { get; set; }
+ public long DeptId { get; set; }
+ public string UserName { get; set; }
+
+ public bool IsApi { get; set; }
+
+ ///
+ /// 角色集合
+ ///
+ public List RoleIds { get; set; }
+ ///
+ /// 角色集合(数据权限过滤使用)
+ ///
+ public List Roles { get; set; }
+ ///
+ /// 权限集合
+ ///
+ public List Permissions { get; set; } = new List();
+ public LoginUser()
+ {
+ }
+
+ public LoginUser(SysUser user, List roles, List permissions)
+ {
+ UserId = user.UserId;
+ UserName = user.UserName;
+ DeptId = user.DeptId;
+ Roles = roles;
+ RoleIds = roles.Select(f => f.RoleKey).ToList();
+ Permissions = permissions;
+ }
+ }
+}
diff --git a/ARW.Model/System/SysBase.cs b/ARW.Model/System/SysBase.cs
new file mode 100644
index 0000000..840c44b
--- /dev/null
+++ b/ARW.Model/System/SysBase.cs
@@ -0,0 +1,65 @@
+//using Dapper.Contrib.Extensions;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SqlSugar;
+using OfficeOpenXml.Attributes;
+
+namespace ARW.Model.System
+{
+ [EpplusTable(PrintHeaders = true, AutofitColumns = true, AutoCalculate = true, ShowTotal = true)]
+ public class SysBase
+ {
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]//设置后修改不会有此字段
+ [JsonProperty(propertyName: "CreateBy")]
+ [EpplusIgnore]
+ public string Create_by { get; set; }
+
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]//设置后修改不会有此字段
+ [JsonProperty(propertyName: "CreateTime")]
+ [EpplusTableColumn(NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime Create_time { get; set; } = DateTime.Now;
+
+ [JsonIgnore]
+ [JsonProperty(propertyName: "UpdateBy")]
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ [EpplusIgnore]
+ public string Update_by { get; set; }
+
+ //[JsonIgnore]
+ [SugarColumn(IsOnlyIgnoreInsert = true)]//设置后插入数据不会有此字段
+ [JsonProperty(propertyName: "UpdateTime")]
+ [EpplusIgnore]
+ public DateTime? Update_time { get; set; }
+
+ public string Remark { get; set; }
+
+ ///
+ /// 搜索时间起始时间
+ ///
+ ///
+ /// Write:需穿一个bool值,false时insert,update等操作会忽略此列(和Computed的作用差不多,看了源码也没发现与Computed有什么不一样的地方,有了解的朋友可以赐教下哈)
+ /// ExplicitKey:指定此列为主键(不自动增长类型例如guid,ExplicitKey与Key地区别下面会详细讲)
+ /// Key:指定此列为主键(自动增长主键),可忽略,忽略后默认查找
+ /// [Computed]计算属性,打上此标签,对象地insert,update等操作会忽略此列
+ ///
+ [SugarColumn(IsIgnore = true)]
+ [JsonIgnore]
+ [EpplusIgnore]
+ public DateTime? BeginTime { get; set; }
+
+ ///
+ /// 用于搜索使用
+ ///
+ [SugarColumn(IsIgnore = true)]
+ [JsonIgnore]
+ [EpplusIgnore]
+ public DateTime? EndTime { get; set; }
+
+ [JsonProperty(propertyName: "IsDelete")]
+ [SugarColumn(IsNullable = true)]
+ [EpplusIgnore]
+ public bool IsDelete { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysConfig.cs b/ARW.Model/System/SysConfig.cs
new file mode 100644
index 0000000..c38d7f1
--- /dev/null
+++ b/ARW.Model/System/SysConfig.cs
@@ -0,0 +1,46 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 参数配置,数据实体对象
+ ///
+ /// @author zhaorui
+ /// @date 2021-09-29
+ ///
+ [SugarTable("sys_config")]
+ [Tenant("0")]
+ public class SysConfig: SysBase
+ {
+ ///
+ /// 描述 :
+ /// 空值 :False
+ ///
+ [SqlSugar.SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public int ConfigId { get; set; }
+ ///
+ /// 描述 :
+ /// 空值 :True
+ ///
+ public string ConfigName { get; set; }
+ ///
+ /// 描述 :
+ /// 空值 :True
+ ///
+ public string ConfigKey { get; set; }
+ ///
+ /// 描述 :
+ /// 空值 :True
+ ///
+ public string ConfigValue { get; set; }
+ ///
+ /// 描述 :
+ /// 空值 :True
+ ///
+ public string ConfigType { get; set; }
+
+ }
+}
diff --git a/ARW.Model/System/SysDept.cs b/ARW.Model/System/SysDept.cs
new file mode 100644
index 0000000..f5abb93
--- /dev/null
+++ b/ARW.Model/System/SysDept.cs
@@ -0,0 +1,58 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 部门表
+ ///
+ [SugarTable("sys_dept")]
+ [Tenant("0")]
+ public class SysDept: SysBase
+ {
+ /** 部门ID */
+ [SqlSugar.SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
+ public long DeptId { get; set; }
+
+ /** 父部门ID */
+ public long ParentId { get; set; }
+
+ /** 祖级列表 */
+ public string Ancestors { get; set; }
+
+ /** 部门名称 */
+ public string DeptName { get; set; }
+
+ /** 显示顺序 */
+ public int OrderNum { get; set; }
+
+ /** 负责人 */
+ public string Leader { get; set; }
+
+ /** 联系电话 */
+ public string Phone { get; set; }
+
+ /** 邮箱 */
+ public string Email { get; set; }
+
+ /** 部门状态:0正常,1停用 */
+ public string Status { get; set; }
+
+ ///
+ /// 删除标志(0代表存在 2代表删除)
+ ///
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ public string DelFlag { get; set; }
+
+ /** 父部门名称 */
+ //[SugarColumn(IsIgnore = true)]
+ //public string ParentName { get; set; }
+
+ ///
+ /// 子菜单
+ ///
+ public List children = new List();
+ }
+}
diff --git a/ARW.Model/System/SysDictData.cs b/ARW.Model/System/SysDictData.cs
new file mode 100644
index 0000000..31fa5a2
--- /dev/null
+++ b/ARW.Model/System/SysDictData.cs
@@ -0,0 +1,31 @@
+//using Dapper.Contrib.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SqlSugar;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 字典数据表
+ ///
+ [Tenant("0")]
+ [SugarTable("sys_dict_data")]
+ public class SysDictData: SysBase
+ {
+ //[Key]
+ ///
+ /// 字典主键
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]//主键并且自增 (string不能设置自增)
+ public long DictCode{ get; set; }
+ public int DictSort { get; set; }
+ public string DictLabel { get; set; }
+ public string DictValue { get; set; }
+ public string DictType { get; set; }
+ public string CssClass { get; set; } = string.Empty;
+ public string ListClass { get; set; } = string.Empty;
+ public string IsDefault { get; set; }
+ public string Status { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysDictType.cs b/ARW.Model/System/SysDictType.cs
new file mode 100644
index 0000000..d8a35a2
--- /dev/null
+++ b/ARW.Model/System/SysDictType.cs
@@ -0,0 +1,36 @@
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 字典类型表
+ ///
+ [SugarTable("sys_dict_type")]
+ [Tenant("0")]
+ public class SysDictType : SysBase
+ {
+ ///
+ /// 字典主键
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]//主键并且自增 (string不能设置自增)
+ public long DictId { get; set; }
+ ///
+ /// 字典名称
+ ///
+ public string DictName { get; set; }
+ ///
+ /// 字典类型
+ ///
+ public string DictType { get; set; }
+ ///
+ /// 状态 0、正常 1、停用
+ ///
+ [EpplusIgnore]
+ public string Status { get; set; }
+ ///
+ /// 系统内置 Y是 N否
+ ///
+ public string Type { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysFile.cs b/ARW.Model/System/SysFile.cs
new file mode 100644
index 0000000..36bfb0b
--- /dev/null
+++ b/ARW.Model/System/SysFile.cs
@@ -0,0 +1,90 @@
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ [Tenant("0")]
+ [SugarTable("sys_file")]
+ public class SysFile
+ {
+ ///
+ /// 描述 : 自增id
+ /// 空值 : false
+ ///
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(IsPrimaryKey = true)]
+ public long Id { get; set; }
+ ///
+ /// 文件原名
+ ///
+ public string RealName { get; set; }
+ ///
+ /// 文件类型
+ ///
+ public string FileType { get; set; }
+ ///
+ /// 描述 : 存储文件名
+ /// 空值 : true
+ ///
+ public string FileName { get; set; }
+ ///
+ /// 描述 : 文件存储地址 eg:/uploads/20220202
+ /// 空值 : true
+ ///
+ public string FileUrl { get; set; }
+ ///
+ /// 描述 : 仓库位置 eg:/uploads
+ /// 空值 : true
+ ///
+ public string StorePath { get; set; }
+ ///
+ /// 描述 : 文件大小
+ /// 空值 : true
+ ///
+ public string FileSize { get; set; }
+ ///
+ /// 描述 : 文件扩展名
+ /// 空值 : true
+ ///
+ public string FileExt { get; set; }
+ ///
+ /// 描述 : 创建人
+ /// 空值 : true
+ ///
+ public string Create_by { get; set; }
+ ///
+ /// 描述 : 上传时间
+ /// 空值 : true
+ ///
+ public DateTime? Create_time { get; set; }
+ ///
+ /// 描述 : 存储类型
+ /// 空值 : true
+ ///
+ public int? StoreType { get; set; }
+ ///
+ /// 描述 : 访问路径
+ /// 空值 : true
+ ///
+ public string AccessUrl { get; set; }
+
+ [JsonProperty(propertyName: "IsDelete")]
+ [SugarColumn(IsNullable = true)]
+ public bool IsDelete { get; set; }
+
+ public SysFile() { }
+ public SysFile(string originFileName, string fileName, string ext, string fileSize, string storePath, string create_by)
+ {
+ StorePath = storePath;
+ RealName = originFileName;
+ FileName = fileName;
+ FileExt = ext;
+ FileSize = fileSize;
+ Create_by = create_by;
+ Create_time = DateTime.Now;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Model/System/SysLogininfor.cs b/ARW.Model/System/SysLogininfor.cs
new file mode 100644
index 0000000..0f407be
--- /dev/null
+++ b/ARW.Model/System/SysLogininfor.cs
@@ -0,0 +1,64 @@
+//using Dapper.Contrib.Extensions;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+using System;
+
+namespace ARW.Model.System
+{
+ ///
+ /// sys_logininfor 表
+ ///
+ [SugarTable("sys_logininfor")]
+ [Tenant("0")]
+ public class SysLogininfor
+ {
+ //[Key]
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public long infoId { get; set; }
+
+ ///
+ /// 用户账号
+ ///
+ public string userName { get; set; }
+
+ ///
+ /// 登录状态 0成功 1失败
+ ///
+ [SugarColumn(Length = 1)]
+ public string status { get; set; }
+
+ ///
+ /// 登录IP地址
+ ///
+ public string ipaddr { get; set; }
+
+ ///
+ /// 登录地点
+ ///
+ public string loginLocation { get; set; }
+
+ ///
+ /// 浏览器类型
+ ///
+ public string browser { get; set; }
+
+ /** 操作系统 */
+ //@Excel(name = "操作系统")
+ public string os { get; set; }
+
+ ///
+ /// 提示消息
+ ///
+ public string msg { get; set; }
+
+ ///
+ /// 访问时间
+ ///
+ [EpplusTableColumn(NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime loginTime { get; set; } = DateTime.Now;
+ [SugarColumn(IsIgnore = true)]
+ public DateTime? BeginTime { get; set; }
+ [SugarColumn(IsIgnore = true)]
+ public DateTime? EndTime { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysMenu.cs b/ARW.Model/System/SysMenu.cs
new file mode 100644
index 0000000..cb50b46
--- /dev/null
+++ b/ARW.Model/System/SysMenu.cs
@@ -0,0 +1,107 @@
+using SqlSugar;
+using System.Collections.Generic;
+
+namespace ARW.Model.System
+{
+ ///
+ /// Sys_menu表
+ ///
+ [SugarTable("sys_menu")]
+ [Tenant("0")]
+ public class SysMenu : SysBase
+ {
+ ///
+ /// 菜单ID
+ ///
+ //[Key]//非自动增长主键时使用ExplicitKey
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public long MenuId { get; set; }
+ ///
+ /// 菜单名称
+ ///
+ public string MenuName { get; set; }
+
+ ///
+ /// 父菜单ID
+ ///
+ public long parentId { get; set; }
+
+ ///
+ /// 显示顺序
+ ///
+ public int orderNum { get; set; }
+
+ ///
+ /// 路由地址
+ ///
+ public string path { get; set; } = "#";
+
+ ///
+ /// 组件路径
+ ///
+ [SugarColumn(IsNullable = true)]
+ public string component { get; set; }
+
+ ///
+ /// 是否缓存(1缓存 0不缓存)
+ ///
+ public string isCache { get; set; }
+ ///
+ /// 是否外链 1、是 0、否
+ ///
+ public string isFrame { get; set; }
+
+ ///
+ /// 类型(M目录 C菜单 F按钮 L链接)
+ ///
+ public string menuType { get; set; }
+
+ ///
+ /// 显示状态(0显示 1隐藏)
+ ///
+ public string visible { get; set; }
+
+ ///
+ /// 菜单状态(0正常 1停用)
+ ///
+ public string status { get; set; }
+
+ ///
+ /// 权限字符串
+ ///
+ [SugarColumn(IsNullable = true)]
+ public string perms { get; set; }
+
+ ///
+ /// 菜单图标
+ ///
+ [SugarColumn(IsNullable = true)]
+ public string icon { get; set; } = string.Empty;
+ ///
+ /// 菜单名key
+ ///
+ [SugarColumn(ColumnName = "menuName_key", IsNullable = true)]
+ public string MenuNameKey { get; set; }
+ ///
+ /// 子菜单
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public List children { get; set; } = new List();
+ ///
+ /// 子菜单个数
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public int SubNum { get; set; }
+ ///
+ /// 是否包含子节点,前端用
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public bool HasChildren
+ {
+ get
+ {
+ return SubNum > 0 || children.Count > 0;
+ }
+ }
+ }
+}
diff --git a/ARW.Model/System/SysNotice.cs b/ARW.Model/System/SysNotice.cs
new file mode 100644
index 0000000..a91b285
--- /dev/null
+++ b/ARW.Model/System/SysNotice.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using SqlSugar;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 通知公告表,数据实体对象
+ ///
+ /// @author zr
+ /// @date 2021-12-15
+ ///
+ [SugarTable("sys_notice")]
+ [Tenant(0)]
+ public class SysNotice : SysBase
+ {
+ ///
+ /// 描述 : 公告ID
+ /// 空值 : true
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnName = "notice_id")]
+ public int NoticeId { get; set; }
+ ///
+ /// 描述 : 公告标题
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "notice_title")]
+ public string NoticeTitle { get; set; }
+ ///
+ /// 描述 : 公告类型 (1通知 2公告)
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "notice_type")]
+ public string NoticeType { get; set; }
+ ///
+ /// 描述 : 公告内容
+ /// 空值 : true
+ ///
+ [SugarColumn(ColumnName = "notice_content")]
+ public string NoticeContent { get; set; }
+ ///
+ /// 描述 : 公告状态 (0正常 1关闭)
+ /// 空值 : true
+ ///
+ public string Status { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/ARW.Model/System/SysOperLog.cs b/ARW.Model/System/SysOperLog.cs
new file mode 100644
index 0000000..871baa5
--- /dev/null
+++ b/ARW.Model/System/SysOperLog.cs
@@ -0,0 +1,92 @@
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OfficeOpenXml.Attributes;
+
+namespace ARW.Model.System
+{
+ [SugarTable("sys_oper_log")]
+ [Tenant("0")]
+ public class SysOperLog
+ {
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public long OperId { get; set; }
+ /** 操作模块 */
+ //@Excel(name = "操作模块")
+ [SugarColumn(IsNullable = true)]
+ public string title { get; set; }
+
+ /** 业务类型(0其它 1新增 2修改 3删除) */
+ //@Excel(name = "业务类型", readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据")
+ public int businessType { get; set; }
+
+ /** 业务类型数组 */
+ [SugarColumn(IsIgnore = true)]
+ public int[] businessTypes { get; set; }
+
+ /** 请求方法 */
+ //@Excel(name = "请求方法")
+ [SugarColumn(IsNullable = true)]
+ public string method { get; set; }
+
+ /** 请求方式 */
+ //@Excel(name = "请求方式")
+ public string requestMethod { get; set; }
+
+ /** 操作类别(0其它 1后台用户 2手机端用户) */
+ //@Excel(name = "操作类别", readConverterExp = "0=其它,1=后台用户,2=手机端用户")
+ public int operatorType { get; set; }
+
+ /** 操作人员 */
+ //@Excel(name = "操作人员")
+ [SugarColumn(IsNullable = true)]
+ public string operName { get; set; }
+
+ /** 部门名称 */
+ //@Excel(name = "部门名称")
+ [SugarColumn(IsNullable = true)]
+ public string deptName { get; set; }
+
+ /** 请求url */
+ //@Excel(name = "请求地址")
+ public string operUrl { get; set; }
+
+ /** 操作地址 */
+ //@Excel(name = "操作地址")
+ public string operIp { get; set; }
+
+ /** 操作地点 */
+ //@Excel(name = "操作地点")
+ public string operLocation { get; set; }
+
+ /** 请求参数 */
+ //@Excel(name = "请求参数")
+ public string operParam { get; set; }
+
+ /** 返回参数 */
+ //@Excel(name = "返回参数")
+ public string jsonResult { get; set; }
+
+ /** 操作状态(0正常 1异常) */
+ //@Excel(name = "状态", readConverterExp = "0=正常,1=异常")
+ public int status { get; set; }
+
+ ///
+ /// 错误消息
+ ///
+ [EpplusTableColumn(Header = "错误消息")]
+ public string errorMsg { get; set; }
+
+ ///
+ /// 操作时间
+ ///
+ [EpplusTableColumn(Header = "操作时间", NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime? operTime { get; set; }
+ ///
+ /// 操作用时
+ ///
+ public long Elapsed { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysPost.cs b/ARW.Model/System/SysPost.cs
new file mode 100644
index 0000000..4bfd544
--- /dev/null
+++ b/ARW.Model/System/SysPost.cs
@@ -0,0 +1,22 @@
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+
+namespace ARW.Model.System
+{
+ [SugarTable("sys_post")]
+ [Tenant("0")]
+ public class SysPost : SysBase
+ {
+ ///
+ /// 岗位Id
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public long PostId { get; set; }
+ public string PostCode { get; set; }
+ public string PostName { get; set; }
+ [EpplusIgnore]
+ public int PostSort { get; set; }
+ [EpplusIgnore]
+ public string Status { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysRole.cs b/ARW.Model/System/SysRole.cs
new file mode 100644
index 0000000..f8e9523
--- /dev/null
+++ b/ARW.Model/System/SysRole.cs
@@ -0,0 +1,94 @@
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 角色表 sys_role
+ ///
+ [SugarTable("sys_role")]
+ [Tenant("0")]
+ public class SysRole : SysBase
+ {
+ ///
+ /// 角色ID
+ ///
+ [SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
+ public long RoleId { get; set; }
+
+ ///
+ /// 角色名称
+ ///
+ public string RoleName { get; set; }
+
+ ///
+ /// 角色权限
+ ///
+ public string RoleKey { get; set; }
+
+ ///
+ /// 角色排序
+ ///
+ public int RoleSort { get; set; }
+
+ ///
+ /// 帐号状态(0正常 1停用)
+ ///
+ public string Status { get; set; }
+
+ ///
+ /// 删除标志(0代表存在 2代表删除)
+ ///
+ [SugarColumn(IsOnlyIgnoreInsert = true, IsOnlyIgnoreUpdate = true)]
+ public string DelFlag { get; set; }
+ ///
+ /// 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限))
+ ///
+ public string DataScope { get; set; }
+ ///
+ /// 菜单树选择项是否关联显示
+ ///
+ [SugarColumn(ColumnName = "menu_check_strictly")]
+ public bool MenuCheckStrictly { get; set; }
+ ///
+ /// 部门树选择项是否关联显示
+ ///
+ [SugarColumn(ColumnName = "dept_check_strictly")]
+ public bool DeptCheckStrictly { get; set; }
+ ///
+ /// 菜单组
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public long[] MenuIds { get; set; }
+ ///
+ /// 部门组(数据权限)
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public long[] DeptIds { get; set; }
+ ///
+ /// 用户个数
+ ///
+ [SugarColumn(IsIgnore = true)]
+ public int UserNum { get; set; }
+
+ public SysRole() { }
+
+ public SysRole(long roleId)
+ {
+ RoleId = roleId;
+ }
+
+ public bool IsAdmin()
+ {
+ return IsAdmin(RoleId);
+ }
+
+ public static bool IsAdmin(long roleId)
+ {
+ return 1 == roleId;
+ }
+ }
+}
diff --git a/ARW.Model/System/SysRoleDept.cs b/ARW.Model/System/SysRoleDept.cs
new file mode 100644
index 0000000..4b5629b
--- /dev/null
+++ b/ARW.Model/System/SysRoleDept.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ [SqlSugar.SugarTable("sys_role_dept")]
+ [SqlSugar.Tenant(0)]
+ public class SysRoleDept
+ {
+ public long RoleId { get; set; }
+ public long DeptId { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysRoleMenu.cs b/ARW.Model/System/SysRoleMenu.cs
new file mode 100644
index 0000000..fc09ce0
--- /dev/null
+++ b/ARW.Model/System/SysRoleMenu.cs
@@ -0,0 +1,25 @@
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 角色菜单
+ ///
+ [SugarTable("sys_role_menu")]
+ [Tenant("0")]
+ public class SysRoleMenu
+ {
+ [JsonProperty("roleId")]
+ [SugarColumn(IsPrimaryKey = true)]
+ public long Role_id { get; set; }
+ [JsonProperty("menuId")]
+ [SugarColumn(IsPrimaryKey = true)]
+ public long Menu_id { get; set; }
+ public DateTime Create_time { get; set; }
+ public string Create_by { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysRolePost.cs b/ARW.Model/System/SysRolePost.cs
new file mode 100644
index 0000000..47fd843
--- /dev/null
+++ b/ARW.Model/System/SysRolePost.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SqlSugar;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 角色部门
+ ///
+ [SugarTable("sys_role_post")]
+ [Tenant("0")]
+ public class SysRolePost
+ {
+ public long RoleId { get; set; }
+ public long DeptId { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysTasksLog.cs b/ARW.Model/System/SysTasksLog.cs
new file mode 100644
index 0000000..3e8bece
--- /dev/null
+++ b/ARW.Model/System/SysTasksLog.cs
@@ -0,0 +1,54 @@
+using Newtonsoft.Json;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 任务日志
+ ///
+ [SugarTable("sys_tasks_log")]
+ [Tenant("0")]
+ public class SysTasksLog
+ {
+ ///
+ /// 日志Id
+ ///
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
+ public long JobLogId { get; set; }
+ ///
+ /// 任务Id
+ ///
+ public string JobId { get; set; }
+ public string JobName { get; set; }
+ public string JobGroup { get; set; }
+ ///
+ /// 执行状态(0正常 1失败)
+ ///
+ public string Status { get; set; }
+ ///
+ /// 异常
+ ///
+ public string Exception { get; set; }
+ ///
+ ///
+ ///
+ public string JobMessage { get; set; }
+ ///
+ /// 调用目标字符串
+ ///
+ public string InvokeTarget { get; set; }
+
+ [EpplusTableColumn(NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime CreateTime { get; set; }
+ ///
+ /// 执行用时,毫秒
+ ///
+ //[SqlSugar.SugarColumn(IsIgnore = true)]
+ public double Elapsed { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysTasksQz.cs b/ARW.Model/System/SysTasksQz.cs
new file mode 100644
index 0000000..6374782
--- /dev/null
+++ b/ARW.Model/System/SysTasksQz.cs
@@ -0,0 +1,170 @@
+using Newtonsoft.Json;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ ///计划任务
+ ///
+ [SugarTable("sys_tasks")]
+ [Tenant("0")]
+ public class SysTasksQz
+ {
+ public SysTasksQz()
+ {
+ }
+
+ ///
+ /// 描述 : UID
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "UID")]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [SugarColumn(IsPrimaryKey = true,IsIdentity =true)]
+ public int ID { get; set; }
+
+ ///
+ /// 描述 : 任务名称
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务名称")]
+ public string Name { get; set; }
+
+ ///
+ /// 描述 : 任务分组
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务分组")]
+ public string JobGroup { get; set; }
+
+ ///
+ /// 描述 : 运行时间表达式
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "运行时间表达式")]
+ public string Cron { get; set; }
+
+ ///
+ /// 描述 : 程序集名称
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "程序集名称")]
+ public string AssemblyName { get; set; }
+
+ ///
+ /// 描述 : 任务所在类
+ /// 空值 : False
+ /// 默认 :
+ ///
+ [Display(Name = "任务所在类")]
+ public string ClassName { get; set; }
+
+ ///
+ /// 描述 : 任务描述
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "任务描述")]
+ public string Remark { get; set; }
+
+ ///
+ /// 描述 : 执行次数
+ /// 空值 : False
+ /// 默认 : 0
+ ///
+ [Display(Name = "执行次数")]
+ public int RunTimes { get; set; }
+
+ ///
+ /// 描述 : 开始时间
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "开始时间")]
+ public DateTime? BeginTime { get; set; }
+
+ ///
+ /// 描述 : 结束时间
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "结束时间")]
+ public DateTime? EndTime { get; set; }
+
+ ///
+ /// 描述 : 触发器类型(0、simple 1、cron)
+ /// 空值 : False
+ /// 默认 : 1
+ ///
+ [Display(Name = "触发器类型(0、simple 1、cron)")]
+ public int TriggerType { get; set; }
+
+ ///
+ /// 描述 : 执行间隔时间(单位:秒)
+ /// 空值 : False
+ /// 默认 : 0
+ ///
+ [Display(Name = "执行间隔时间(单位:秒)")]
+ public int IntervalSecond { get; set; }
+
+ ///
+ /// 描述 : 是否启动
+ /// 空值 : False
+ /// 默认 : 0
+ ///
+ [Display(Name = "是否启动")]
+ public bool IsStart { get; set; }
+
+ ///
+ /// 描述 : 传入参数
+ /// 空值 : True
+ /// 默认 :
+ ///
+ [Display(Name = "传入参数")]
+ public string JobParams { get; set; }
+
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]//设置后修改不会有此字段
+ [JsonProperty(propertyName: "CreateBy")]
+ public string Create_by { get; set; }
+
+ ///
+ /// 描述 : 创建时间
+ /// 空值 : False
+ /// 默认 :
+ ///
+ //[Display(Name = "创建时间")]
+ [SugarColumn(IsOnlyIgnoreUpdate = true)]//设置后修改不会有此字段
+ [JsonProperty(propertyName: "CreateTime")]
+ public DateTime Create_time { get; set; } = DateTime.Now;
+
+ [JsonIgnore]
+ [JsonProperty(propertyName: "UpdateBy")]
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ public string Update_by { get; set; }
+
+ [SugarColumn(IsOnlyIgnoreInsert = true)]//设置后插入数据不会有此字段
+ [JsonProperty(propertyName: "UpdateTime")]
+ public DateTime Update_time { get; set; } = DateTime.Now;
+ ///
+ /// 最后运行时间
+ ///
+ public DateTime? LastRunTime { get; set; }
+ ///
+ /// api执行地址
+ ///
+ public string ApiUrl { get; set; }
+ ///
+ /// 任务类型 1程序集2网络请求
+ ///
+ public int TaskType { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysUser.cs b/ARW.Model/System/SysUser.cs
new file mode 100644
index 0000000..890016f
--- /dev/null
+++ b/ARW.Model/System/SysUser.cs
@@ -0,0 +1,144 @@
+using Newtonsoft.Json;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 用户表
+ ///
+ [SugarTable("sys_user")]
+ [Tenant("0")]
+ public class SysUser : SysBase
+ {
+ ///
+ /// 用户id
+ ///
+ [SugarColumn(IsIdentity = true, IsPrimaryKey = true)]
+ public long UserId { get; set; }
+ //[Duplication]//校验模板类该列数据是否重复
+ public string UserName { get; set; }
+ public string NickName { get; set; }
+ ///
+ /// '用户类型(00系统用户)',
+ ///
+ //[JsonProperty(propertyName: "userType")]
+ //public string User_type { get; set; } = "";
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ [EpplusIgnore]
+ public string Avatar { get; set; }
+ public string Email { get; set; }
+
+ //[JsonIgnore]
+ [EpplusIgnore]
+ public string Password { get; set; }
+ ///
+ /// 手机号
+ ///
+ public string Phonenumber { get; set; }
+ ///
+ /// 用户性别(0男 1女 2未知)
+ ///
+ public string Sex { get; set; }
+
+ ///
+ /// 帐号状态(0正常 1停用)
+ ///
+ [EpplusIgnore]
+ public string Status { get; set; }
+
+ ///
+ /// 删除标志(0代表存在 2代表删除)
+ ///
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ public string DelFlag { get; set; }
+
+ ///
+ /// 最后登录IP
+ ///
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ public string LoginIP { get; set; }
+
+ ///
+ /// 最后登录时间
+ ///
+ [SugarColumn(IsOnlyIgnoreInsert = true)]
+ [EpplusTableColumn(NumberFormat = "yyyy-MM-dd HH:mm:ss")]
+ public DateTime LoginDate { get; set; }
+
+ ///
+ /// 部门Id
+ ///
+ public long DeptId { get; set; }
+
+ #region 表额外字段
+ public bool IsAdmin()
+ {
+ return IsAdmin(UserId);
+ }
+ public static bool IsAdmin(long userId)
+ {
+ return 1 == userId;
+ }
+
+ ///
+ /// 拥有角色个数
+ ///
+ //[SugarColumn(IsIgnore = true)]
+ //public int RoleNum { get; set; }
+ [SugarColumn(IsIgnore = true)]
+ public string DeptName { get; set; }
+ ///
+ /// 角色id集合
+ ///
+ [SugarColumn(IsIgnore = true)]
+ [EpplusIgnore]
+ public long[] RoleIds { get; set; }
+ ///
+ /// 岗位集合
+ ///
+ [SugarColumn(IsIgnore = true)]
+ [EpplusIgnore]
+ public int[] PostIds { get; set; }
+
+ [SugarColumn(IsIgnore = true)]
+ [EpplusIgnore]
+ public List Roles { get; set; }
+ [SugarColumn(IsIgnore = true)]
+ public string WelcomeMessage
+ {
+ get
+ {
+ int now = DateTime.Now.Hour;
+
+ if (now > 0 && now <= 6)
+ {
+ return "午夜好";
+ }
+ else if (now > 6 && now <= 11)
+ {
+ return "早上好";
+ }
+ else if (now > 11 && now <= 14)
+ {
+ return "中午好";
+ }
+ else if (now > 14 && now <= 18)
+ {
+ return "下午好";
+ }
+ else
+ {
+ return "晚上好";
+ }
+ }
+ }
+ [SugarColumn(IsIgnore = true)]
+ public string WelcomeContent { get; set; }
+
+ #endregion
+ }
+}
diff --git a/ARW.Model/System/SysUserPost.cs b/ARW.Model/System/SysUserPost.cs
new file mode 100644
index 0000000..7ec3b59
--- /dev/null
+++ b/ARW.Model/System/SysUserPost.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using SqlSugar;
+
+namespace ARW.Model.System
+{
+
+ ///
+ /// 用户岗位
+ ///
+ [SugarTable("sys_user_post")]
+ [Tenant("0")]
+ public class SysUserPost
+ {
+ public long UserId { get; set; }
+ public long PostId { get; set; }
+ }
+}
diff --git a/ARW.Model/System/SysUserRole.cs b/ARW.Model/System/SysUserRole.cs
new file mode 100644
index 0000000..eb80472
--- /dev/null
+++ b/ARW.Model/System/SysUserRole.cs
@@ -0,0 +1,21 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ ///
+ /// 用户角色关联表 用户N-1 角色
+ ///
+ [SqlSugar.SugarTable("sys_user_role")]
+ [Tenant("0")]
+ public class SysUserRole
+ {
+ [SqlSugar.SugarColumn(ColumnName = "user_id", IsPrimaryKey = true)]
+ public long UserId { get; set; }
+
+ [SqlSugar.SugarColumn(ColumnName = "role_id", IsPrimaryKey = true)]
+ public long RoleId { get; set; }
+ }
+}
diff --git a/ARW.Model/System/UserConstants.cs b/ARW.Model/System/UserConstants.cs
new file mode 100644
index 0000000..ead0d74
--- /dev/null
+++ b/ARW.Model/System/UserConstants.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System
+{
+ public class UserConstants
+ {
+ /**
+ * 平台内系统用户的唯一标志
+ */
+ public static string SYS_USER = "SYS_USER";
+
+ /** 正常状态 */
+ public static string NORMAL = "0";
+
+ /** 异常状态 */
+ public static string EXCEPTION = "1";
+
+ /** 用户封禁状态 */
+ public static string USER_DISABLE = "1";
+
+ /** 角色封禁状态 */
+ public static string ROLE_DISABLE = "1";
+
+ /** 部门正常状态 */
+ public static string DEPT_NORMAL = "0";
+
+ /** 部门停用状态 */
+ public static string DEPT_DISABLE = "1";
+
+ /** 字典正常状态 */
+ public static string DICT_NORMAL = "0";
+
+ /** 是否为系统默认(是) */
+ public static string YES = "Y";
+
+ /** 是否菜单外链(是) */
+ public static string YES_FRAME = "1";
+
+ /** 是否菜单外链(否) */
+ public static string NO_FRAME = "0";
+
+ /** 菜单类型(目录) */
+ public static string TYPE_DIR = "M";
+
+ /** 菜单类型(菜单) */
+ public static string TYPE_MENU = "C";
+
+ /** 菜单类型(按钮) */
+ public static string TYPE_BUTTON = "F";
+ /** 菜单类型(链接) */
+ //public static string TYPE_ARWNK = "L";
+
+ /** Layout组件标识 */
+ public static string LAYOUT = "Layout";
+ /** ParentView组件标识 */
+ public static string PARENT_VIEW = "ParentView";
+ /** InnerLink组件标识 */
+ public static string INNER_ARWNK = "InnerLink";
+ /** 校验返回结果码 */
+ public static string UNIQUE = "0";
+ public static string NOT_UNIQUE = "1";
+
+ ///
+ /// http请求
+ ///
+ public static string HTTP = "http://";
+
+ ///
+ /// https请求
+ ///
+ public static string HTTPS = "https://";
+ }
+}
diff --git a/ARW.Model/System/Vo/LangVo.cs b/ARW.Model/System/Vo/LangVo.cs
new file mode 100644
index 0000000..2479012
--- /dev/null
+++ b/ARW.Model/System/Vo/LangVo.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace ARW.Model.System.Vo
+{
+ public class LangVo
+ {
+
+ }
+}
diff --git a/ARW.Model/System/Vo/RouterVo.cs b/ARW.Model/System/Vo/RouterVo.cs
new file mode 100644
index 0000000..4bb9441
--- /dev/null
+++ b/ARW.Model/System/Vo/RouterVo.cs
@@ -0,0 +1,70 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace ARW.Model.System.Vo
+{
+ ///
+ /// 路由展示
+ ///
+ public class RouterVo
+ {
+ [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+ public bool AlwaysShow { get; set; }
+ private string component;
+ [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+ public bool Hidden { get; set; }
+ public string Name { get; set; }
+ public string Path { get; set; }
+ public string Redirect { get; set; }
+ public Meta Meta { get; set; }
+ [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+ public List Children { get; set; }
+ public string Component { get => component; set => component = value; }
+ }
+
+ public class Meta
+ {
+ ///
+ /// 设置该路由在侧边栏和面包屑中展示的名字
+ ///
+ public string Title { get; set; }
+ ///
+ /// 设置该路由的图标,对应路径src/assets/icons/svg
+ ///
+ public string Icon { get; set; }
+ ///
+ /// 设置为true,则不会被 缓存
+ ///
+ public bool NoCache { get; set; }
+ public string TitleKey { get; set; } = string.Empty;
+ public string Link { get; set; } = string.Empty;
+
+ public Meta(string title, string icon)
+ {
+ Title = title;
+ Icon = icon;
+ }
+ public Meta(string title, string icon, string path)
+ {
+ Title = title;
+ Icon = icon;
+ Link = path;
+ }
+ public Meta(string title, string icon, bool noCache)
+ {
+ Title = title;
+ Icon = icon;
+ NoCache = noCache;
+ }
+ public Meta(string title, string icon, bool noCache, string titleKey, string path)
+ {
+ Title = title;
+ Icon = icon;
+ NoCache = noCache;
+ TitleKey = titleKey;
+ Link = path;
+ }
+ }
+}
diff --git a/ARW.Model/System/Vo/TreeSelectVo.cs b/ARW.Model/System/Vo/TreeSelectVo.cs
new file mode 100644
index 0000000..75234c2
--- /dev/null
+++ b/ARW.Model/System/Vo/TreeSelectVo.cs
@@ -0,0 +1,58 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using ARW.Model.System;
+
+namespace ARW.Model.System.Vo
+{
+ ///
+ /// Treeselect树结构实体类
+ ///
+ public class TreeSelectVo
+ {
+ ///
+ /// 节点Id
+ ///
+ public long Id { get; set; }
+ ///
+ /// 节点名称
+ ///
+ public string Label { get; set; }
+
+ public TreeSelectVo() { }
+
+ public TreeSelectVo(SysMenu menu)
+ {
+ Id = menu.MenuId;
+ Label = menu.MenuName;
+
+ //menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); java写法
+ List child = new List();
+ foreach (var item in menu.children)
+ {
+ child.Add(new TreeSelectVo(item));
+ }
+
+ Children = child;
+ }
+
+ public TreeSelectVo(SysDept dept)
+ {
+ Id = dept.DeptId;
+ Label = dept.DeptName;
+
+ //menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); java写法
+ List child = new List();
+ foreach (var item in dept.children)
+ {
+ child.Add(new TreeSelectVo(item));
+ }
+
+ Children = child;
+ }
+
+ [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
+ public List Children { get; set; }
+ }
+}
diff --git a/ARW.Model/Vo/Business/Crawler/CrawlVo.cs b/ARW.Model/Vo/Business/Crawler/CrawlVo.cs
new file mode 100644
index 0000000..cfaeab6
--- /dev/null
+++ b/ARW.Model/Vo/Business/Crawler/CrawlVo.cs
@@ -0,0 +1,51 @@
+using Newtonsoft.Json;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ARW.Model.Models.Business;
+using ARW.Model.Models.Business.Crawler;
+using Newtonsoft.Json.Linq;
+
+namespace ARW.Model.Vo.Crawler
+{
+ public class CrawlVo
+ {
+ public long Id { get; set; }
+
+ public string Name { get; set; }
+
+ public string Intro { get; set; }
+
+ public string Cover { get; set; }
+
+ public string Link { get; set; }
+
+ public string Type { get; set; }
+
+ public DateTime PublishTime { get; set; }
+
+ [JsonIgnore]
+ public List DownResources { get; set; }
+
+ public string Resources
+ {
+ get
+ {
+ if (this.DownResources != null)
+ {
+ return JToken.FromObject(this.DownResources).ToString();
+ }
+ else
+ {
+ return "[]";
+ }
+
+ }
+ }
+ }
+
+}
diff --git a/ARW.Model/Vo/Business/Customers/CustomerVo.cs b/ARW.Model/Vo/Business/Customers/CustomerVo.cs
new file mode 100644
index 0000000..ba94d75
--- /dev/null
+++ b/ARW.Model/Vo/Business/Customers/CustomerVo.cs
@@ -0,0 +1,42 @@
+using Newtonsoft.Json;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+
+namespace ARW.Model.Vo.Business.Customers
+{
+ ///
+ /// 小程序客户展示对象
+ ///
+ public class CustomerVo
+ {
+
+ [EpplusIgnore]
+ [EpplusTableColumn(Header = "CustomerId")]
+ public int CustomerId { get; set; }
+
+ [EpplusIgnore]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [EpplusTableColumn(Header = "CustomerGuid")]
+ public long CustomerGuid { get; set; }
+ [EpplusTableColumn(Header = "客户姓名")]
+ public string CustomerName { get; set; }
+
+ [EpplusTableColumn(Header = "客户生日")]
+ public string CustomerBrithday { get; set; }
+
+ [EpplusTableColumn(Header = "客户性别")]
+ public int? CustomerSex { get; set; }
+
+ [EpplusTableColumn(Header = "客户图片")]
+ public string CustomerImg { get; set; }
+
+ [EpplusTableColumn(Header = "客户电话")]
+ public string CustomerPhone { get; set; }
+ [EpplusTableColumn(Header = "小程序openid")]
+ public string CustomerXcxOpenid { get; set; }
+ [EpplusTableColumn(Header = "小程序名称")]
+ public string CustomerXcxName { get; set; }
+ [EpplusTableColumn(Header = "小程序头像")]
+ public string CustomerXcxImg { get; set; }
+ }
+}
diff --git a/ARW.Model/Vo/Business/Payments/PaymentVo.cs b/ARW.Model/Vo/Business/Payments/PaymentVo.cs
new file mode 100644
index 0000000..2250cad
--- /dev/null
+++ b/ARW.Model/Vo/Business/Payments/PaymentVo.cs
@@ -0,0 +1,34 @@
+using Newtonsoft.Json;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+
+namespace ARW.Model.Vo.Business.Payments
+{
+ ///
+ /// 支付订单展示对象
+ ///
+ public class PaymentVo
+ {
+
+ [EpplusIgnore]
+ [EpplusTableColumn(Header = "PaymentId")]
+ public int PaymentId { get; set; }
+
+ [EpplusIgnore]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ [EpplusTableColumn(Header = "支付订单guid")]
+ public long PaymentGuid { get; set; }
+ [EpplusTableColumn(Header = "操作状态(1待支付 |2已支付 | 3已取消 | 4已退款)")]
+ public int PaymentStatus { get; set; }
+ [EpplusTableColumn(Header = "核销后价格/操作金额")]
+ public decimal PaymentMoney { get; set; }
+ [EpplusTableColumn(Header = "系统订单号")]
+ public string PaymentNumber { get; set; }
+ [EpplusTableColumn(Header = "操作客户guid(外键)")]
+ public long? CustomerGuid { get; set; }
+ [EpplusTableColumn(Header = "业务订单guid(外键)")]
+ public long? PaymentBusinessGuid { get; set; }
+ [EpplusTableColumn(Header = "购买类型(1| )")]
+ public int PaymentBuytype { get; set; }
+ }
+}
diff --git a/ARW.Model/Vo/Business/SubscribeTasks/SubscribeTaskVo.cs b/ARW.Model/Vo/Business/SubscribeTasks/SubscribeTaskVo.cs
new file mode 100644
index 0000000..467487f
--- /dev/null
+++ b/ARW.Model/Vo/Business/SubscribeTasks/SubscribeTaskVo.cs
@@ -0,0 +1,27 @@
+using Newtonsoft.Json;
+using OfficeOpenXml.Attributes;
+using SqlSugar;
+using System;
+
+namespace ARW.Model.Vo.Business.SubscribeTasks
+{
+ ///
+ /// 订阅推送任务展示对象
+ ///
+ public class SubscribeTaskVo
+ {
+
+ [EpplusIgnore]
+ public int SubscribeTaskId { get; set; }
+
+ [EpplusIgnore]
+ [JsonConverter(typeof(ValueToStringConverter))]
+ public long SubscribeTaskGuid { get; set; }
+ public string OpenId { get; set; }
+ public DateTime EndTime { get; set; }
+ public int? SubscribeTaskType { get; set; }
+ public string TemplateId { get; set; }
+ public int? SubscribeTaskStatus { get; set; }
+ public string SubscribeTaskErrorMsg { get; set; }
+ }
+}
diff --git a/ARW.Repository/ARW.Repository.csproj b/ARW.Repository/ARW.Repository.csproj
new file mode 100644
index 0000000..cda6fdc
--- /dev/null
+++ b/ARW.Repository/ARW.Repository.csproj
@@ -0,0 +1,23 @@
+
+
+
+ net6.0
+ ARW.Repository
+ ARW.Repository
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ARW.Repository/BaseRepository.cs b/ARW.Repository/BaseRepository.cs
new file mode 100644
index 0000000..69fc9b7
--- /dev/null
+++ b/ARW.Repository/BaseRepository.cs
@@ -0,0 +1,416 @@
+using SqlSugar;
+using SqlSugar.IOC;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq.Expressions;
+using System.Reflection;
+using ARW.Model;
+using ARW.Model.Models.Business.Crawler;
+using System.Threading.Tasks;
+
+namespace ARW.Repository
+{
+ ///
+ ///
+ ///
+ ///
+ public class BaseRepository : SimpleClient where T : class, new()
+ {
+ public ITenant itenant = null;//多租户事务
+ public BaseRepository(ISqlSugarClient context = null) : base(context)
+ {
+ //通过特性拿到ConfigId
+ var configId = typeof(T).GetCustomAttribute()?.configId;
+ if (configId != null)
+ {
+ Context = DbScoped.SugarScope.GetConnectionScope(configId);//根据类传入的ConfigId自动选择
+ }
+ else
+ {
+ Context = context ?? DbScoped.SugarScope.GetConnectionScope(0);//没有默认db0
+ }
+ //Context = DbScoped.SugarScope.GetConnectionScopeWithAttr();
+ itenant = DbScoped.SugarScope;//设置租户接口
+ }
+
+ #region add
+
+ ///
+ /// 插入实体
+ ///
+ ///
+ ///
+ public int Add(T t)
+ {
+ return Context.Insertable(t).IgnoreColumns(true).ExecuteCommand();
+ }
+
+ public int Insert(List t)
+ {
+ return Context.Insertable(t).ExecuteCommand();
+ }
+ public int Insert(T parm, Expression> iClumns = null, bool ignoreNull = true)
+ {
+ return Context.Insertable(parm).InsertColumns(iClumns).IgnoreColumns(ignoreNullColumn: ignoreNull).ExecuteCommand();
+ }
+ public IInsertable Insertable(T t)
+ {
+ return Context.Insertable(t);
+ }
+ #endregion add
+
+ #region update
+ public IUpdateable Updateable(T entity)
+ {
+ return Context.Updateable(entity);
+ }
+ public int Update(T entity, bool ignoreNullColumns = false)
+ {
+ return Context.Updateable(entity).IgnoreColumns(ignoreNullColumns).ExecuteCommand();
+ }
+
+ public int Update(T entity, Expression> expression, bool ignoreAllNull = false)
+ {
+ return Context.Updateable(entity).UpdateColumns(expression).IgnoreColumns(ignoreAllNull).ExecuteCommand();
+ }
+
+ ///
+ /// 根据实体类更新指定列 eg:Update(dept, it => new { it.Status }, f => depts.Contains(f.DeptId));只更新Status列,条件是包含
+ ///
+ ///
+ ///
+ ///
+ ///
+ public int Update(T entity, Expression> expression, Expression> where)
+ {
+ return Context.Updateable(entity).UpdateColumns(expression).Where(where).ExecuteCommand();
+ }
+
+ public int Update(SqlSugarClient client, T entity, Expression> expression, Expression> where)
+ {
+ return client.Updateable(entity).UpdateColumns(expression).Where(where).ExecuteCommand();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// 默认为true
+ ///
+ public int Update(T entity, List list = null, bool isNull = true)
+ {
+ if (list == null)
+ {
+ list = new List()
+ {
+ "Create_By",
+ "Create_time"
+ };
+ }
+ return Context.Updateable(entity).IgnoreColumns(isNull).IgnoreColumns(list.ToArray()).ExecuteCommand();
+ }
+
+ //public bool Update(List entity)
+ //{
+ // var result = base.Context.Ado.UseTran(() =>
+ // {
+ // base.Context.Updateable(entity).ExecuteCommand();
+ // });
+ // return result.IsSuccess;
+ //}
+
+ ///
+ /// 更新指定列 eg:Update(w => w.NoticeId == model.NoticeId, it => new SysNotice(){ Update_time = DateTime.Now, Title = "通知标题" });
+ ///
+ ///
+ ///
+ ///
+ public int Update(Expression> where, Expression> columns)
+ {
+ return Context.Updateable().SetColumns(columns).Where(where).RemoveDataCache().ExecuteCommand();
+ }
+ #endregion update
+
+ public DbResult UseTran(Action action)
+ {
+ try
+ {
+ var result = Context.Ado.UseTran(() => action());
+ return result;
+ }
+ catch (Exception ex)
+ {
+ Context.Ado.RollbackTran();
+ Console.WriteLine(ex.Message);
+ throw;
+ }
+ }
+
+
+ public async Task> UseTranAsync(Func action)
+ {
+ try
+ {
+ var result = await Context.Ado.UseTranAsync(() => action());
+ return result;
+ }
+ catch (Exception ex)
+ {
+ Context.Ado.RollbackTran();
+ Console.WriteLine(ex.Message);
+ throw;
+ }
+ }
+
+
+ //public bool UseTran3(Action action)
+ //{
+ // try
+ // {
+ // Context.Ado.BeginTran();//老版本用Context.Ado.BeginTran()新版本用了MySqlConnector必须要用异步事务
+
+ // action();
+ // Context.Ado.CommitTran();
+ // return true;
+ // }
+ // catch (Exception)
+ // {
+ // Context.Ado.RollbackTran();
+ // }
+ // return false;
+ //}
+
+ public IStorageable Storageable(T t)
+ {
+ return Context.Storageable(t);
+ }
+ public IStorageable Storageable(List t)
+ {
+ return Context.Storageable(t);
+ }
+ ///
+ ///
+ ///
+ ///
+ /// 增删改查方法
+ ///
+ public DbResult UseTran(SqlSugarClient client, Action action)
+ {
+ try
+ {
+ var result = client.AsTenant().UseTran(() => action());
+ return result;
+ }
+ catch (Exception ex)
+ {
+ client.AsTenant().RollbackTran();
+ Console.WriteLine(ex.Message);
+ throw;
+ }
+ }
+
+ public bool UseTran2(Action action)
+ {
+ var result = Context.Ado.UseTran(() => action());
+ return result.IsSuccess;
+ }
+
+ #region delete
+ public IDeleteable Deleteable()
+ {
+ return Context.Deleteable();
+ }
+
+ ///
+ /// 批量删除
+ ///
+ ///
+ ///
+ public int Delete(object[] obj)
+ {
+ return Context.Deleteable().In(obj).ExecuteCommand();
+ }
+ public int Delete(object id)
+ {
+ return Context.Deleteable(id).IsLogic().ExecuteCommand();
+ }
+ public int DeleteTable()
+ {
+ return Context.Deleteable().ExecuteCommand();
+ }
+
+ #endregion delete
+
+ #region query
+
+ public bool Any(Expression> expression)
+ {
+ return Context.Queryable().Where(expression).Any();
+ }
+
+ public ISugarQueryable Queryable()
+ {
+ return Context.Queryable();
+ }
+
+ public (List, int) QueryableToPage(Expression> expression, int pageIndex = 0, int pageSize = 10)
+ {
+ int totalNumber = 0;
+ var list = Context.Queryable().Where(expression).ToPageList(pageIndex, pageSize, ref totalNumber);
+ return (list, totalNumber);
+ }
+
+ public (List, int) QueryableToPage(Expression> expression, string order, int pageIndex = 0, int pageSize = 10)
+ {
+ int totalNumber = 0;
+ var list = Context.Queryable().Where(expression).OrderBy(order).ToPageList(pageIndex, pageSize, ref totalNumber);
+ return (list, totalNumber);
+ }
+
+ public (List, int) QueryableToPage(Expression> expression, Expression> orderFiled, string orderBy, int pageIndex = 0, int pageSize = 10)
+ {
+ int totalNumber = 0;
+
+ if (orderBy.Equals("DESC", StringComparison.OrdinalIgnoreCase))
+ {
+ var list = Context.Queryable().Where(expression).OrderBy(orderFiled, OrderByType.Desc).ToPageList(pageIndex, pageSize, ref totalNumber);
+ return (list, totalNumber);
+ }
+ else
+ {
+ var list = Context.Queryable().Where(expression).OrderBy(orderFiled, OrderByType.Asc).ToPageList(pageIndex, pageSize, ref totalNumber);
+ return (list, totalNumber);
+ }
+ }
+
+ public List SqlQueryToList(string sql, object obj = null)
+ {
+ return Context.Ado.SqlQuery(sql, obj);
+ }
+
+ ///
+ /// 根据主值查询单条数据
+ ///
+ /// 主键值
+ /// 泛型实体
+ public T GetId(object pkValue)
+ {
+ return Context.Queryable().InSingle(pkValue);
+ }
+ ///
+ /// 根据条件查询分页数据
+ ///
+ ///
+ ///
+ ///
+ public PagedInfo GetPages(Expression> where, PagerInfo parm)
+ {
+ var source = Context.Queryable().Where(where);
+
+ return source.ToPage(parm);
+ }
+
+ public PagedInfo GetPages(Expression> where, PagerInfo parm, Expression> order, OrderByType orderEnum = OrderByType.Asc)
+ {
+ var source = Context.Queryable().Where(where).OrderByIF(orderEnum == OrderByType.Asc, order, OrderByType.Asc).OrderByIF(orderEnum == OrderByType.Desc, order, OrderByType.Desc);
+
+ return source.ToPage(parm);
+ }
+
+ public PagedInfo GetPages(Expression> where, PagerInfo parm, Expression> order, string orderByType)
+ {
+ return GetPages(where, parm, order, orderByType == "desc" ? OrderByType.Desc : OrderByType.Asc);
+ }
+
+ ///
+ /// 查询所有数据(无分页,请慎用)
+ ///
+ ///
+ public List GetAll(bool useCache = false, int cacheSecond = 3600)
+ {
+ return Context.Queryable().WithCacheIF(useCache, cacheSecond).ToList();
+ }
+
+ #endregion query
+
+ ///
+ /// 此方法不带output返回值
+ /// var list = new List();
+ /// list.Add(new SugarParameter(ParaName, ParaValue)); input
+ ///
+ ///
+ ///
+ ///
+ public DataTable UseStoredProcedureToDataTable(string procedureName, List parameters)
+ {
+ return Context.Ado.UseStoredProcedure().GetDataTable(procedureName, parameters);
+ }
+
+ ///
+ /// 带output返回值
+ /// var list = new List();
+ /// list.Add(new SugarParameter(ParaName, ParaValue, true)); output
+ /// list.Add(new SugarParameter(ParaName, ParaValue)); input
+ ///
+ ///
+ ///
+ ///
+ public (DataTable, List) UseStoredProcedureToTuple(string procedureName, List parameters)
+ {
+ var result = (Context.Ado.UseStoredProcedure().GetDataTable(procedureName, parameters), parameters);
+ return result;
+ }
+ }
+
+ ///
+ /// 分页查询扩展
+ ///
+ public static class QueryableExtension
+ {
+ ///
+ /// 读取列表
+ ///
+ ///
+ /// 查询表单式
+ /// 分页参数
+ ///
+ public static PagedInfo ToPage(this ISugarQueryable source, PagerInfo parm)
+ {
+ var page = new PagedInfo();
+ var total = 0;
+ page.PageSize = parm.PageSize;
+ page.PageIndex = parm.PageNum;
+
+ page.Result = source.OrderByIF(!string.IsNullOrEmpty(parm.Sort), $"{parm.Sort} {(parm.SortType.Contains("desc") ? "desc" : "asc")}")
+ .ToPageList(parm.PageNum, parm.PageSize, ref total);
+ page.TotalNum = total;
+ return page;
+ }
+
+ ///
+ /// 读取列表(异步)
+ ///
+ ///
+ /// 查询表单式
+ /// 分页参数
+ ///
+ public static async Task> ToPageAsync(this ISugarQueryable source, PagerInfo parm)
+ {
+ var page = new PagedInfo();
+ var total = 0;
+ page.PageSize = parm.PageSize;
+ page.PageIndex = parm.PageNum;
+
+ page.Result = await source.OrderByIF(!string.IsNullOrEmpty(parm.Sort), $"{parm.Sort} {(parm.SortType.Contains("desc") ? "desc" : "asc")}")
+ .ToPageListAsync(parm.PageNum, parm.PageSize);
+ page.TotalNum = total;
+ return page;
+ }
+
+ }
+
+
+
+}
diff --git a/ARW.Repository/Business/Crawler/CrawlRepository.cs b/ARW.Repository/Business/Crawler/CrawlRepository.cs
new file mode 100644
index 0000000..58fa0b3
--- /dev/null
+++ b/ARW.Repository/Business/Crawler/CrawlRepository.cs
@@ -0,0 +1,143 @@
+using Infrastructure.Attribute;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ARW.Model.Models.Business.Crawler;
+using AngleSharp.Html.Parser;
+using RestSharp;
+
+namespace ARW.Repository.Business
+{
+ ///
+ /// 爬虫仓储服务
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class CrawlRepository : BaseRepository
+ {
+ protected static HtmlParser htmlParser = new HtmlParser();
+
+
+ // 不羞涩
+ public string LoadBuxiuseHTML(string url)
+ {
+ try
+ {
+ var client = new RestClient(url);
+ var request = new RestRequest("https://www.buxiuse.com/", Method.Get);
+ request.AddHeader("cookie", "SESSION=YmNhNjgxNTctNzk3MS00YTVkLThmM2YtMDBjYzhjZDNiNzNm; Hm_lvt_479b5d690f3b5d1eae450ce953f78480=1660291808,1660530399; Hm_lpvt_479b5d690f3b5d1eae450ce953f78480=1660530399");
+ request.AddHeader("accept-encoding", "gzip, deflate, br");
+ request.AddHeader("accept", "application/json, text/javascript, */*; q=0.01");
+ request.AddHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36");
+ request.AddHeader("upgrade-insecure-requests", "1");
+ request.AddHeader("referer", "https://www.buxiuse.com/");
+ request.AddHeader("cache-control", "max-age=0,no-cache");
+ request.AddHeader("authority", "www.buxiuse.com");
+ RestResponse response = client.Execute(request);
+ return response.IsSuccessful ? response.Content : "";
+
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"LoadHTML fail,url:{url},ex:{ex.ToString()}");
+
+ return string.Empty;
+ }
+ }
+ public int ParseBuxiusePic(string html)
+ {
+ var dom = htmlParser.ParseDocument(html);
+ var movies = new List();
+ var lis = dom.QuerySelectorAll(".panel-body li");
+ foreach (var li in lis)
+ {
+
+ var onlineURL = "https://www.buxiuse.com" + li.QuerySelector("a").GetAttribute("href");
+ var movie = new Crawl()
+ {
+ Name = li.QuerySelector("img").GetAttribute("title"),
+ Cover = li.QuerySelector("img").GetAttribute("src"),
+ Link = onlineURL,
+ Type = "图片",
+ PublishTime = DateTime.Now,
+ };
+ //Context.Insertable(movie).ExecuteReturnIdentity();
+ Add(movie);
+ movies.Add(movie);
+ }
+
+ if (movies.Count == 0)
+ return 0;
+ else
+ return 1;
+ }
+
+
+ // Yellow
+ public string LoadYellowHTML(string url)
+ {
+ try
+ {
+ var client = new RestClient(url);
+ var request = new RestRequest(url, Method.Get);
+ request.AddHeader("cookie", "Hm_lvt_07f2c7e5bd9592209d606f0184fc3d8f=1660568257; recente=%5B%7B%22vod_name%22%3A%22%E5%9B%BD%E4%BA%A7AV%E5%89%A7%E6%83%85-%E4%B8%88%E5%A4%AB%E7%9A%84%22%2C%22vod_url%22%3A%22https%3A%2F%2Frra5ii1x6k3in.com%3A58002%2Findex.php%2Fvod%2Fplay%2Fid%2F138577%2Fsid%2F1%2Fnid%2F1.html%22%2C%22vod_part%22%3A%22%E7%AC%AC1%E9%9B%86%22%7D%5D; Hm_lvt_36ab7abfe863c7133f2af34068ebfc82=1660568383; Hm_lpvt_36ab7abfe863c7133f2af34068ebfc82=1660568383; Hm_lpvt_07f2c7e5bd9592209d606f0184fc3d8f=1660570678");
+ request.AddHeader("accept-encoding", "gzip, deflate, br");
+ request.AddHeader("accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
+ request.AddHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36");
+ request.AddHeader("upgrade-insecure-requests", "1");
+ request.AddHeader("referer", url);
+ request.AddHeader("cache-control", "max-age=0");
+ RestResponse response = client.Execute(request);
+ return response.IsSuccessful ? response.Content : "";
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"LoadHTML fail,url:{url},ex:{ex.ToString()}");
+
+ return string.Empty;
+ }
+ }
+ public int ParseYellowPic(string html)
+ {
+ var dom = htmlParser.ParseDocument(html);
+ var movies = new List();
+ var lis = dom.QuerySelectorAll(".stui-pannel_bd")?.SelectMany(div => div.QuerySelectorAll("li"));
+ foreach (var li in lis)
+ {
+ var onlineURL = "https://x4dgjgj002d5c.com:58002/" + li.QuerySelector("a").GetAttribute("href");
+ var name = li.QuerySelector("a").GetAttribute("title");
+
+ string[] arr = { "福利姬","swag","丝" ,"jk","可爱","制服","网红"};
+
+ foreach (var item in arr)
+ {
+ if (name.Contains(item) == true)
+ {
+ var movie = new Crawl()
+ {
+ Name = name,
+ Link = onlineURL,
+ Type = "Yellow",
+ Cover = li.QuerySelector("a").GetAttribute("data-original"),
+ };
+ Add(movie);
+ movies.Add(movie);
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ }
+
+ if (movies.Count == 0)
+ return 0;
+ else
+ return 1;
+ }
+
+
+ }
+}
diff --git a/ARW.Repository/Business/Customers/CustomerRepository.cs b/ARW.Repository/Business/Customers/CustomerRepository.cs
new file mode 100644
index 0000000..8534664
--- /dev/null
+++ b/ARW.Repository/Business/Customers/CustomerRepository.cs
@@ -0,0 +1,20 @@
+using System;
+using Infrastructure.Attribute;
+using ARW.Repository.System;
+using ARW.Model.Models.Business.Customers;
+
+namespace ARW.Repository.Business.Customers
+{
+ ///
+ /// 小程序客户仓储
+ ///
+ /// @author admin
+ /// @date 2022-12-06
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class CustomerRepository : BaseRepository
+ {
+ #region 业务逻辑代码
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ARW.Repository/Business/Payments/PaymentRepository.cs b/ARW.Repository/Business/Payments/PaymentRepository.cs
new file mode 100644
index 0000000..e407a75
--- /dev/null
+++ b/ARW.Repository/Business/Payments/PaymentRepository.cs
@@ -0,0 +1,20 @@
+using System;
+using Infrastructure.Attribute;
+using ARW.Repository.System;
+using ARW.Model.Models.Business.Payments;
+
+namespace ARW.Repository.Business.Payments
+{
+ ///
+ /// 支付订单仓储
+ ///
+ /// @author admin
+ /// @date 2022-12-15
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class PaymentRepository : BaseRepository
+ {
+ #region 业务逻辑代码
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ARW.Repository/Business/SubscribeTasks/SubscribeTaskRepository.cs b/ARW.Repository/Business/SubscribeTasks/SubscribeTaskRepository.cs
new file mode 100644
index 0000000..8ae0f35
--- /dev/null
+++ b/ARW.Repository/Business/SubscribeTasks/SubscribeTaskRepository.cs
@@ -0,0 +1,20 @@
+using System;
+using Infrastructure.Attribute;
+using ARW.Repository.System;
+using ARW.Model.Models.Business.SubscribeTasks;
+
+namespace ARW.Repository.Business.SubscribeTasks
+{
+ ///
+ /// 订阅推送任务仓储
+ ///
+ /// @author admin
+ /// @date 2022-12-21
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SubscribeTaskRepository : BaseRepository
+ {
+ #region 业务逻辑代码
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ARW.Repository/IBaseRepository.cs b/ARW.Repository/IBaseRepository.cs
new file mode 100644
index 0000000..a8ccc88
--- /dev/null
+++ b/ARW.Repository/IBaseRepository.cs
@@ -0,0 +1,93 @@
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Linq.Expressions;
+using ARW.Model;
+
+namespace ARW.Repository
+{
+ public interface IBaseRepository : ISimpleClient where T : class, new()
+ {
+ #region add
+ int Add(T t);
+
+ int Insert(List t);
+ int Insert(T parm, Expression> iClumns = null, bool ignoreNull = true);
+
+ IInsertable Insertable(T t);
+ #endregion add
+
+ #region update
+ IUpdateable Updateable(T entity);
+ int Update(T entity, bool ignoreNullColumns = false);
+
+ ///
+ /// 只更新表达式的值
+ ///
+ ///
+ ///
+ ///
+ int Update(T entity, Expression> expression, bool ignoreAllNull = false);
+
+ int Update(T entity, Expression> expression, Expression> where);
+
+ int Update(SqlSugarClient client, T entity, Expression> expression, Expression> where);
+
+ int Update(Expression> where, Expression> columns);
+
+ #endregion update
+ IStorageable Storageable(T t);
+ IStorageable Storageable(List t);
+ DbResult UseTran(Action action);
+
+ DbResult UseTran(SqlSugarClient client, Action action);
+
+ bool UseTran2(Action action);
+
+ #region delete
+ IDeleteable Deleteable();
+ int Delete(object[] obj);
+ int Delete(object id);
+ int DeleteTable();
+
+ #endregion delete
+
+ #region query
+ ///
+ /// 根据条件查询分页数据
+ ///
+ ///
+ ///
+ ///
+ PagedInfo GetPages(Expression> where, PagerInfo parm);
+
+ PagedInfo GetPages(Expression> where, PagerInfo parm, Expression> order, OrderByType orderEnum = OrderByType.Asc);
+ PagedInfo GetPages(Expression> where, PagerInfo parm, Expression> order, string orderByType);
+
+ bool Any(Expression> expression);
+
+ ISugarQueryable Queryable();
+ List GetAll(bool useCache = false, int cacheSecond = 3600);
+
+ (List, int) QueryableToPage(Expression> expression, int pageIndex = 0, int pageSize = 10);
+
+ (List, int) QueryableToPage(Expression> expression, string order, int pageIndex = 0, int pageSize = 10);
+
+ (List, int) QueryableToPage(Expression> expression, Expression> orderFiled, string orderBy, int pageIndex = 0, int pageSize = 10);
+
+ List SqlQueryToList(string sql, object obj = null);
+
+ T GetId(object pkValue);
+
+ #endregion query
+
+ #region Procedure
+
+ DataTable UseStoredProcedureToDataTable(string procedureName, List parameters);
+
+ (DataTable, List) UseStoredProcedureToTuple(string procedureName, List parameters);
+
+ #endregion Procedure
+ }
+}
diff --git a/ARW.Repository/System/CommonLangRepository.cs b/ARW.Repository/System/CommonLangRepository.cs
new file mode 100644
index 0000000..435e6bf
--- /dev/null
+++ b/ARW.Repository/System/CommonLangRepository.cs
@@ -0,0 +1,20 @@
+using System;
+using Infrastructure.Attribute;
+using ARW.Repository.System;
+using ARW.Model.Models;
+
+namespace ARW.Repository
+{
+ ///
+ /// 多语言配置仓储
+ ///
+ /// @author zr
+ /// @date 2022-05-06
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class CommonLangRepository : BaseRepository
+ {
+ #region 业务逻辑代码
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ARW.Repository/System/GenTableRepository.cs b/ARW.Repository/System/GenTableRepository.cs
new file mode 100644
index 0000000..f6020fb
--- /dev/null
+++ b/ARW.Repository/System/GenTableRepository.cs
@@ -0,0 +1,91 @@
+using Infrastructure.Attribute;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ARW.Model.System.Generate;
+
+namespace ARW.Repository.System
+{
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class GenTableRepository : BaseRepository
+ {
+
+ }
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class GenTableColumnRepository : BaseRepository
+ {
+ ///
+ /// 根据表id批量删除表字段
+ ///
+ ///
+ ///
+ public int DeleteGenTableColumn(long[] tableId)
+ {
+ return Context.Deleteable().Where(f => tableId.Contains(f.TableId)).ExecuteCommand();
+ }
+
+ ///
+ /// 根据表名删除字段
+ ///
+ ///
+ ///
+ public int DeleteGenTableColumnByTableName(string tableName)
+ {
+ return Context.Deleteable().Where(f => f.TableName == tableName).ExecuteCommand();
+ }
+
+ ///
+ /// 获取表所有字段
+ ///
+ ///
+ ///
+ public List GenTableColumns(long tableId)
+ {
+ return Context.Queryable().Where(f => f.TableId == tableId).OrderBy(x => x.Sort,OrderByType.Asc).ToList();
+ }
+
+ ///
+ /// 插入表字段
+ ///
+ ///
+ ///
+ public int InsertGenTableColumn(List tableColumn)
+ {
+ return Context.Insertable(tableColumn).IgnoreColumns(x => new { x.Remark }).ExecuteCommand();
+ }
+
+ ///
+ /// 批量更新表字段
+ ///
+ ///
+ ///
+ public int UpdateGenTableColumn(List tableColumn)
+ {
+ return Context.Updateable(tableColumn)
+ .WhereColumns(it => new { it.ColumnId, it.TableId})
+ .UpdateColumns(it => new
+ {
+ it.ColumnComment,
+ it.CsharpField,
+ it.CsharpType,
+ it.IsQuery,
+ it.IsEdit,
+ it.IsInsert,
+ it.IsList,
+ it.QueryType,
+ it.HtmlType,
+ it.IsRequired,
+ it.Sort,
+ it.Update_time,
+ it.DictType,
+ it.Update_by,
+ it.Remark,
+ it.IsSort
+ })
+ .ExecuteCommand();
+ }
+ }
+}
diff --git a/ARW.Repository/System/SysConfigRepository.cs b/ARW.Repository/System/SysConfigRepository.cs
new file mode 100644
index 0000000..89af844
--- /dev/null
+++ b/ARW.Repository/System/SysConfigRepository.cs
@@ -0,0 +1,19 @@
+using System;
+using Infrastructure.Attribute;
+using ARW.Model.System;
+
+namespace ARW.Repository
+{
+ ///
+ /// 参数配置仓储接口的实现
+ ///
+ /// @author zhaorui
+ /// @date 2021-09-29
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysConfigRepository : BaseRepository
+ {
+ #region 业务逻辑代码
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ARW.Repository/System/SysDeptRepository.cs b/ARW.Repository/System/SysDeptRepository.cs
new file mode 100644
index 0000000..438b52b
--- /dev/null
+++ b/ARW.Repository/System/SysDeptRepository.cs
@@ -0,0 +1,48 @@
+using Infrastructure.Attribute;
+using System.Collections.Generic;
+using ARW.Model.System;
+
+namespace ARW.Repository.System
+{
+ ///
+ /// 部门管理
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysDeptRepository : BaseRepository
+ {
+ ///
+ ///
+ ///
+ ///
+ ///
+ public List SelectChildrenDeptById(long deptId)
+ {
+ string sql = "select * from sys_dept where find_in_set(@deptId, ancestors)";
+
+ return Context.SqlQueryable(sql).AddParameters(new { @deptId = deptId }).ToList();
+ }
+
+ public int UdateDeptChildren(List dept)
+ {
+ return Context.Updateable(dept).WhereColumns(f => new { f.DeptId })
+ .UpdateColumns(it => new { it.Ancestors }).ExecuteCommand();
+ }
+ }
+
+ ///
+ /// 角色部门
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysRoleDeptRepository : BaseRepository
+ {
+ ///
+ /// 根据角色获取菜单id
+ ///
+ ///
+ ///
+ public List SelectRoleDeptByRoleId(long roleId)
+ {
+ return Context.Queryable().Where(it => it.RoleId == roleId).ToList();
+ }
+ }
+}
diff --git a/ARW.Repository/System/SysDictDataRepository.cs b/ARW.Repository/System/SysDictDataRepository.cs
new file mode 100644
index 0000000..0c5e3b6
--- /dev/null
+++ b/ARW.Repository/System/SysDictDataRepository.cs
@@ -0,0 +1,126 @@
+using Infrastructure.Attribute;
+using Infrastructure.Model;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using ARW.Model;
+using ARW.Model.System;
+
+namespace ARW.Repository.System
+{
+ ///
+ /// 字典数据
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysDictDataRepository : BaseRepository
+ {
+ ///
+ /// 字典类型数据搜索
+ ///
+ ///
+ ///
+ ///
+ public PagedInfo SelectDictDataList(SysDictData dictData, PagerInfo pagerInfo)
+ {
+ var exp = Expressionable.Create();
+ exp.AndIF(!string.IsNullOrEmpty(dictData.DictLabel), it => it.DictLabel.Contains(dictData.DictLabel));
+ exp.AndIF(!string.IsNullOrEmpty(dictData.Status), it => it.Status == dictData.Status);
+ exp.AndIF(!string.IsNullOrEmpty(dictData.DictType), it => it.DictType == dictData.DictType);
+ return GetPages(exp.ToExpression(), pagerInfo);
+ }
+
+ ///
+ /// 根据字典类型查询
+ ///
+ ///
+ ///
+ public List SelectDictDataByType(string dictType)
+ {
+ return Context.Queryable().Where(f => f.Status == "0" && f.DictType == dictType)
+ .OrderBy(it => it.DictSort)
+ .ToList();
+ }
+
+ ///
+ /// 根据字典类型查询
+ ///
+ ///
+ ///
+ public List SelectDictDataByTypes(string[] dictTypes)
+ {
+ return Context.Queryable().Where(f => f.Status == "0" && dictTypes.Contains(f.DictType))
+ .OrderBy(it => it.DictSort)
+ .ToList();
+ }
+ ///
+ /// 新增保存字典数据信息
+ ///
+ ///
+ ///
+ public long InsertDictData(SysDictData dict)
+ {
+ var result = Context.Insertable(dict).ExecuteReturnBigIdentity();
+ return result;
+ }
+
+ ///
+ /// 修改数据
+ ///
+ ///
+ ///
+ public long UpdateDictData(SysDictData dict)
+ {
+ return Context.Updateable()
+ .SetColumns(t => new SysDictData()
+ {
+ Remark = dict.Remark,
+ Update_time = DateTime.Now,
+ DictSort = dict.DictSort,
+ DictLabel = dict.DictLabel,
+ DictValue = dict.DictValue,
+ Status = dict.Status,
+ CssClass = dict.CssClass,
+ ListClass = dict.ListClass
+ })
+ .Where(f => f.DictCode == dict.DictCode).ExecuteCommand();
+ }
+
+ ///
+ /// 批量删除字典数据信息
+ ///
+ ///
+ ///
+ public int DeleteDictDataByIds(long[] dictCodes)
+ {
+ return Delete(dictCodes);
+ }
+
+ ///
+ /// 同步修改字典类型
+ ///
+ /// 旧字典类型
+ /// 新字典类型
+ ///
+ public int UpdateDictDataType(string old_dictType, string new_dictType)
+ {
+ //只更新DictType字段根据where条件
+ return Context.Updateable()
+ .SetColumns(t => new SysDictData() { DictType = new_dictType })
+ .Where(f => f.DictType == old_dictType)
+ .ExecuteCommand();
+ }
+
+ ///
+ /// 获取字典信息名称
+ ///
+ ///
+ public string GetDictNameByName(string name, string value)
+ {
+ var dictData = Context.Queryable().Where(s => s.DictType == name).ToList();
+ var res = dictData.Where(s => s.DictValue == value).First();
+ return res.DictLabel;
+ }
+
+ }
+}
diff --git a/ARW.Repository/System/SysDictRepository.cs b/ARW.Repository/System/SysDictRepository.cs
new file mode 100644
index 0000000..7754291
--- /dev/null
+++ b/ARW.Repository/System/SysDictRepository.cs
@@ -0,0 +1,56 @@
+using Infrastructure.Attribute;
+using SqlSugar;
+using System.Collections.Generic;
+using ARW.Model;
+using ARW.Model.System;
+
+namespace ARW.Repository.System
+{
+ ///
+ /// 字典
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysDictRepository : BaseRepository
+ {
+ public List GetAll()
+ {
+ return Context.Queryable().ToList();
+ }
+
+ ///
+ /// 查询字段类型列表
+ ///
+ /// 实体模型
+ ///
+ public PagedInfo SelectDictTypeList(SysDictType dictType, PagerInfo pager)
+ {
+ var exp = Expressionable.Create();
+ exp.AndIF(!string.IsNullOrEmpty(dictType.DictName), it => it.DictName.Contains(dictType.DictName));
+ exp.AndIF(!string.IsNullOrEmpty(dictType.Status), it => it.Status == dictType.Status);
+ exp.AndIF(!string.IsNullOrEmpty(dictType.DictType), it => it.DictType.Contains(dictType.DictType));
+ exp.AndIF(!string.IsNullOrEmpty(dictType.Type), it => it.Type.Equals(dictType.Type));
+
+ return GetPages(exp.ToExpression(), pager, f => f.DictId, OrderByType.Desc);
+ }
+
+ ///
+ /// 批量删除
+ ///
+ ///
+ ///
+ public int DeleteDictTypeByIds(long[] id)
+ {
+ return Context.Deleteable().In(id).ExecuteCommand();
+ }
+
+ ///
+ /// 修改
+ ///
+ ///
+ ///
+ public int UpdateDictType(SysDictType dictType)
+ {
+ return Context.Updateable(dictType).IgnoreColumns(it => new { dictType.Create_by }).ExecuteCommand();
+ }
+ }
+}
diff --git a/ARW.Repository/System/SysFileRepository.cs b/ARW.Repository/System/SysFileRepository.cs
new file mode 100644
index 0000000..aa2eda1
--- /dev/null
+++ b/ARW.Repository/System/SysFileRepository.cs
@@ -0,0 +1,21 @@
+using System;
+using Infrastructure.Attribute;
+using ARW.Repository.System;
+using ARW.Model.Models;
+using ARW.Model.System;
+
+namespace ARW.Repository.System
+{
+ ///
+ /// 文件存储仓储
+ ///
+ /// @author zz
+ /// @date 2021-12-15
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysFileRepository : BaseRepository
+ {
+ #region 业务逻辑代码
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/ARW.Repository/System/SysLogininfoRepository.cs b/ARW.Repository/System/SysLogininfoRepository.cs
new file mode 100644
index 0000000..c065a5b
--- /dev/null
+++ b/ARW.Repository/System/SysLogininfoRepository.cs
@@ -0,0 +1,89 @@
+using Infrastructure.Attribute;
+using Infrastructure.Extensions;
+using System.Collections.Generic;
+using ARW.Model;
+using ARW.Model.System.Dto;
+using ARW.Model.System;
+using SqlSugar;
+
+namespace ARW.Repository.System
+{
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysLogininfoRepository : BaseRepository
+ {
+ ///
+ /// 查询登录日志
+ ///
+ ///
+ ///
+ ///
+ public PagedInfo GetLoginLog(SysLogininfor logininfoDto, PagerInfo pager)
+ {
+ var exp = Expressionable.Create();
+ exp.And(it => it.loginTime >= logininfoDto.BeginTime && it.loginTime <= logininfoDto.EndTime);
+ exp.AndIF(logininfoDto.ipaddr.IfNotEmpty(), f => f.ipaddr == logininfoDto.ipaddr);
+ exp.AndIF(logininfoDto.userName.IfNotEmpty(), f => f.userName.Contains(logininfoDto.userName));
+ exp.AndIF(logininfoDto.status.IfNotEmpty(), f => f.status == logininfoDto.status);
+ var query = Context.Queryable()
+ .Where(exp.ToExpression())
+ .OrderBy(it => it.infoId, OrderByType.Desc);
+
+ return query.ToPage(pager);
+ }
+
+ ///
+ /// 登录日志记录
+ ///
+ ///
+ ///
+ public void AddLoginInfo(SysLogininfor sysLogininfor)
+ {
+ int result = Context.Insertable(sysLogininfor)
+ .ExecuteReturnIdentity();
+ }
+
+ ///
+ /// 清空登录日志
+ ///
+ public void TruncateLogininfo()
+ {
+ string sql = "truncate table sys_logininfor";
+
+ Context.Ado.ExecuteCommand(sql);
+ }
+
+ ///
+ /// 删除登录日志
+ ///
+ ///
+ ///
+ public int DeleteLogininforByIds(long[] ids)
+ {
+ return Context.Deleteable().In(ids).ExecuteCommand();
+ }
+
+ ///
+ /// 登录
+ ///
+ /// 登录实体
+ ///
+ public SysUser Login(LoginBodyDto user)
+ {
+ return Context.Queryable().First(it => it.UserName == user.Username && it.Password == user.Password);
+ }
+
+ ///
+ /// 修改登录信息
+ ///
+ ///
+ ///
+ ///
+ public void UpdateLoginInfo(LoginBodyDto user, long userId)
+ {
+ var db = Context;
+ db.Updateable(new SysUser() { LoginIP = user.LoginIP, LoginDate = db.GetDate(), UserId = userId })
+ .UpdateColumns(it => new { it.LoginIP, it.LoginDate })
+ .ExecuteCommand();
+ }
+ }
+}
diff --git a/ARW.Repository/System/SysMenuRepository.cs b/ARW.Repository/System/SysMenuRepository.cs
new file mode 100644
index 0000000..66b5e1e
--- /dev/null
+++ b/ARW.Repository/System/SysMenuRepository.cs
@@ -0,0 +1,198 @@
+using Infrastructure.Attribute;
+using SqlSugar;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using ARW.Model.System.Dto;
+using ARW.Model.System;
+
+namespace ARW.Repository.System
+{
+ ///
+ /// 系统菜单
+ ///
+ [AppService(ServiceLifetime = LifeTime.Transient)]
+ public class SysMenuRepository : BaseRepository
+ {
+ ///
+ /// 获取所有菜单(菜单管理)
+ ///
+ ///
+ public List SelectTreeMenuList(MenuQueryDto menu)
+ {
+ return Context.Queryable()
+ .WhereIF(!string.IsNullOrEmpty(menu.MenuName), it => it.MenuName.Contains(menu.MenuName))
+ .WhereIF(!string.IsNullOrEmpty(menu.Visible), it => it.visible == menu.Visible)
+ .WhereIF(!string.IsNullOrEmpty(menu.Status), it => it.status == menu.Status)
+ .WhereIF(!string.IsNullOrEmpty(menu.MenuTypeIds), it => menu.MenuTypeIdArr.Contains(it.menuType))
+ .OrderBy(it => new { it.parentId, it.orderNum })
+ .ToTree(it => it.children, it => it.parentId, 0);
+ }
+
+ ///
+ /// 根据用户查询系统菜单列表
+ ///
+ ///
+ /// 用户角色集合
+ ///
+ public List SelectTreeMenuListByRoles(MenuQueryDto menu, List roles)
+ {
+ var roleMenus = Context.Queryable()
+ .Where(r => roles.Contains(r.Role_id))
+ .Select(f => f.Menu_id).Distinct().ToList();
+
+ return Context.Queryable()
+ .Where(c => roleMenus.Contains(c.MenuId))
+ .WhereIF(!string.IsNullOrEmpty(menu.MenuName), (c) => c.MenuName.Contains(menu.MenuName))
+ .WhereIF(!string.IsNullOrEmpty(menu.Visible), (c) => c.visible == menu.Visible)
+ .WhereIF(!string.IsNullOrEmpty(menu.Status), (c) => c.status == menu.Status)
+ .WhereIF(!string.IsNullOrEmpty(menu.MenuTypeIds), c => menu.MenuTypeIdArr.Contains(c.menuType))
+ .OrderBy((c) => new { c.parentId, c.orderNum })
+ .Select(c => c)
+ .ToTree(it => it.children, it => it.parentId, 0);
+ }
+
+ ///
+ /// 获取所有菜单
+ ///
+ ///
+ public List SelectMenuList(MenuQueryDto menu)
+ {
+ return Context.Queryable()
+ .WhereIF(!string.IsNullOrEmpty(menu.MenuName), it => it.MenuName.Contains(menu.MenuName))
+ .WhereIF(!string.IsNullOrEmpty(menu.Visible), it => it.visible == menu.Visible)
+ .WhereIF(!string.IsNullOrEmpty(menu.Status), it => it.status == menu.Status)
+ .WhereIF(menu.ParentId != null, it => it.parentId == menu.ParentId)
+ .OrderBy(it => new { it.parentId, it.orderNum })
+ .ToList();
+ }
+
+ ///
+ /// 根据用户查询系统菜单列表
+ ///
+ ///
+ /// 用户角色集合
+ ///
+ public List SelectMenuListByRoles(MenuQueryDto sysMenu, List roles)
+ {
+ var roleMenus = Context.Queryable()
+ .Where(r => roles.Contains(r.Role_id));
+
+ return Context.Queryable()
+ .InnerJoin(roleMenus, (c, j) => c.MenuId == j.Menu_id)
+ .Where((c, j) => c.status == "0")
+ .WhereIF(!string.IsNullOrEmpty(sysMenu.MenuName), (c, j) => c.MenuName.Contains(sysMenu.MenuName))
+ .WhereIF(!string.IsNullOrEmpty(sysMenu.Visible), (c, j) => c.visible == sysMenu.Visible)
+ .OrderBy((c, j) => new { c.parentId, c.orderNum })
+ .Select(c => c)
+ .ToList();
+ }
+
+ ///
+ /// 获取菜单详情
+ ///
+ ///
+ ///
+ public SysMenu SelectMenuById(int menuId)
+ {
+ return Context.Queryable().Where(it => it.MenuId == menuId).Single();
+ }
+
+ ///
+ /// 添加菜单
+ ///
+ ///
+ ///
+ public int AddMenu(SysMenu menu)
+ {
+ var Db = Context;
+ menu.Create_time = Db.GetDate();
+ menu.MenuId = Db.Insertable(menu).ExecuteReturnIdentity();
+ return 1;
+ }
+
+ ///
+ /// 编辑菜单
+ ///
+ ///
+ ///
+ public int EditMenu(SysMenu menu)
+ {
+ return Context.Updateable(menu).ExecuteCommand();
+ }
+
+ ///
+ /// 删除菜单
+ ///
+ ///
+ ///
+ public int DeleteMenuById(int menuId)
+ {
+ return Context.Deleteable().Where(it => it.MenuId == menuId).ExecuteCommand();
+ }
+
+ ///
+ /// 菜单排序
+ ///
+ /// 菜单Dto
+ ///
+ public int ChangeSortMenu(MenuDto menuDto)
+ {
+ var result = Context.Updateable(new SysMenu() { MenuId = menuDto.MenuId, orderNum = menuDto.orderNum })
+ .UpdateColumns(it => new { it.orderNum }).ExecuteCommand();
+ return result;
+ }
+
+ ///
+ /// 查询菜单权限
+ ///
+ ///
+ ///
+ public List SelectMenuPermsByUserId(long userId)
+ {
+ return Context.Queryable((m, rm, ur, r) => new JoinQueryInfos(
+ JoinType.Left, m.MenuId == rm.Menu_id,
+ JoinType.Left, rm.Role_id == ur.RoleId,
+ JoinType.Left, ur.RoleId == r.RoleId
+ ))
+ //.Distinct()
+ .Where((m, rm, ur, r) => m.status == "0" && r.Status == "0" && ur.UserId == userId)
+ .Select((m, rm, ur, r) => m).ToList();
+ }
+
+ ///