diff --git a/source/_posts/ASP.Net 6.md b/source/_posts/ASP.Net 6.md index 60e93f4..9f6ef5a 100644 --- a/source/_posts/ASP.Net 6.md +++ b/source/_posts/ASP.Net 6.md @@ -7,9 +7,9 @@ top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FB # ASP.Net 6 -## 1. 部署到Docker +## 部署到Docker -### 1.1 安装.Net SDK 6.0环境 +### 安装.Net SDK 6.0环境 ```shell sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm @@ -17,18 +17,18 @@ sudo yum install dotnet-sdk-6.0 dotnet --info ``` -### 1.2 Visual Studio添加Docker支持 +### Visual Studio添加Docker支持 ![image-20221121144928205](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221121144928205.png) -### 1.3 Linux下构建Docker镜像 +### Linux下构建Docker镜像 ```shell docker image build -f ./XiaodaERP/Dockerfile -t aspnetcore . docker images ``` -### 1.4 运行Docker镜像 +### 运行Docker镜像 ```shell docker run --name=aspnetcore -p 9001:80 -d aspnetcore @@ -45,9 +45,9 @@ docker images docker run --name xiaodaerp/netcore -p 7274:80 -d xiaodaerp/netcore ``` -## 2. 顶级语句配置`Program.cs` +## 顶级语句配置`Program.cs` -### 2.1 取消默认JSON首字母小写命名 +### 取消默认JSON首字母小写命名 ```c# builder.Services.AddControllers().AddJsonOptions(options => { @@ -55,7 +55,7 @@ builder.Services.AddControllers().AddJsonOptions(options => { }); ``` -### 2.2 Json序列化时忽略属性为null的值 +### Json序列化时忽略属性为null的值 ```c# builder.Services.AddControllers().AddJsonOptions(options => { @@ -63,7 +63,7 @@ builder.Services.AddControllers().AddJsonOptions(options => { }); ``` -### 2.3 使用Autofac自动注入Service +### 使用Autofac自动注入Service 通过NuGet包管理器 安装NuGet包 @@ -111,7 +111,7 @@ builder.Host.ConfigureContainer(builder => }); ``` -### 2.4 注入Entity Framework Core 6 DbContext上下文 +### 注入Entity Framework Core 6 DbContext上下文 ```c# builder.Services.AddDbContext(options => @@ -120,7 +120,7 @@ options.UseOracle(builder.Configuration.GetConnectionString("OracleDbContext"))) builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerDbContext"))); ``` -### 2.5 使用JWT进行授权与认证 +### 使用JWT进行授权与认证 安装NuGet包 @@ -337,7 +337,7 @@ public ResultUtil GetUserInfo() ![image-20221206132124913](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221206132124913.png) -## 3. 面向切面编程(AOP) +## 面向切面编程(AOP) 三大拦截器 @@ -350,48 +350,116 @@ public ResultUtil GetUserInfo() 方法拦截器 ```c# +using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Filters; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System.IdentityModel.Tokens.Jwt; +using Castle.Core.Internal; +using XiaodaERP.Models; +using XiaodaERP.Utils; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Options; namespace XiaodaERP.Attributes { public class AuthFilter : ActionFilterAttribute { - // 方法请求后 + //private readonly TokenHelper _tokenHelper; + //public AuthFilter(TokenHelper tokenHelper) + //{ + // this._tokenHelper = tokenHelper; + //} + private readonly SqlServerDbContext _sqlServerDbContext; + public AuthFilter(SqlServerDbContext sqlServerDbContext) + { + this._sqlServerDbContext = sqlServerDbContext; + } + + private SysActionLog sysActionLog = new() + { + ActionId = Guid.NewGuid().ToString().Replace("-", "").ToUpper() + }; + public override void OnActionExecuting(ActionExecutingContext context) + { + var descriptor = context.ActionDescriptor as ControllerActionDescriptor; + string param = string.Empty; + string globalParam = string.Empty; + + var jsonSetting = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; + foreach (var arg in context.ActionArguments) + { + string value = Newtonsoft.Json.JsonConvert.SerializeObject(arg.Value, Formatting.None, jsonSetting); + param += $"{arg.Key} : {value} \r\n"; + globalParam += value; + } + // 方法名 + Console.WriteLine(descriptor.ActionName); + // 参数值拼接 + Console.WriteLine(globalParam); + // 参数名 与 值 + Console.WriteLine(param); + sysActionLog.ActionName = descriptor.ActionName; + sysActionLog.RequestParams = param; + } + public override void OnActionExecuted(ActionExecutedContext context) { // 获取请求Host Console.WriteLine(context.HttpContext.Request.Host); + sysActionLog.RequestHost = context.HttpContext.Request.Host.ToString(); // 获取请求方法 Console.WriteLine(context.HttpContext.Request.Method); + sysActionLog.RequestMethod = context.HttpContext.Request.Method; // 获取请求Url Console.WriteLine(context.HttpContext.Request.Path); - } - // 方法请求时 - public override void OnActionExecuting(ActionExecutingContext context) - { - //Console.WriteLine(context.ActionArguments.ToList()); - foreach (var kv in context.ActionArguments) + sysActionLog.RequestPath = context.HttpContext.Request.Path.ToString(); + // 获取应答返回状态码 + Console.WriteLine(context.HttpContext.Response.StatusCode); + if (context.HttpContext.Request.Path.Equals("/api/User/login")) { - Console.WriteLine("{0}, : ,{1}", kv.Key, kv.Value); + sysActionLog.ActionTime = DateTime.Now; } + else + { + string Token = context.HttpContext.Request.Headers["Authorization"]; + // Token失效 + if (Token.IsNullOrEmpty()) + { - + } + else + { + Token = Token.Split(" ")[1]; + TokenHelper.Token = Token; + ViewUser us = new TokenHelper(new JwtSecurityTokenHandler()).GetToken(Token); + Console.WriteLine(us.UserId); + sysActionLog.ActionUserId = us.UserId; + Console.WriteLine(us.username); + sysActionLog.ActionUserName = us.username; + } + sysActionLog.ActionTime = DateTime.Now; + } + _sqlServerDbContext.SysActionLogs.Add(sysActionLog); + _sqlServerDbContext.SaveChanges(); } - } } + ``` 接口上使用 ```c# -[AuthFilter] +//[AuthFilter] +[TypeFilter(typeof(AuthFilter))] [HttpPost(Name = "login")] public ResultUtil Login(ViewUser viewUser) => ResultUtil.ok(_userService.Login(viewUser.username, viewUser.password)); [Authorize] -[AuthFilter] // 注解为拦截器类名 +//[AuthFilter] // 注解为拦截器类名 +[TypeFilter(typeof(AuthFilter))] // 因为主键中使用了构造器依赖注入,所以需要使用TypeFilter,并需要在顶级语句中注入 AuthFilter [HttpGet(Name = "getUserInfo")] public ResultUtil GetUserInfo() { @@ -403,6 +471,12 @@ public ResultUtil GetUserInfo() } ``` +顶级语句中注入 + +```c# +builder.Services.AddScoped(); +``` + `ExceptionFilterAttribute` diff --git a/source/_posts/Oracle.md b/source/_posts/Oracle.md index 7a5d6b0..bfe7d74 100644 --- a/source/_posts/Oracle.md +++ b/source/_posts/Oracle.md @@ -5,11 +5,11 @@ author: 文永达 --- # Oracle -## 1.1 安装Oracle 19c +## 安装Oracle 19c -### 1.1.1 Linux下安装 +### Linux下安装 -#### 1.1.1.1 rpm方式 `没成功` +#### rpm方式 `没成功` 从Oracle官网下载安装包 Linux x86-64 RPM @@ -169,7 +169,7 @@ Connected to an idle instance. ![image-20221017123327552](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017123327552.png) -#### 1.1.1.2 Docker方式 +#### Docker方式 安装Docker @@ -264,21 +264,21 @@ Grant succeeded. -## 2.1 Oracle SQL Developer +## Oracle SQL Developer -### 2.1.1 设置自动提示 +### 设置自动提示 工具栏 -> 工具 -> 首选项 -> 代码编辑器 -> 完成设置 ![image-20221017111632399](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017111632399.png) -### 2.1.2 设置代码模板 +### 设置代码模板 工具栏 -> 工具 -> 首选项 -> 代码编辑器 -> 代码模板 ![image-20221017112825105](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017112825105.png) -### 2.1.3 同时打开多个表 +### 同时打开多个表 工具栏 -> 工具 -> 首选项 -> 数据库 ->对象查看器 @@ -286,13 +286,13 @@ Grant succeeded. -## 3.1 SQL PLUS +## SQL PLUS -### 3.1.1 解决控制台输错命令删除 +### 解决控制台输错命令删除 使用`Ctrl + backspace`代替`backspace` -### 3.1.2 登录 +### 登录 ```shell # 以oracle账号登录 @@ -302,9 +302,9 @@ $ORACLE_HOME/bin/sqlplus / as sysdba -## 4.1 语法 +## 语法 -### 4.1.1 新建表空间 +### 新建表空间 ```sql CREATE TABLESPACE ACT_DEV @@ -314,7 +314,7 @@ CREATE TABLESPACE ACT_DEV EXTENT MANAGEMENT LOCAL; ``` -### 4.1.2 解除占用 +### 解除占用 ```sql select l.session_id,o.owner,o.object_name @@ -326,7 +326,7 @@ SELECT sid, serial#, username, osuser FROM v$session where sid = sid; alter system kill session 'sid,serial#'; ``` -### 4.1.3 修改表 +### 修改表 ```sql -- 表重命名 @@ -339,13 +339,13 @@ ADD (USERNAME VARCHAR2(20) ); ALTER TABLE BIND_PHONE_NUMBER RENAME COLUMN NAME TO APPNAME; ``` -### 4.1.4 使用关键字做完表名,列名 +### 使用关键字做完表名,列名 使用""形式,如"INDEX" -## 5.1 内连接与外连接 +## 内连接与外连接 -### 5.1.1 内连接 +### 内连接 合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行 @@ -379,19 +379,19 @@ WHERE e.`department_id` = d.department_id; 于是引入外连接。 -### 5.1.2 外连接 +### 外连接 查询多表时一般要求中出现:查询所有的数据时,就一定会用到外连接。 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。 -#### 5.1.2.1 满外连接 +#### 满外连接 `FULL JOIN` `LEFT JOIN UNION RIGHT JOIN` -#### 5.1.2.2 左外连接 +#### 左外连接 语法: @@ -413,7 +413,7 @@ ON (e.department_id = d.department_id) ; `employees`表中的数据会全部显示出来 -#### 5.1.2.3 右外连接 +#### 右外连接 语法: @@ -435,7 +435,7 @@ ON (e.department_id = d.department_id) ; `departments`表中的数据会全部显示出来 -### 5.1.3 UNION的使用 +### UNION的使用 ·语法: diff --git a/source/_posts/PowerDesigner.md b/source/_posts/PowerDesigner.md new file mode 100644 index 0000000..759f95a --- /dev/null +++ b/source/_posts/PowerDesigner.md @@ -0,0 +1,103 @@ +--- +title: PowerDesigner +date: 2022-12-07 9:05:31 +author: 文永达 +top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B951AE18-D431-417F-B3FE-A382403FF21B.jpeg +--- + +# PowerDesigner + +## 简介 + +PowerDesigner是图形化的建模环境,几乎包括了数据库模型设计的全过程。利用PowerDesigner可以制作数据流程图、概念数据模型、物理数据模型,可以生成多种客户端开发工具的应用程序。它可与许多流行的数据库设计模型。 + +## 新建数据库物理模型 + +File -> New Model... + +![image-20221207094426837](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207094426837.png) +Model types -> Physical Data Model -> Physical Diagram + +![image-20221207094525649](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207094525649.png) + +DBMS可以选择数据库 + +![image-20221207094631013](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207094631013.png) + +## 修改当前DBMS + +Database -> Change Current DBMS + +![image-20221207094737302](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207094737302.png) + +New 选择要修改的DBMS + +![image-20221207094815942](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207094815942.png) + +## 根据Name生成Comment + +Tools -> Resources -> DBMS... + +![image-20221207095510030](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207095510030.png)会弹出DBMS 列表 + +![image-20221207095551772](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207095551772.png) + +为了不修改原有的,所以这里选择新建一个DBMS,选择New + +![image-20221207095726544](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207095726544.png) + +取名,选择拷贝原有的DBMS + +![image-20221207095817293](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207095817293.png) + +另存到默认路径 + +![image-20221207095910048](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207095910048.png) + +接着会弹出DBMS属性页面 + +![image-20221207100021926](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207100021926.png) + +修改关键特征树,在 Script\Objects\Table\TableComment和Script\Objects\Column\ColumnComment位置的直修改如下: + +修改TableComment + +![image-20221207100115731](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207100115731.png)修改右侧Value + +```sql +EXECUTE sp_addextendedproperty  +N'MS_Description', N'%COMMENT%', N'user', N'%OWNER%', N'table', N'%TABLE%', NULL, NULL +``` + +![image-20221207100228921](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207100228921.png) + +修改ColumnComment + +![image-20221207100356529](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207100356529.png) + +```sql +EXECUTE sp_addextendedproperty  +N'MS_Description', N'%Name%', N'user', N'%OWNER%', N'table', N'%TABLE%', N'column', N'%COLUMN%' +``` + +确定即可 + +修改生成数据库 + +Database -> Generate Database + +![image-20221207101015449](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207101015449.png) + +弹出对话框 + +选择Format 勾选 Generate name in empty comment + +![image-20221207101114940](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207101114940.png) + +否则当你备注为空的时候注释出不来;反之,如果你备注不为空那么名称(Name)才能作为注释出现!! + +测试是否成功生成 + +![image-20221207101314310](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207101314310.png) + +成功生成 diff --git a/source/_posts/Redis.md b/source/_posts/Redis.md index fbb03a9..c725d6a 100644 --- a/source/_posts/Redis.md +++ b/source/_posts/Redis.md @@ -88,7 +88,7 @@ port 6379 ### Redis数据类型 -#### 1. string类型 +#### string类型 1. mset: 一次设置多个key-value 2. mget: 一次获取多个key-value 3. getset: 获得原始的key的值,同时设置新值,如果不存在key则新建一个key @@ -96,7 +96,7 @@ port 6379 5. append: 为对应的key的value追加内容 6. getrange: 字符串截取 -#### 2. List类型 +#### List类型 相当于Java中的List集合 @@ -116,7 +116,7 @@ port 6379 12. ltrim:保留列表中特定区间内的元素。列表的截取 13. linsert:在某一个元素之前或者之后插入元素 -#### 3. Set类型 +#### Set类型 ​ 相当于Java中的set集合 @@ -135,7 +135,7 @@ port 6379 11. sunion:求并集 -#### 4.Zset类型 +#### Zset类型 ​ 相当于Java中的TreeSet集合 @@ -152,7 +152,7 @@ port 6379 9. zrem:移除某一个元素 10. zincrby:给某一个元素加分 -#### 5.Hash类型 +#### Hash类型 ​ 相当于Java中的Map集合 diff --git a/source/_posts/SQL Server.md b/source/_posts/SQL Server.md index 061235f..b51d297 100644 --- a/source/_posts/SQL Server.md +++ b/source/_posts/SQL Server.md @@ -1,3 +1,10 @@ +--- +title: SQL Server +date: 2022-11-26 14:48:31 +author: 文永达 +top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B951AE18-D431-417F-B3FE-A382403FF21B.jpeg +--- + # SQL Server ## 建库字符集问题 diff --git a/source/_posts/Vue.md b/source/_posts/Vue.md index 1065e5e..f7efacd 100644 --- a/source/_posts/Vue.md +++ b/source/_posts/Vue.md @@ -31,7 +31,7 @@ export default defineConfig({ }) ``` -## 1.1 vite.config.ts 引入 path 模块注意点 +## vite.config.ts 引入 path 模块注意点 1. 安装`@types/node` @@ -312,15 +312,15 @@ export const add = (data) => { # TypeScript -## 1.1 基础类型 +## 基础类型 -### 1.1.1 布尔值 +### 布尔值 ```typescript let isDone: boolean = false; ``` -### 1.1.2 数字 +### 数字 ```typescript let decLiteral: number = 6; @@ -329,7 +329,7 @@ let binaryLiteral: number = 0b1010; let octalLiteral: number = 0o744; ``` -### 1.1.3 字符串 +### 字符串 ```typescript let name: string = "bob"; @@ -352,7 +352,7 @@ let sentence: string = "Hello, my name is " + name + ".\n\n" + "I'll be " + (age + 1) + " years old next month."; ``` -### 1.1.4 数组 +### 数组 可以在元素类型后面接上`[]`,表示由此类型元素组成的一个数组: @@ -366,7 +366,7 @@ let list: number[] = [1, 2, 3]; let list: Array = [1, 2, 3]; ``` -### 1.1.5 元组 +### 元组 元组类型允许表示一个已知元素类型和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为`string`和`number`类型的元组。 @@ -376,7 +376,7 @@ let x: [string, number]; x = ['hello', 10]; ``` -### 1.1.6 枚举 +### 枚举 使用`enum`类型可以为一组数组赋予友好的名字。 @@ -408,7 +408,7 @@ let colorName: string = Color[2]; console.log(colorName); // 显示'Green'因为上面代码里它的值是2 ``` -### 1.1.7 Any +### Any 不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 @@ -441,7 +441,7 @@ list[1] = 100; // 100 比较像元组 -### 1.1.8 Void +### Void `void`类型与`any`类型相反,它表示没有任何类型。当一个函数没有返回值时,通常会见到其返回类型是`void`: diff --git a/source/_posts/Winform.md b/source/_posts/Winform.md index beb8fc6..1a46e07 100644 --- a/source/_posts/Winform.md +++ b/source/_posts/Winform.md @@ -7,11 +7,11 @@ top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B951AE1 # Winform -## 1 .Net Framework +## Net Framework -### 1.1 控件属性 +### 控件属性 -#### 1.1.1 Name +#### Name 表示控件名 @@ -19,7 +19,7 @@ top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B951AE1 this.button1.Name = "button1"; ``` -#### 1.1.2 Text +#### Text 表示控件文本显示 @@ -27,15 +27,15 @@ this.button1.Name = "button1"; this.button.Text = "button1"; ``` -### 1.2 控件事件 +### 控件事件 -#### 1.2.1 button按钮 +#### button按钮 -##### 1.2.1.1 click +##### click -#### 1.2.2 comboBox +#### comboBox -##### 1.2.2.1 SelectedIndexChanged +##### SelectedIndexChanged 问题:SelectedIndexChanged控件,初始加载的时候总会进去两次,SelectedValue 值总为System.Data.DataRowView。 @@ -43,7 +43,7 @@ this.button.Text = "button1"; 解决办法:正确的做法是先设置这两个属性,后绑定数据源。 -##### 1.2.2.2 绑定数据源 +##### 绑定数据源 ```c# DataTable dt = new DataTable(); @@ -68,9 +68,9 @@ this.comboBox1.DataSource = dt; -### 1.3 控件文本显示国际化 +### 控件文本显示国际化 -#### 1.3.1 使用资源文件方式 +#### 使用资源文件方式 在解决方案根目录新建`App_GlobalResources`文件夹 diff --git a/source/_posts/XiaodaERP.md b/source/_posts/XiaodaERP.md index 8a25c27..187b932 100644 --- a/source/_posts/XiaodaERP.md +++ b/source/_posts/XiaodaERP.md @@ -56,32 +56,22 @@ namespace XiaodaERP.Models public class User { public string? UserId { get; set; } - public string? UserName { get; set; } - public string? RealName { get; set;} - public string? Avatar { get; set;} - public string? Desc { get; set;} - public string? PassWord { get; set; } - public string? HomePath { get; set; } - public Role? Role { get; set; } - public string? RoleId { get; set; } - public string? Email { get; set;} - - public string? CreateUser { get; set; } - + public string? CreateUserId { get; set; } public DateTime? CreateTime { get; set; } - public DateTime? UpdateTime{ get; set; } - - public string? DeptId { get; set; } + public string? DeptId { get; set; } + public string? CreateUserName { get; set; } + public string? UpdateUserId { get; set; } + public string? UpdateUserName { get; set; } } } ``` @@ -119,7 +109,10 @@ namespace XiaodaERP.Mapping builder.Property(t => t.Desc).HasColumnName("DESC"); builder.Property(t => t.PassWord).HasColumnName("PASSWORD"); builder.Property(t => t.HomePath).HasColumnName("HOMEPATH"); - builder.Property(t => t.CreateUser).HasColumnName("CREATEUSER"); + builder.Property(t => t.CreateUserId).HasColumnName("CREATEUSERID"); + builder.Property(t => t.CreateUserName).HasColumnName("CREATEUSERNAME"); + builder.Property(t => t.UpdateUserId).HasColumnName("UPDATEUSERID"); + builder.Property(t => t.UpdateUserName).HasColumnName("UPDATEUSERNAME"); builder.Property(t => t.CreateTime).HasColumnName("CREATETIME"); builder.Property(t => t.UpdateTime).HasColumnName("UPDATETIME"); builder.Property(t => t.Email).HasColumnName("EMAIL"); @@ -184,33 +177,19 @@ namespace XiaodaERP.Models public class ViewUser { public string? UserId { get; set; } - - public string? UserName { get; set; } - + public string? username { get; set; } public string? RealName { get; set; } - public string? Avatar { get; set; } - public string? Desc { get; set; } - - public string? PassWord { get; set; } - + public string? password { get; set; } public string? Token { get; set; } - public string? HomePath { get; set; } - public string? RoleId { get; set; } - public string? RoleName { get; set; } - public string? Email { get; set; } - public string? CreateUser { get; set; } - public string? DeptId { get; set; } - public Role[]? Roles { get; set; } - public int? Total { get; set; } } } @@ -219,9 +198,9 @@ namespace XiaodaERP.Models #### 创建 `Service` -在**解决方案资源管理器**中已创建的**Services**文件夹的**IServices**文件夹中新建 `IUserService.cs`接口 +在**解决方案资源管理器**中已创建的**Services**文件夹的**IServices**文件夹中新建 `IAccountService.cs`接口 -![image-20221130173255597](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221130173255597.png) +![image-20221207091417161](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207091417161.png) ```c# using XiaodaERP.Models; @@ -229,29 +208,30 @@ using XiaodaERP.Utils; namespace XiaodaERP.Services.IServices { - public interface IUserService + public interface IAccountService { - // 查询所有User 条件查询 - List GetAllUsers(string DeptId, string? userName, string? realName); - // 添加与更新User - bool UpdateUser(ViewUser viewUser); - // 删除User根据主键ID - bool DeleteUser(string UserId); + // 查询所有Account 条件查询 + List GetAllAccounts(string DeptId, string? userName, string? realName); + // 添加与更新Account + bool UpdateAccount(ViewUser viewUser); + // 删除Account根据主键ID + bool DeleteAccount(string UserId); bool ResetToDefaultPassword(string UserId); - // 分页条件查询User - PageResult GetAllUsersPagination(int page, int pageSize, string DeptId, string? userName, string? realName); + // 分页条件查询Account + PageResult GetAllAccountsPagination(int page, int pageSize, string DeptId, string? userName, string? realName); } } ``` -在**Services**文件夹中新建 `UserService.cs`类,并实现 `IUserService.cs`接口 +在**Services**文件夹中新建 `AccountService.cs`类,并实现 `IAccountService.cs`接口 ```c# using AutoMapper; using Castle.Core.Internal; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Validations; +using Newtonsoft.Json.Linq; using System.Linq; using System.Security.Cryptography; using System.Text; @@ -261,27 +241,24 @@ using XiaodaERP.Utils; namespace XiaodaERP.Services { - public class UserService : IUserService + public class AccountService : IAccountService { - // 通过构造方法注入DbContext private readonly OracleDbContext _oracleDbContext; private readonly SqlServerDbContext _sqlServerDbContext; - public UserService(OracleDbContext oracleDbContext, SqlServerDbContext sqlServerDbContext) + private readonly TokenHelper _tokenHelper; + public AccountService(OracleDbContext oracleDbContext, SqlServerDbContext sqlServerDbContext, TokenHelper tokenHelper) { _oracleDbContext = oracleDbContext; _sqlServerDbContext = sqlServerDbContext; + _tokenHelper = tokenHelper; } - // 实现删除User根据主键ID方法 - public bool DeleteUser(string UserId) + + public bool DeleteAccount(string UserId) { - // 根据UserId主键查询表中是否存在该User - var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault();\ - // 如果存在 + var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault(); if (res != null) { - // 删除User _sqlServerDbContext.Users.Remove(res); - // 提交 return _sqlServerDbContext.SaveChanges() > 0; } else @@ -289,20 +266,17 @@ namespace XiaodaERP.Services return false; } } - // 实现查询所有User 条件查询方法 - public List GetAllUsers(string DeptId, string? userName, string? realName) + + public List GetAllAccounts(string DeptId, string? userName, string? realName) { var res = new List(); - // 部门DeptId不为空 if (!string.IsNullOrEmpty(DeptId)) { - // 根据DeptId查询一级部门 var pdeptRes = _sqlServerDbContext.Depts .Where(t => t.Id == DeptId).Select(t => t.ParentDept).FirstOrDefault(); // 如果pdept是空的,是一级部门 if (string.IsNullOrEmpty(pdeptRes)) { - // userName不为空 if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty()) { res = _sqlServerDbContext.Users.Include(user => user.Role) @@ -312,7 +286,6 @@ namespace XiaodaERP.Services .Contains(u.DeptId)) .Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).ToList(); } - // realName不为空 if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty()) { res = _sqlServerDbContext.Users.Include(user => user.Role) @@ -322,7 +295,6 @@ namespace XiaodaERP.Services .Contains(u.DeptId)) .Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).ToList(); } - // userName不为空 realName不为空 if (!userName.IsNullOrEmpty() && !realName.IsNullOrEmpty()) { res = _sqlServerDbContext.Users.Include(user => user.Role) @@ -333,7 +305,6 @@ namespace XiaodaERP.Services .Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")) .Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).ToList(); } - // 不跟据条件查询 if (userName.IsNullOrEmpty() && realName.IsNullOrEmpty()) { res = _sqlServerDbContext.Users.Include(user => user.Role) @@ -343,39 +314,43 @@ namespace XiaodaERP.Services .Contains(u.DeptId)).ToList(); } } - else // 二级部门查询,此处简写 + else { res = _sqlServerDbContext.Users .Include(user => user.Role) .Where(u => u.DeptId == DeptId).ToList(); } } - else // 不跟据部门查询 + else { res = _sqlServerDbContext.Users.Include(user => user.Role).ToList(); } - + List viewUsers = new(); - // 使用AutoMapper映射POCO至VO var config = new MapperConfiguration(cfg => cfg.CreateMap() - .ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Role.Id)) // 从POCO Role属性对象中取出Id属性映射到 VO RoleId属性 - .ForMember(dest => dest.RoleName, opt => opt.MapFrom(src => src.Role.RoleName))); // 从POCO Role属性对象中取出RoleName属性映射到 VO RoleName属性 + .ForMember(dest => dest.username, opt => opt.MapFrom(src => src.UserName)) + .ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Role.Id)) + .ForMember(dest => dest.RoleName, opt => opt.MapFrom(src => src.Role.RoleName))); var mapper = config.CreateMapper(); foreach (var user in res) { viewUsers.Add( - mapper.Map(user) // 映射 + mapper.Map(user) ) ; } return viewUsers; } - // 实现添加与更新User方法 - public bool UpdateUser(ViewUser viewUser) + + public bool UpdateAccount(ViewUser viewUser) { var res = _sqlServerDbContext.Users.FirstOrDefault(x => x.UserId == viewUser.UserId); var config = new MapperConfiguration(cfg => cfg.CreateMap() + .ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.username)) .BeforeMap((src, des) => src.UserId = Guid.NewGuid().ToString().Replace("-", "").ToUpper()) - .BeforeMap((src, des) => src.PassWord = this.Md5Encoding("123456"))); + .BeforeMap((src, des) => src.password = this.Md5Encoding("123456")) + .BeforeMap((src, des) => des.CreateTime = DateTime.Now) + .BeforeMap((src, des) => des.CreateUserId = _tokenHelper.GetToken(TokenHelper.Token).UserId) + .BeforeMap((src, des) => des.CreateUserName = _tokenHelper.GetToken(TokenHelper.Token).username)); var mapper = config.CreateMapper(); if (res == null) { @@ -385,7 +360,11 @@ namespace XiaodaERP.Services } else { - res = new MapperConfiguration(cfg => cfg.CreateMap()) + res = new MapperConfiguration(cfg => cfg.CreateMap() + .BeforeMap((src, des) => src.password = des.PassWord) + .BeforeMap((src, des) => des.UpdateTime = DateTime.Now) + .BeforeMap((src, des) => des.UpdateUserId = _tokenHelper.GetToken(TokenHelper.Token).UserId) + .BeforeMap((src, des) => des.UpdateUserName = _tokenHelper.GetToken(TokenHelper.Token).username)) .CreateMapper().Map(viewUser, res); } return _sqlServerDbContext.SaveChanges() > 0; @@ -416,6 +395,9 @@ namespace XiaodaERP.Services var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault(); if (res != null) { + res.UpdateTime = DateTime.Now; + res.UpdateUserId = _tokenHelper.GetToken(TokenHelper.Token).UserId; + res.UpdateUserName = _tokenHelper.GetToken(TokenHelper.Token).username; res.PassWord = Md5Encoding("123456"); return _sqlServerDbContext.SaveChanges() > 0; } @@ -424,8 +406,8 @@ namespace XiaodaERP.Services return false; } } - // 实现分页条件查询User方法 - public PageResult GetAllUsersPagination(int page, int pageSize, string DeptId, string? userName, string? realName) + + public PageResult GetAllAccountsPagination(int page, int pageSize, string DeptId, string? userName, string? realName) { var res = new List(); int count = 0; @@ -441,12 +423,12 @@ namespace XiaodaERP.Services .Select(d => d.Id) .ToList()) .Contains(u.DeptId)) - .AsQueryable(); // 创建可拼接的LINQ 查询 + .AsQueryable(); if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty()) { res = sql .Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")) - .Skip((page - 1) * pageSize).Take(pageSize).ToList(); // 分页查询 + .Skip((page - 1) * pageSize).Take(pageSize).ToList(); count = sql.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).Count(); } if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty()) @@ -514,9 +496,10 @@ namespace XiaodaERP.Services List viewUsers = new(); var config = new MapperConfiguration(cfg => cfg.CreateMap() + .ForMember(dest => dest.username, opt => opt.MapFrom(src => src.UserName)) .ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Role.Id)) .ForMember(dest => dest.RoleName, opt => opt.MapFrom(src => src.Role.RoleName)) - .AfterMap((src, des) => des.PassWord = null)); + .AfterMap((src, des) => des.password = null)); var mapper = config.CreateMapper(); foreach (var user in res) { @@ -526,27 +509,28 @@ namespace XiaodaERP.Services } return new PageResult { - Items = viewUsers, // 数据列表 - Total = count // 不分页数据列表元素数量汇总 + Items = viewUsers, + Total = count }; } } } - ``` #### 创建 `Controller` Controller即控制器,API,负责后端与前端数据交互 -在**解决方案资源管理器**中已创建的**Controllers**文件夹中新建 `UserController.cs`类 +在**解决方案资源管理器**中已创建的**Controllers**文件夹中新建 `AccountController.cs`类 -![image-20221130181148128](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221130181148128.png) +![image-20221207091644868](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221207091644868.png) 遵循RestFul风格 查询使用Get请求,增加与更新使用Post请求,删除使用Delete请求 ```c# +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; +using XiaodaERP.Attributes; using XiaodaERP.Models; using XiaodaERP.Services; using XiaodaERP.Services.IServices; @@ -557,41 +541,45 @@ namespace XiaodaERP.Controllers // 使用WebAPI [ApiController] [Route("/api/[controller]/[action]")] // 规定API URL格式 - public class UserController : ControllerBase + public class AccountController : ControllerBase { - // 注入UserService - private readonly IUserService _userService; - - public UserController (IUserService userService) + private readonly IAccountService _accountService; + // 注入AccountService + public AccountController (IAccountService accountService) { - _userService = userService; + _accountService = accountService; } - // 添加与更新User Post请求 Name指定 action 的Url - [HttpPost(Name = "postUser")] - public ResultUtil PostUser(ViewUser viewUser) => - ResultUtil.ok(_userService.UpdateUser(viewUser)); + // 添加与更新Account Post请求 Name指定 action 的Url + [Authorize] + [HttpPost(Name = "postAccount")] + public ResultUtil PostAccount(ViewUser viewUser) => + ResultUtil.ok(_accountService.UpdateAccount(viewUser)); - [HttpGet(Name = "getAllUserList")] - public ResultUtil GetAllUserList(int? page, int? pageSize, string? deptId, string? userName, string? realName) + //[AuthFilter] + [TypeFilter(typeof(AuthFilter))] // 自定义AOP注解 记录接口操作日志 + [Authorize] // 需要携带Token认证的接口 + [HttpGet(Name = "getAllAccountList")] + public ResultUtil GetAllAccountList(int? page, int? pageSize, string? deptId, string? userName, string? realName) { if (page != null && pageSize != null) { - return ResultUtil.ok(_userService.GetAllUsersPagination((int) page, (int) pageSize, deptId, userName, realName)); + return ResultUtil.ok(_accountService.GetAllAccountsPagination((int) page, (int) pageSize, deptId, userName, realName)); } else { - return ResultUtil.ok(_userService.GetAllUsers(deptId, userName, realName)); + return ResultUtil.ok(_accountService.GetAllAccounts(deptId, userName, realName)); } - + } - + [Authorize] [HttpPut(Name = "resetToDefaultPassword")] public ResultUtil ResetToDefaultPassword(string userId) - => ResultUtil.ok(_userService.ResetToDefaultPassword(userId)); + => ResultUtil.ok(_accountService.ResetToDefaultPassword(userId)); - [HttpDelete(Name = "deleteUser")] - public ResultUtil DeleteUser(string userId) => ResultUtil.ok(_userService.DeleteUser(userId)); + [Authorize] + [HttpDelete(Name = "deleteAccount")] + public ResultUtil DeleteAccount(string userId) => ResultUtil.ok(_accountService.DeleteAccount(userId)); } }