接下来,我们在列表页面上加一些功能,来实现对部门信息的增删改查操作。
先实现作废功能。
在列表的每一行末尾增加一个作废按钮,点作废的时候弹出是否要作废的提示,如果用户点是,
执行作废的操作(作废之前要先判断是否有被用到),然后刷新部门列表。
因为作废后要还是要回到部门列表页,所以干脆就将作废功能放在 DeptList.cshtml 页面来完成,
在实现上只要调用 DeptList.cshtml 并将部门编号作为参数传递过去就可以了。
代码如下:
1. 作废功能(红色标记的是新增的部分)
DeptList.cshtml文件:
@page @model AuthManagement.Pages.Auth.DeptListModel @using AuthManagement.DbUtil.Entity @{ ViewData["Title"] = "部门管理"; } <table border="1" width="60%"> <tr style="background-color:antiquewhite;height:40px;"> <td>编号</td> <td>名称</td> <td>创建时间</td> <td> </td> </tr> @foreach (TDept item in Model.DeptList) //遍历输出部门信息 { <tr style="height:30px;"> <td>@item.DeptId</td> <td>@item.DeptName</td> <td>@item.CreateTime</td> <td><a href="/Auth/DeptList?deptid=@item.DeptId" target="_self" onclick="return confirm('确定要作废吗?');">作废</a></td> </tr> } @if (Model.DeptList.Count == 0) { <tr style="height:30px;"> <td colspan="4" align="center">没有查询到部门数据!</td> </tr> } </table>
DeptList.cshtml.cs文件代码如下:
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Text.Encodings.Web; using System.Text.Unicode; using AuthManagement.DbUtil.Entity; namespace AuthManagement.Pages.Auth { public class DeptListModel : PageModel { private readonly AuthDbContext _context; //构造函数中对AuthDbContext做依赖注入 public DeptListModel(AuthDbContext context) { _context = context; } //定义部门列表属性,用于传递给.cshtml页面使用(在OnGet()方法中赋值) public IList<TDept> DeptList { get; set; } public void OnGet() { string deptId = Request.Query["deptid"]; if (int.TryParse(deptId, out int did)) //如果该参数是一个数字说明是点作废后进来的 { //先查询该部门下是否能找到任何一个有效的User TUser user = _context.TUsers.Where<TUser>(user => user.DeptId == did && user.IsValid==1).FirstOrDefault<TUser>(); //如果没有找到才能执行作废的操作 if (user == null) { UpdateByFind(did); //也可以使用 UpdateDirectly() 方法更新数据库 } } //作废的部门不显示,所以这里用 Where() 函数处理条件查询 //参数是一个 Lambda 表达式,查询 is_valid=1 即未作废的部门数据。 DeptList = _context.TDepts.Where<TDept>(dept => dept.IsValid == 1).ToList<TDept>(); } //此方法更新时只会连接1次数据库并更新指定的字段 private void UpdateDirectly(int deptId) { //将要更新的字段及主键赋值 TDept dept = new TDept { DeptId = deptId, IsValid = 0, ModifyTime = DateTime.Now }; //跟踪实体 dept 的状态 _context.TDepts.Attach(dept); //标记要更改的属性是 IsValid 和 ModifyTime,不做标记即使赋值了也不会更改 _context.Entry<TDept>(dept).Property(dept => dept.IsValid).IsModified = true; _context.Entry<TDept>(dept).Property(dept => dept.ModifyTime).IsModified = true; //将更改保存到数据库 _context.SaveChanges(); } /// <summary> /// 此方法更新时会连接2次数据库并更新所有的字段。 /// 因为要写日志表,故调用这个方法更合适。 /// </summary> /// <param name="deptId"></param> private void UpdateByFind(int deptId) { //设置序列化时的对中文的编码方式 JsonSerializerOptions options = new JsonSerializerOptions { Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), }; List<TLog> logList = GenerateLog(); //初始化包含2条日志信息的列表 //先找出要更改的实体 TDept dept = _context.TDepts.Find(deptId); //将更改前的数据序列化成json后记录下来 logList[0].TableData = JsonSerializer.Serialize<TDept>(dept, options); //给要更改的属性赋值 dept.IsValid = 0; dept.ModifyTime = DateTime.Now; //将更改后的数据序列化成json后记录下来 logList[1].TableData = JsonSerializer.Serialize<TDept>(dept, options); //标记实体 State 已被修改 _context.Entry<TDept>(dept).State = EntityState.Modified; //保存数据到t_log表 _context.TLogs.AddRange(logList); //将更改保存到数据库 _context.SaveChanges(); } /// <summary> /// 将更改前和更改后的数据保存到t_log表 /// </summary> /// <returns></returns> private List<TLog> GenerateLog() { string batchNo = Guid.NewGuid().ToString(); TLog beforeLog = new TLog { UserId = 1, //因没有处理登录,这里用模拟数据 UserName = "张三", BatchNo = batchNo, TableName = "t_dept", TableData = "", LogTime = DateTime.Now }; TLog afterLog = new TLog { UserId = 1, UserName = "张三", BatchNo = batchNo, TableName = "t_dept", TableData = "", LogTime = DateTime.Now }; List<TLog> logList = new List<TLog>(); logList.Add(beforeLog); logList.Add(afterLog); return logList; } } }
编译后运行程序,效果如下:
点确定后数据库的 t_log 表生成了2条记录,如下: