22 KiB
22 KiB
title, date, author, top_img
| title | date | author | top_img |
|---|---|---|---|
| XiaodaERP | 2021-03-23 10:30:31 | 文永达 | https://gcore.jsdelivr.net/gh/volantis-x/cdn-wallpaper/abstract/67239FBB-E15D-4F4F-8EE8-0F1C9F3C4E7C.jpeg |
XiaodaERP
访问地址: XiaodaERP
技术选形
- ASP.Net 6
- Entity Framework Core 6
- Microsoft SQL Server
开发手册
本节以用户模块开发为模板
首先数据库建表
数据库建模PDM
表名
表结构
SQL Server数据库建表
EF Core 建立POCO对象
创建POCO
POCO全称 Plain Old CLR Object 普通旧CLR对象 作为 ORM映射
在解决方案资源管理器中已创建的Models文件夹中新建 User.cs类
参照数据库表结构将对应列添加进属性中
需要加 **? **代表可空数据类型
其中 Role是另一个POCO,在这里的作用是多表联查,用户与角色为多对一关系
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 DateTime? CreateTime { get; set; }
public DateTime? UpdateTime{ get; set; }
public string? DeptId { get; set; }
}
}
创建Mapping映射
建立ORM映射
在解决方案资源管理器中已创建的Mapping文件夹中新建 UserMap.cs类
根据数据库表结构配置映射
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using XiaodaERP.Models;
namespace XiaodaERP.Mapping
{
public class UserMap : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
// 数据库表名
builder.ToTable("BASE_USER");
// 数据库主键
builder.HasKey(t => t.UserId);
// 数据库列名
builder.Property(t => t.UserId).HasColumnName("USERID");
builder.Property(t => t.UserName).HasColumnName("USERNAME");
builder.Property(t => t.RealName).HasColumnName("REALNAME");
builder.Property(t => t.Avatar).HasColumnName("AVATAR");
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.CreateTime).HasColumnName("CREATETIME");
builder.Property(t => t.UpdateTime).HasColumnName("UPDATETIME");
builder.Property(t => t.Email).HasColumnName("EMAIL");
builder.Property(t => t.RoleId).HasColumnName("ROLEID");
builder.Property(t => t.DeptId).HasColumnName("DEPTID");
// User包含一个Role 一个Role对应多个User
builder.HasOne(u => u.Role).WithMany();
}
}
}
配置DbContext
DbContext为EF Core数据库上下文
打开创建好的 SqlServerDbContext.cs
加入DbSet, Mapping映射
using Microsoft.EntityFrameworkCore;
using XiaodaERP.Mapping;
using XiaodaERP.Models;
namespace XiaodaERP
{
public class SqlServerDbContext : DbContext
{
public SqlServerDbContext(DbContextOptions<SqlServerDbContext> options)
: base(options)
{
}
// DbSet
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Mapping映射
modelBuilder.ApplyConfiguration<User>(new UserMap());
base.OnModelCreating(modelBuilder);
}
}
}
创建VO
VO全称ViewObject 视图对象 作为 API与前端数据交换的媒介
在解决方案资源管理器中已创建的Models文件夹中新建 ViewUser.cs类
using System.Security.Permissions;
namespace XiaodaERP.Models
{
public class ViewUser
{
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? 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; }
}
}
创建 Service
在解决方案资源管理器中已创建的Services文件夹的IServices文件夹中新建 IUserService.cs接口
using XiaodaERP.Models;
using XiaodaERP.Utils;
namespace XiaodaERP.Services.IServices
{
public interface IUserService
{
// 查询所有User 条件查询
List<ViewUser> GetAllUsers(string DeptId, string? userName, string? realName);
// 添加与更新User
bool UpdateUser(ViewUser viewUser);
// 删除User根据主键ID
bool DeleteUser(string UserId);
bool ResetToDefaultPassword(string UserId);
// 分页条件查询User
PageResult<ViewUser> GetAllUsersPagination(int page, int pageSize, string DeptId, string? userName, string? realName);
}
}
在Services文件夹中新建 UserService.cs类,并实现 IUserService.cs接口
using AutoMapper;
using Castle.Core.Internal;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Validations;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using XiaodaERP.Models;
using XiaodaERP.Services.IServices;
using XiaodaERP.Utils;
namespace XiaodaERP.Services
{
public class UserService : IUserService
{
// 通过构造方法注入DbContext
private readonly OracleDbContext _oracleDbContext;
private readonly SqlServerDbContext _sqlServerDbContext;
public UserService(OracleDbContext oracleDbContext, SqlServerDbContext sqlServerDbContext)
{
_oracleDbContext = oracleDbContext;
_sqlServerDbContext = sqlServerDbContext;
}
// 实现删除User根据主键ID方法
public bool DeleteUser(string UserId)
{
// 根据UserId主键查询表中是否存在该User
var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault();\
// 如果存在
if (res != null)
{
// 删除User
_sqlServerDbContext.Users.Remove(res);
// 提交
return _sqlServerDbContext.SaveChanges() > 0;
}
else
{
return false;
}
}
// 实现查询所有User 条件查询方法
public List<ViewUser> GetAllUsers(string DeptId, string? userName, string? realName)
{
var res = new List<User>();
// 部门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)
.Where(u => (_sqlServerDbContext.Depts.Where(d => d.ParentDept == DeptId)
.Select(d => d.Id)
.ToList())
.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)
.Where(u => (_sqlServerDbContext.Depts.Where(d => d.ParentDept == DeptId)
.Select(d => d.Id)
.ToList())
.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)
.Where(u => (_sqlServerDbContext.Depts.Where(d => d.ParentDept == DeptId)
.Select(d => d.Id)
.ToList())
.Contains(u.DeptId))
.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)
.Where(u => (_sqlServerDbContext.Depts.Where(d => d.ParentDept == DeptId)
.Select(d => d.Id)
.ToList())
.Contains(u.DeptId)).ToList();
}
}
else // 二级部门查询,此处简写
{
res = _sqlServerDbContext.Users
.Include(user => user.Role)
.Where(u => u.DeptId == DeptId).ToList();
}
}
else // 不跟据部门查询
{
res = _sqlServerDbContext.Users.Include(user => user.Role).ToList();
}
List<ViewUser> viewUsers = new();
// 使用AutoMapper映射POCO至VO
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.RoleName, opt => opt.MapFrom(src => src.Role.RoleName))); // 从POCO Role属性对象中取出RoleName属性映射到 VO RoleName属性
var mapper = config.CreateMapper();
foreach (var user in res)
{
viewUsers.Add(
mapper.Map<ViewUser>(user) // 映射
) ;
}
return viewUsers;
}
// 实现添加与更新User方法
public bool UpdateUser(ViewUser viewUser)
{
var res = _sqlServerDbContext.Users.FirstOrDefault(x => x.UserId == viewUser.UserId);
var config = new MapperConfiguration(cfg => cfg.CreateMap<ViewUser, User>()
.BeforeMap((src, des) => src.UserId = Guid.NewGuid().ToString().Replace("-", "").ToUpper())
.BeforeMap((src, des) => src.PassWord = this.Md5Encoding("123456")));
var mapper = config.CreateMapper();
if (res == null)
{
_sqlServerDbContext.Users.Add(
mapper.Map<User>(viewUser)
);
}
else
{
res = new MapperConfiguration(cfg => cfg.CreateMap<ViewUser, User>())
.CreateMapper().Map(viewUser, res);
}
return _sqlServerDbContext.SaveChanges() > 0;
}
/// <summary>
/// MD5 加密字符串
/// </summary>
/// <param name="rawPass">源字符串</param>
/// <returns>加密后字符串</returns>
public string Md5Encoding(string rawPass)
{
// 创建MD5类的默认实例:MD5CryptoServiceProvider
var md5 = MD5.Create();
var bs = Encoding.UTF8.GetBytes(rawPass);
var hs = md5.ComputeHash(bs);
var sb = new StringBuilder();
foreach (var b in hs)
{
// 以十六进制格式格式化
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
public bool ResetToDefaultPassword(string UserId)
{
var res = _sqlServerDbContext.Users.Where(t => t.UserId == UserId).FirstOrDefault();
if (res != null)
{
res.PassWord = Md5Encoding("123456");
return _sqlServerDbContext.SaveChanges() > 0;
}
else
{
return false;
}
}
// 实现分页条件查询User方法
public PageResult<ViewUser> GetAllUsersPagination(int page, int pageSize, string DeptId, string? userName, string? realName)
{
var res = new List<User>();
int count = 0;
if (!string.IsNullOrEmpty(DeptId))
{
var pdeptRes = _sqlServerDbContext.Depts
.Where(t => t.Id == DeptId).Select(t => t.ParentDept).FirstOrDefault();
// 如果pdept是空的,是一级部门 一级部门查询
if (string.IsNullOrEmpty(pdeptRes))
{
var sql = _sqlServerDbContext.Users.Include(user => user.Role)
.Where(u => (_sqlServerDbContext.Depts.Where(d => d.ParentDept == DeptId)
.Select(d => d.Id)
.ToList())
.Contains(u.DeptId))
.AsQueryable(); // 创建可拼接的LINQ 查询
if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{
res = sql
.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%"))
.Skip((page - 1) * pageSize).Take(pageSize).ToList(); // 分页查询
count = sql.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).Count();
}
if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty())
{
res = sql
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%"))
.Skip((page - 1) * pageSize).Take(pageSize).ToList();
count = sql.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).Count();
}
if (!userName.IsNullOrEmpty() && !realName.IsNullOrEmpty())
{
res = sql
.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%"))
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%"))
.Skip((page - 1) * pageSize).Take(pageSize).ToList();
count = sql.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%"))
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).Count();
}
if (userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{
res = sql.Skip((page - 1) * pageSize).Take(pageSize).ToList();
count = sql.Count();
}
} // 二级部门查询
else
{
var sql = _sqlServerDbContext.Users
.Include(user => user.Role)
.Where(u => u.DeptId == DeptId).AsQueryable();
if (!userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{
res = sql
.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%"))
.Skip((page - 1) * pageSize).Take(pageSize).ToList();
count = sql.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%")).Count();
}
if (!realName.IsNullOrEmpty() && userName.IsNullOrEmpty())
{
res = sql
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%"))
.Skip((page - 1) * pageSize).Take(pageSize).ToList();
count = sql.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).Count();
}
if (!userName.IsNullOrEmpty() && !realName.IsNullOrEmpty())
{
res = sql
.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%"))
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%"))
.Skip((page - 1) * pageSize).Take(pageSize).ToList();
count = sql.Where(u => EF.Functions.Like(u.UserName, "%" + userName + "%"))
.Where(u => EF.Functions.Like(u.RealName, "%" + realName + "%")).Count();
}
if (userName.IsNullOrEmpty() && realName.IsNullOrEmpty())
{
res = sql.ToList();
count = sql.Count();
}
}
}
else
{
res = _sqlServerDbContext.Users.Include(user => user.Role).ToList();
count = _sqlServerDbContext.Users.Include(user => user.Role).Count();
}
List<ViewUser> viewUsers = new();
var config = new MapperConfiguration(cfg => cfg.CreateMap<User, ViewUser>()
.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));
var mapper = config.CreateMapper();
foreach (var user in res)
{
viewUsers.Add(
mapper.Map<ViewUser>(user)
);
}
return new PageResult<ViewUser>
{
Items = viewUsers, // 数据列表
Total = count // 不分页数据列表元素数量汇总
};
}
}
}
创建 Controller
Controller即控制器,API,负责后端与前端数据交互
在解决方案资源管理器中已创建的Controllers文件夹中新建 UserController.cs类
遵循RestFul风格 查询使用Get请求,增加与更新使用Post请求,删除使用Delete请求
using Microsoft.AspNetCore.Mvc;
using XiaodaERP.Models;
using XiaodaERP.Services;
using XiaodaERP.Services.IServices;
using XiaodaERP.Utils;
namespace XiaodaERP.Controllers
{
// 使用WebAPI
[ApiController]
[Route("/api/[controller]/[action]")] // 规定API URL格式
public class UserController : ControllerBase
{
// 注入UserService
private readonly IUserService _userService;
public UserController (IUserService userService)
{
_userService = userService;
}
// 添加与更新User Post请求 Name指定 action 的Url
[HttpPost(Name = "postUser")]
public ResultUtil PostUser(ViewUser viewUser) =>
ResultUtil.ok(_userService.UpdateUser(viewUser));
[HttpGet(Name = "getAllUserList")]
public ResultUtil GetAllUserList(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));
}
else
{
return ResultUtil.ok(_userService.GetAllUsers(deptId, userName, realName));
}
}
[HttpPut(Name = "resetToDefaultPassword")]
public ResultUtil ResetToDefaultPassword(string userId)
=> ResultUtil.ok(_userService.ResetToDefaultPassword(userId));
[HttpDelete(Name = "deleteUser")]
public ResultUtil DeleteUser(string userId) => ResultUtil.ok(_userService.DeleteUser(userId));
}
}






