This commit is contained in:
wenyongda 2022-12-07 14:23:24 +08:00
parent e9c73cd03f
commit bf780617ca
8 changed files with 348 additions and 176 deletions

View File

@ -7,9 +7,9 @@ top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FB
# ASP.Net 6 # ASP.Net 6
## 1. 部署到Docker ## 部署到Docker
### 1.1 安装.Net SDK 6.0环境 ### 安装.Net SDK 6.0环境
```shell ```shell
sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm 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 dotnet --info
``` ```
### 1.2 Visual Studio添加Docker支持 ### Visual Studio添加Docker支持
![image-20221121144928205](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221121144928205.png) ![image-20221121144928205](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221121144928205.png)
### 1.3 Linux下构建Docker镜像 ### Linux下构建Docker镜像
```shell ```shell
docker image build -f ./XiaodaERP/Dockerfile -t aspnetcore . docker image build -f ./XiaodaERP/Dockerfile -t aspnetcore .
docker images docker images
``` ```
### 1.4 运行Docker镜像 ### 运行Docker镜像
```shell ```shell
docker run --name=aspnetcore -p 9001:80 -d aspnetcore 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 docker run --name xiaodaerp/netcore -p 7274:80 -d xiaodaerp/netcore
``` ```
## 2. 顶级语句配置`Program.cs` ## 顶级语句配置`Program.cs`
### 2.1 取消默认JSON首字母小写命名 ### 取消默认JSON首字母小写命名
```c# ```c#
builder.Services.AddControllers().AddJsonOptions(options => { builder.Services.AddControllers().AddJsonOptions(options => {
@ -55,7 +55,7 @@ builder.Services.AddControllers().AddJsonOptions(options => {
}); });
``` ```
### 2.2 Json序列化时忽略属性为null的值 ### Json序列化时忽略属性为null的值
```c# ```c#
builder.Services.AddControllers().AddJsonOptions(options => { builder.Services.AddControllers().AddJsonOptions(options => {
@ -63,7 +63,7 @@ builder.Services.AddControllers().AddJsonOptions(options => {
}); });
``` ```
### 2.3 使用Autofac自动注入Service ### 使用Autofac自动注入Service
通过NuGet包管理器 安装NuGet包 通过NuGet包管理器 安装NuGet包
@ -111,7 +111,7 @@ builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
}); });
``` ```
### 2.4 注入Entity Framework Core 6 DbContext上下文 ### 注入Entity Framework Core 6 DbContext上下文
```c# ```c#
builder.Services.AddDbContext<OracleDbContext>(options => builder.Services.AddDbContext<OracleDbContext>(options =>
@ -120,7 +120,7 @@ options.UseOracle(builder.Configuration.GetConnectionString("OracleDbContext")))
builder.Services.AddDbContext<SqlServerDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerDbContext"))); builder.Services.AddDbContext<SqlServerDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerDbContext")));
``` ```
### 2.5 使用JWT进行授权与认证 ### 使用JWT进行授权与认证
安装NuGet包 安装NuGet包
@ -337,7 +337,7 @@ public ResultUtil GetUserInfo()
![image-20221206132124913](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221206132124913.png) ![image-20221206132124913](https://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221206132124913.png)
## 3. 面向切面编程(AOP) ## 面向切面编程(AOP)
三大拦截器 三大拦截器
@ -350,48 +350,116 @@ public ResultUtil GetUserInfo()
方法拦截器 方法拦截器
```c# ```c#
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters; 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 namespace XiaodaERP.Attributes
{ {
public class AuthFilter : ActionFilterAttribute 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) public override void OnActionExecuted(ActionExecutedContext context)
{ {
// 获取请求Host // 获取请求Host
Console.WriteLine(context.HttpContext.Request.Host); Console.WriteLine(context.HttpContext.Request.Host);
sysActionLog.RequestHost = context.HttpContext.Request.Host.ToString();
// 获取请求方法 // 获取请求方法
Console.WriteLine(context.HttpContext.Request.Method); Console.WriteLine(context.HttpContext.Request.Method);
sysActionLog.RequestMethod = context.HttpContext.Request.Method;
// 获取请求Url // 获取请求Url
Console.WriteLine(context.HttpContext.Request.Path); Console.WriteLine(context.HttpContext.Request.Path);
} sysActionLog.RequestPath = context.HttpContext.Request.Path.ToString();
// 方法请求时 // 获取应答返回状态码
public override void OnActionExecuting(ActionExecutingContext context) Console.WriteLine(context.HttpContext.Response.StatusCode);
{ if (context.HttpContext.Request.Path.Equals("/api/User/login"))
//Console.WriteLine(context.ActionArguments.ToList());
foreach (var kv in context.ActionArguments)
{ {
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<ViewUser>(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# ```c#
[AuthFilter] //[AuthFilter]
[TypeFilter(typeof(AuthFilter))]
[HttpPost(Name = "login")] [HttpPost(Name = "login")]
public ResultUtil Login(ViewUser viewUser) => public ResultUtil Login(ViewUser viewUser) =>
ResultUtil.ok(_userService.Login(viewUser.username, viewUser.password)); ResultUtil.ok(_userService.Login(viewUser.username, viewUser.password));
[Authorize] [Authorize]
[AuthFilter] // 注解为拦截器类名 //[AuthFilter] // 注解为拦截器类名
[TypeFilter(typeof(AuthFilter))] // 因为主键中使用了构造器依赖注入所以需要使用TypeFilter并需要在顶级语句中注入 AuthFilter
[HttpGet(Name = "getUserInfo")] [HttpGet(Name = "getUserInfo")]
public ResultUtil GetUserInfo() public ResultUtil GetUserInfo()
{ {
@ -403,6 +471,12 @@ public ResultUtil GetUserInfo()
} }
``` ```
顶级语句中注入
```c#
builder.Services.AddScoped<AuthFilter>();
```
`ExceptionFilterAttribute` `ExceptionFilterAttribute`

View File

@ -5,11 +5,11 @@ author: 文永达
--- ---
# Oracle # Oracle
## 1.1 安装Oracle 19c ## 安装Oracle 19c
### 1.1.1 Linux下安装 ### Linux下安装
#### 1.1.1.1 rpm方式 `没成功` #### rpm方式 `没成功`
从Oracle官网下载安装包 Linux x86-64 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) ![image-20221017123327552](http://markdownhexo.oss-cn-hangzhou.aliyuncs.com/img/image-20221017123327552.png)
#### 1.1.1.2 Docker方式 #### 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) ![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) ![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` 使用`Ctrl + backspace`代替`backspace`
### 3.1.2 登录 ### 登录
```shell ```shell
# 以oracle账号登录 # 以oracle账号登录
@ -302,9 +302,9 @@ $ORACLE_HOME/bin/sqlplus / as sysdba
## 4.1 语法 ## 语法
### 4.1.1 新建表空间 ### 新建表空间
```sql ```sql
CREATE TABLESPACE ACT_DEV CREATE TABLESPACE ACT_DEV
@ -314,7 +314,7 @@ CREATE TABLESPACE ACT_DEV
EXTENT MANAGEMENT LOCAL; EXTENT MANAGEMENT LOCAL;
``` ```
### 4.1.2 解除占用 ### 解除占用
```sql ```sql
select l.session_id,o.owner,o.object_name 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#'; alter system kill session 'sid,serial#';
``` ```
### 4.1.3 修改表 ### 修改表
```sql ```sql
-- 表重命名 -- 表重命名
@ -339,13 +339,13 @@ ADD (USERNAME VARCHAR2(20) );
ALTER TABLE BIND_PHONE_NUMBER RENAME COLUMN NAME TO APPNAME; ALTER TABLE BIND_PHONE_NUMBER RENAME COLUMN NAME TO APPNAME;
``` ```
### 4.1.4 使用关键字做完表名,列名 ### 使用关键字做完表名,列名
使用""形式,如"INDEX" 使用""形式,如"INDEX"
## 5.1 内连接与外连接 ## 内连接与外连接
### 5.1.1 内连接 ### 内连接
合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行 合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
@ -379,19 +379,19 @@ WHERE e.`department_id` = d.department_id;
于是引入外连接。 于是引入外连接。
### 5.1.2 外连接 ### 外连接
查询多表时一般要求中出现:查询所有的数据时,就一定会用到外连接。 查询多表时一般要求中出现:查询所有的数据时,就一定会用到外连接。
两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行,这种连接称为左(或右)外连接。没有匹配的行时,结果表中相应的列为空(NULL)。
#### 5.1.2.1 满外连接 #### 满外连接
`FULL JOIN` `FULL JOIN`
`LEFT JOIN UNION RIGHT JOIN` `LEFT JOIN UNION RIGHT JOIN`
#### 5.1.2.2 左外连接 #### 左外连接
语法: 语法:
@ -413,7 +413,7 @@ ON (e.department_id = d.department_id) ;
`employees`表中的数据会全部显示出来 `employees`表中的数据会全部显示出来
#### 5.1.2.3 右外连接 #### 右外连接
语法: 语法:
@ -435,7 +435,7 @@ ON (e.department_id = d.department_id) ;
`departments`表中的数据会全部显示出来 `departments`表中的数据会全部显示出来
### 5.1.3 UNION的使用 ### UNION的使用
·语法: ·语法:

View File

@ -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)
成功生成

View File

@ -88,7 +88,7 @@ port 6379
### Redis数据类型 ### Redis数据类型
#### 1. string类型 #### string类型
1. mset: 一次设置多个key-value 1. mset: 一次设置多个key-value
2. mget: 一次获取多个key-value 2. mget: 一次获取多个key-value
3. getset: 获得原始的key的值同时设置新值如果不存在key则新建一个key 3. getset: 获得原始的key的值同时设置新值如果不存在key则新建一个key
@ -96,7 +96,7 @@ port 6379
5. append: 为对应的key的value追加内容 5. append: 为对应的key的value追加内容
6. getrange: 字符串截取 6. getrange: 字符串截取
#### 2. List类型 #### List类型
相当于Java中的List集合 相当于Java中的List集合
@ -116,7 +116,7 @@ port 6379
12. ltrim保留列表中特定区间内的元素。列表的截取 12. ltrim保留列表中特定区间内的元素。列表的截取
13. linsert在某一个元素之前或者之后插入元素 13. linsert在某一个元素之前或者之后插入元素
#### 3. Set类型 #### Set类型
相当于Java中的set集合 相当于Java中的set集合
@ -135,7 +135,7 @@ port 6379
11. sunion求并集 11. sunion求并集
#### 4.Zset类型 #### Zset类型
相当于Java中的TreeSet集合 相当于Java中的TreeSet集合
@ -152,7 +152,7 @@ port 6379
9. zrem移除某一个元素 9. zrem移除某一个元素
10. zincrby给某一个元素加分 10. zincrby给某一个元素加分
#### 5.Hash类型 #### Hash类型
相当于Java中的Map集合 相当于Java中的Map集合

View File

@ -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 # SQL Server
## 建库字符集问题 ## 建库字符集问题

View File

@ -31,7 +31,7 @@ export default defineConfig({
}) })
``` ```
## 1.1 vite.config.ts 引入 path 模块注意点 ## vite.config.ts 引入 path 模块注意点
1. 安装`@types/node` 1. 安装`@types/node`
@ -312,15 +312,15 @@ export const add = (data) => {
# TypeScript # TypeScript
## 1.1 基础类型 ## 基础类型
### 1.1.1 布尔值 ### 布尔值
```typescript ```typescript
let isDone: boolean = false; let isDone: boolean = false;
``` ```
### 1.1.2 数字 ### 数字
```typescript ```typescript
let decLiteral: number = 6; let decLiteral: number = 6;
@ -329,7 +329,7 @@ let binaryLiteral: number = 0b1010;
let octalLiteral: number = 0o744; let octalLiteral: number = 0o744;
``` ```
### 1.1.3 字符串 ### 字符串
```typescript ```typescript
let name: string = "bob"; 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."; "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<number> = [1, 2, 3]; let list: Array<number> = [1, 2, 3];
``` ```
### 1.1.5 元组 ### 元组
元组类型允许表示一个已知元素类型和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为`string``number`类型的元组。 元组类型允许表示一个已知元素类型和类型的数组,各元素的类型不必相同。比如,你可以定义一对值分别为`string``number`类型的元组。
@ -376,7 +376,7 @@ let x: [string, number];
x = ['hello', 10]; x = ['hello', 10];
``` ```
### 1.1.6 枚举 ### 枚举
使用`enum`类型可以为一组数组赋予友好的名字。 使用`enum`类型可以为一组数组赋予友好的名字。
@ -408,7 +408,7 @@ let colorName: string = Color[2];
console.log(colorName); // 显示'Green'因为上面代码里它的值是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` `void`类型与`any`类型相反,它表示没有任何类型。当一个函数没有返回值时,通常会见到其返回类型是`void`

View File

@ -7,11 +7,11 @@ top_img: https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/B951AE1
# Winform # 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"; this.button1.Name = "button1";
``` ```
#### 1.1.2 Text #### Text
表示控件文本显示 表示控件文本显示
@ -27,15 +27,15 @@ this.button1.Name = "button1";
this.button.Text = "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。 问题SelectedIndexChanged控件初始加载的时候总会进去两次SelectedValue 值总为System.Data.DataRowView。
@ -43,7 +43,7 @@ this.button.Text = "button1";
解决办法:正确的做法是先设置这两个属性,后绑定数据源。 解决办法:正确的做法是先设置这两个属性,后绑定数据源。
##### 1.2.2.2 绑定数据源 ##### 绑定数据源
```c# ```c#
DataTable dt = new DataTable(); DataTable dt = new DataTable();
@ -68,9 +68,9 @@ this.comboBox1.DataSource = dt;
### 1.3 控件文本显示国际化 ### 控件文本显示国际化
#### 1.3.1 使用资源文件方式 #### 使用资源文件方式
在解决方案根目录新建`App_GlobalResources`文件夹 在解决方案根目录新建`App_GlobalResources`文件夹

View File

@ -56,32 +56,22 @@ namespace XiaodaERP.Models
public class User public class User
{ {
public string? UserId { get; set; } public string? UserId { get; set; }
public string? UserName { get; set; } public string? UserName { get; set; }
public string? RealName { get; set;} public string? RealName { get; set;}
public string? Avatar { get; set;} public string? Avatar { get; set;}
public string? Desc { get; set;} public string? Desc { get; set;}
public string? PassWord { get; set; } public string? PassWord { get; set; }
public string? HomePath { get; set; } public string? HomePath { get; set; }
public Role? Role { get; set; } public Role? Role { get; set; }
public string? RoleId { get; set; } public string? RoleId { get; set; }
public string? Email { get; set;} public string? Email { get; set;}
public string? CreateUserId { get; set; }
public string? CreateUser { get; set; }
public DateTime? CreateTime { get; set; } public DateTime? CreateTime { get; set; }
public DateTime? UpdateTime{ 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.Desc).HasColumnName("DESC");
builder.Property(t => t.PassWord).HasColumnName("PASSWORD"); builder.Property(t => t.PassWord).HasColumnName("PASSWORD");
builder.Property(t => t.HomePath).HasColumnName("HOMEPATH"); 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.CreateTime).HasColumnName("CREATETIME");
builder.Property(t => t.UpdateTime).HasColumnName("UPDATETIME"); builder.Property(t => t.UpdateTime).HasColumnName("UPDATETIME");
builder.Property(t => t.Email).HasColumnName("EMAIL"); builder.Property(t => t.Email).HasColumnName("EMAIL");
@ -184,33 +177,19 @@ namespace XiaodaERP.Models
public class ViewUser public class ViewUser
{ {
public string? UserId { get; set; } public string? UserId { get; set; }
public string? username { get; set; }
public string? UserName { get; set; }
public string? RealName { get; set; } public string? RealName { get; set; }
public string? Avatar { get; set; } public string? Avatar { get; set; }
public string? Desc { get; set; } public string? Desc { get; set; }
public string? password { get; set; }
public string? PassWord { get; set; }
public string? Token { get; set; } public string? Token { get; set; }
public string? HomePath { get; set; } public string? HomePath { get; set; }
public string? RoleId { get; set; } public string? RoleId { get; set; }
public string? RoleName { get; set; } public string? RoleName { get; set; }
public string? Email { get; set; } public string? Email { get; set; }
public string? CreateUser { get; set; } public string? CreateUser { get; set; }
public string? DeptId { get; set; } public string? DeptId { get; set; }
public Role[]? Roles { get; set; } public Role[]? Roles { get; set; }
public int? Total { get; set; } public int? Total { get; set; }
} }
} }
@ -219,9 +198,9 @@ namespace XiaodaERP.Models
#### 创建 `Service` #### 创建 `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# ```c#
using XiaodaERP.Models; using XiaodaERP.Models;
@ -229,29 +208,30 @@ using XiaodaERP.Utils;
namespace XiaodaERP.Services.IServices namespace XiaodaERP.Services.IServices
{ {
public interface IUserService public interface IAccountService
{ {
// 查询所有User 条件查询 // 查询所有Account 条件查询
List<ViewUser> GetAllUsers(string DeptId, string? userName, string? realName); List<ViewUser> GetAllAccounts(string DeptId, string? userName, string? realName);
// 添加与更新User // 添加与更新Account
bool UpdateUser(ViewUser viewUser); bool UpdateAccount(ViewUser viewUser);
// 删除User根据主键ID // 删除Account根据主键ID
bool DeleteUser(string UserId); bool DeleteAccount(string UserId);
bool ResetToDefaultPassword(string UserId); bool ResetToDefaultPassword(string UserId);
// 分页条件查询User // 分页条件查询Account
PageResult<ViewUser> GetAllUsersPagination(int page, int pageSize, string DeptId, string? userName, string? realName); PageResult<ViewUser> GetAllAccountsPagination(int page, int pageSize, string DeptId, string? userName, string? realName);
} }
} }
``` ```
在**Services**文件夹中新建 `UserService.cs`类,并实现 `IUserService.cs`接口 在**Services**文件夹中新建 `AccountService.cs`类,并实现 `IAccountService.cs`接口
```c# ```c#
using AutoMapper; using AutoMapper;
using Castle.Core.Internal; using Castle.Core.Internal;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Validations; using Microsoft.OpenApi.Validations;
using Newtonsoft.Json.Linq;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
@ -261,27 +241,24 @@ using XiaodaERP.Utils;
namespace XiaodaERP.Services namespace XiaodaERP.Services
{ {
public class UserService : IUserService public class AccountService : IAccountService
{ {
// 通过构造方法注入DbContext
private readonly OracleDbContext _oracleDbContext; private readonly OracleDbContext _oracleDbContext;
private readonly SqlServerDbContext _sqlServerDbContext; private readonly SqlServerDbContext _sqlServerDbContext;
public UserService(OracleDbContext oracleDbContext, SqlServerDbContext sqlServerDbContext) private readonly TokenHelper _tokenHelper;
public AccountService(OracleDbContext oracleDbContext, SqlServerDbContext sqlServerDbContext, TokenHelper tokenHelper)
{ {
_oracleDbContext = oracleDbContext; _oracleDbContext = oracleDbContext;
_sqlServerDbContext = sqlServerDbContext; _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) if (res != null)
{ {
// 删除User
_sqlServerDbContext.Users.Remove(res); _sqlServerDbContext.Users.Remove(res);
// 提交
return _sqlServerDbContext.SaveChanges() > 0; return _sqlServerDbContext.SaveChanges() > 0;
} }
else else
@ -289,20 +266,17 @@ namespace XiaodaERP.Services
return false; return false;
} }
} }
// 实现查询所有User 条件查询方法
public List<ViewUser> GetAllUsers(string DeptId, string? userName, string? realName) public List<ViewUser> GetAllAccounts(string DeptId, string? userName, string? realName)
{ {
var res = new List<User>(); var res = new List<User>();
// 部门DeptId不为空
if (!string.IsNullOrEmpty(DeptId)) if (!string.IsNullOrEmpty(DeptId))
{ {
// 根据DeptId查询一级部门
var pdeptRes = _sqlServerDbContext.Depts var pdeptRes = _sqlServerDbContext.Depts
.Where(t => t.Id == DeptId).Select(t => t.ParentDept).FirstOrDefault(); .Where(t => t.Id == DeptId).Select(t => t.ParentDept).FirstOrDefault();
// 如果pdept是空的是一级部门 // 如果pdept是空的是一级部门
if (string.IsNullOrEmpty(pdeptRes)) if (string.IsNullOrEmpty(pdeptRes))
{ {
// userName不为空
if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty()) if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{ {
res = _sqlServerDbContext.Users.Include(user => user.Role) res = _sqlServerDbContext.Users.Include(user => user.Role)
@ -312,7 +286,6 @@ namespace XiaodaERP.Services
.Contains(u.DeptId)) .Contains(u.DeptId))
.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).ToList(); .Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).ToList();
} }
// realName不为空
if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty()) if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty())
{ {
res = _sqlServerDbContext.Users.Include(user => user.Role) res = _sqlServerDbContext.Users.Include(user => user.Role)
@ -322,7 +295,6 @@ namespace XiaodaERP.Services
.Contains(u.DeptId)) .Contains(u.DeptId))
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).ToList(); .Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).ToList();
} }
// userName不为空 realName不为空
if (!userName.IsNullOrEmpty() && !realName.IsNullOrEmpty()) if (!userName.IsNullOrEmpty() && !realName.IsNullOrEmpty())
{ {
res = _sqlServerDbContext.Users.Include(user => user.Role) 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.UserName, "%" + userName + "%"))
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).ToList(); .Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).ToList();
} }
// 不跟据条件查询
if (userName.IsNullOrEmpty() && realName.IsNullOrEmpty()) if (userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{ {
res = _sqlServerDbContext.Users.Include(user => user.Role) res = _sqlServerDbContext.Users.Include(user => user.Role)
@ -343,39 +314,43 @@ namespace XiaodaERP.Services
.Contains(u.DeptId)).ToList(); .Contains(u.DeptId)).ToList();
} }
} }
else // 二级部门查询,此处简写 else
{ {
res = _sqlServerDbContext.Users res = _sqlServerDbContext.Users
.Include(user => user.Role) .Include(user => user.Role)
.Where(u => u.DeptId == DeptId).ToList(); .Where(u => u.DeptId == DeptId).ToList();
} }
} }
else // 不跟据部门查询 else
{ {
res = _sqlServerDbContext.Users.Include(user => user.Role).ToList(); res = _sqlServerDbContext.Users.Include(user => user.Role).ToList();
} }
List<ViewUser> viewUsers = new(); List<ViewUser> viewUsers = new();
// 使用AutoMapper映射POCO至VO
var config = new MapperConfiguration(cfg => cfg.CreateMap<User, ViewUser>() var config = new MapperConfiguration(cfg => cfg.CreateMap<User, ViewUser>()
.ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Role.Id)) // 从POCO Role属性对象中取出Id属性映射到 VO RoleId属性 .ForMember(dest => dest.username, opt => opt.MapFrom(src => src.UserName))
.ForMember(dest => dest.RoleName, opt => opt.MapFrom(src => src.Role.RoleName))); // 从POCO Role属性对象中取出RoleName属性映射到 VO RoleName属性 .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(); var mapper = config.CreateMapper();
foreach (var user in res) foreach (var user in res)
{ {
viewUsers.Add( viewUsers.Add(
mapper.Map<ViewUser>(user) // 映射 mapper.Map<ViewUser>(user)
) ; ) ;
} }
return viewUsers; return viewUsers;
} }
// 实现添加与更新User方法
public bool UpdateUser(ViewUser viewUser) public bool UpdateAccount(ViewUser viewUser)
{ {
var res = _sqlServerDbContext.Users.FirstOrDefault(x => x.UserId == viewUser.UserId); var res = _sqlServerDbContext.Users.FirstOrDefault(x => x.UserId == viewUser.UserId);
var config = new MapperConfiguration(cfg => cfg.CreateMap<ViewUser, User>() var config = new MapperConfiguration(cfg => cfg.CreateMap<ViewUser, User>()
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.username))
.BeforeMap((src, des) => src.UserId = Guid.NewGuid().ToString().Replace("-", "").ToUpper()) .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<ViewUser>(TokenHelper.Token).UserId)
.BeforeMap((src, des) => des.CreateUserName = _tokenHelper.GetToken<ViewUser>(TokenHelper.Token).username));
var mapper = config.CreateMapper(); var mapper = config.CreateMapper();
if (res == null) if (res == null)
{ {
@ -385,7 +360,11 @@ namespace XiaodaERP.Services
} }
else else
{ {
res = new MapperConfiguration(cfg => cfg.CreateMap<ViewUser, User>()) res = new MapperConfiguration(cfg => cfg.CreateMap<ViewUser, User>()
.BeforeMap((src, des) => src.password = des.PassWord)
.BeforeMap((src, des) => des.UpdateTime = DateTime.Now)
.BeforeMap((src, des) => des.UpdateUserId = _tokenHelper.GetToken<ViewUser>(TokenHelper.Token).UserId)
.BeforeMap((src, des) => des.UpdateUserName = _tokenHelper.GetToken<ViewUser>(TokenHelper.Token).username))
.CreateMapper().Map(viewUser, res); .CreateMapper().Map(viewUser, res);
} }
return _sqlServerDbContext.SaveChanges() > 0; return _sqlServerDbContext.SaveChanges() > 0;
@ -416,6 +395,9 @@ namespace XiaodaERP.Services
var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault(); var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault();
if (res != null) if (res != null)
{ {
res.UpdateTime = DateTime.Now;
res.UpdateUserId = _tokenHelper.GetToken<ViewUser>(TokenHelper.Token).UserId;
res.UpdateUserName = _tokenHelper.GetToken<ViewUser>(TokenHelper.Token).username;
res.PassWord = Md5Encoding("123456"); res.PassWord = Md5Encoding("123456");
return _sqlServerDbContext.SaveChanges() > 0; return _sqlServerDbContext.SaveChanges() > 0;
} }
@ -424,8 +406,8 @@ namespace XiaodaERP.Services
return false; return false;
} }
} }
// 实现分页条件查询User方法
public PageResult<ViewUser> GetAllUsersPagination(int page, int pageSize, string DeptId, string? userName, string? realName) public PageResult<ViewUser> GetAllAccountsPagination(int page, int pageSize, string DeptId, string? userName, string? realName)
{ {
var res = new List<User>(); var res = new List<User>();
int count = 0; int count = 0;
@ -441,12 +423,12 @@ namespace XiaodaERP.Services
.Select(d => d.Id) .Select(d => d.Id)
.ToList()) .ToList())
.Contains(u.DeptId)) .Contains(u.DeptId))
.AsQueryable(); // 创建可拼接的LINQ 查询 .AsQueryable();
if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty()) if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{ {
res = sql res = sql
.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")) .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(); count = sql.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).Count();
} }
if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty()) if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty())
@ -514,9 +496,10 @@ namespace XiaodaERP.Services
List<ViewUser> viewUsers = new(); List<ViewUser> viewUsers = new();
var config = new MapperConfiguration(cfg => cfg.CreateMap<User, ViewUser>() var config = new MapperConfiguration(cfg => cfg.CreateMap<User, ViewUser>()
.ForMember(dest => dest.username, opt => opt.MapFrom(src => src.UserName))
.ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Role.Id)) .ForMember(dest => dest.RoleId, opt => opt.MapFrom(src => src.Role.Id))
.ForMember(dest => dest.RoleName, opt => opt.MapFrom(src => src.Role.RoleName)) .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(); var mapper = config.CreateMapper();
foreach (var user in res) foreach (var user in res)
{ {
@ -526,27 +509,28 @@ namespace XiaodaERP.Services
} }
return new PageResult<ViewUser> return new PageResult<ViewUser>
{ {
Items = viewUsers, // 数据列表 Items = viewUsers,
Total = count // 不分页数据列表元素数量汇总 Total = count
}; };
} }
} }
} }
``` ```
#### 创建 `Controller` #### 创建 `Controller`
Controller即控制器API负责后端与前端数据交互 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请求 遵循RestFul风格 查询使用Get请求增加与更新使用Post请求删除使用Delete请求
```c# ```c#
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using XiaodaERP.Attributes;
using XiaodaERP.Models; using XiaodaERP.Models;
using XiaodaERP.Services; using XiaodaERP.Services;
using XiaodaERP.Services.IServices; using XiaodaERP.Services.IServices;
@ -557,41 +541,45 @@ namespace XiaodaERP.Controllers
// 使用WebAPI // 使用WebAPI
[ApiController] [ApiController]
[Route("/api/[controller]/[action]")] // 规定API URL格式 [Route("/api/[controller]/[action]")] // 规定API URL格式
public class UserController : ControllerBase public class AccountController : ControllerBase
{ {
// 注入UserService private readonly IAccountService _accountService;
private readonly IUserService _userService; // 注入AccountService
public AccountController (IAccountService accountService)
public UserController (IUserService userService)
{ {
_userService = userService; _accountService = accountService;
} }
// 添加与更新User Post请求 Name指定 action 的Url // 添加与更新Account Post请求 Name指定 action 的Url
[HttpPost(Name = "postUser")] [Authorize]
public ResultUtil PostUser(ViewUser viewUser) => [HttpPost(Name = "postAccount")]
ResultUtil.ok(_userService.UpdateUser(viewUser)); public ResultUtil PostAccount(ViewUser viewUser) =>
ResultUtil.ok(_accountService.UpdateAccount(viewUser));
[HttpGet(Name = "getAllUserList")] //[AuthFilter]
public ResultUtil GetAllUserList(int? page, int? pageSize, string? deptId, string? userName, string? realName) [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) 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 else
{ {
return ResultUtil.ok(_userService.GetAllUsers(deptId, userName, realName)); return ResultUtil.ok(_accountService.GetAllAccounts(deptId, userName, realName));
} }
} }
[Authorize]
[HttpPut(Name = "resetToDefaultPassword")] [HttpPut(Name = "resetToDefaultPassword")]
public ResultUtil ResetToDefaultPassword(string userId) public ResultUtil ResetToDefaultPassword(string userId)
=> ResultUtil.ok(_userService.ResetToDefaultPassword(userId)); => ResultUtil.ok(_accountService.ResetToDefaultPassword(userId));
[HttpDelete(Name = "deleteUser")] [Authorize]
public ResultUtil DeleteUser(string userId) => ResultUtil.ok(_userService.DeleteUser(userId)); [HttpDelete(Name = "deleteAccount")]
public ResultUtil DeleteAccount(string userId) => ResultUtil.ok(_accountService.DeleteAccount(userId));
} }
} }