This commit is contained in:
2021-10-19 06:29:11 +08:00
commit 60131e4608
131 changed files with 46479 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
@page
@model _2021_backend.Pages.Account.AccessDeniedModel
@{
ViewData["Title"] = "认证失败";
}
<h1>权限不足</h1>
<h3>认证失败,您没有足够的权限进行操作,请联系系统管理员</h3>
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace _2021_backend.Pages.Account
{
public class AccessDeniedModel : PageModel
{
public void OnGet()
{
}
}
}
+9
View File
@@ -0,0 +1,9 @@
@page
@model _2021_backend.Pages.Account.DeniedModel
@{
ViewData["Title"] = "登录";
}
<h1>登录</h1>
<h3>认证失败,请重新登录或联系系统管理员</h3>
<button class="btn btn-primary" asp-area="/" asp-page="/Account/Login">重新登录</button>
+17
View File
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace _2021_backend.Pages.Account
{
public class DeniedModel : PageModel
{
public void OnGet()
{
}
}
}
+35
View File
@@ -0,0 +1,35 @@
@page
@model _2021_backend.Pages.Account.LoginModel
@{
ViewData["Title"] = "登录";
}
<h1>登录</h1>
<div class="row">
<div class="col-md-8">
<section>
<form asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post" class="form-horizontal" role="form">
<div class="form-group">
<label class="col-md-2 control-label">学号</label>
<div class="col-md-10">
<input type="text" name="username" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">密码</label>
<div class="col-md-10">
<input type="password" name="password" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="btn btn-primary">冲!</button>
</div>
</div>
</form>
</section>
</div>
</div>
+148
View File
@@ -0,0 +1,148 @@
using _2021_backend.Data;
using _2021_backend.Models;
using _2021_backend.Utils;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Account
{
public class LoginModel : PageModel
{
private readonly string LoginURL = "https://xms.zjueva.net/api/auth/login";
private readonly IConfiguration config;
private readonly BackendContext context;
public LoginModel(IConfiguration configuration, BackendContext context)
{
config = configuration;
this.context = context;
}
public IActionResult OnGet(string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
return Page();
}
[BindProperty]
public string username { get; set; }
[BindProperty]
public string password { get; set; }
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var NowSecret = EvaCryptoHelper.Password2Secret(password);
string stuID = username;
var query = from _user in context.Users
where _user.stuID == stuID
select _user;
var user = await query.AsNoTracking().FirstOrDefaultAsync();
//need use xms login service
if (user == null)
{
Login login_Stu = new Login(username, password);
//post login information to xms.zjueva.net and receive the response with string
string ansString = LoginHelper.PostMoths(LoginURL, login_Stu);
JObject ansJson = (JObject)JsonConvert.DeserializeObject(ansString);
//error and Denied
if (ansJson["status"].ToString() == "error")
{
return RedirectToPage("/Account/Denied");
}
else if (ansJson["status"].ToString() == "success")
{
User add_user = new User()
{
stuID = ansJson["data"]["stuid"].ToString(),
Name = ansJson["data"]["name"].ToString(),
Secret = login_Stu.GetSHASecret(),
isManager = login_Stu.isManager()
};
context.Users.Add(add_user);
await context.SaveChangesAsync();
//add new user to DB and now continue to create cookie;
user = add_user;
//this user is correct and don't use the follow "else"
}
}
if (user.Secret == NowSecret)
{
var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme, ClaimTypes.Name, ClaimTypes.Role);
identity.AddClaim(new Claim(ClaimTypes.Name, user.Name));
identity.AddClaim(new Claim(ClaimTypes.Sid, user.Guid.ToString()));
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, username));
if (user.isManager)
{
identity.AddClaim(new Claim(EvaClaimTypes.IsManager, "true"));
identity.AddClaim(new Claim(ClaimTypes.Role, "manager"));
}
else
{
identity.AddClaim(new Claim(ClaimTypes.Role, "user"));
}
var Iprinciple = new ClaimsPrincipal(identity);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
Iprinciple,
new AuthenticationProperties
{
IsPersistent = true,
AllowRefresh = true
}
);
return RedirectToPage("/Students/Index");
}
//if user change his secret in XMS
else
{
Login login_Stu = new Login(username, password);
//post login information to xms.zjueva.net and receive the response with string
string ansString = LoginHelper.PostMoths(LoginURL, login_Stu);
JObject ansJson = (JObject)JsonConvert.DeserializeObject(ansString);
//error and Denied
if (ansJson["status"].ToString() == "error")
{
return RedirectToPage("/Account/Denied");
}
else
{
//change the secret in DB
user = await context.Users.FirstOrDefaultAsync(r => r.stuID == stuID);
user.Secret = login_Stu.GetSHASecret();
context.Attach(user).State = EntityState.Modified;
try
{
await context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
return NotFound();
}
return RedirectToPage("/Index");
}
}
}
}
}
+8
View File
@@ -0,0 +1,8 @@
@page
@model _2021_backend.Pages.Account.LogoutModel
@{
ViewData["Title"] = "登出";
}
<h1>正在登出</h1>
<h3>请稍后</h3>
+19
View File
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
namespace _2021_backend.Pages.Account
{
public class LogoutModel : PageModel
{
public async Task<IActionResult> OnGet()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return RedirectToPage("/Index");
}
}
}
+26
View File
@@ -0,0 +1,26 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
+31
View File
@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
private readonly ILogger<ErrorModel> _logger;
public ErrorModel(ILogger<ErrorModel> logger)
{
_logger = logger;
}
public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
+10
View File
@@ -0,0 +1,10 @@
@page
@model IndexModel
@{
ViewData["Title"] = "首页";
}
<div class="text-center">
<h1 class="display-4">欢迎使用</h1>
</div>
+25
View File
@@ -0,0 +1,25 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages
{
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public IndexModel(ILogger<IndexModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
+113
View File
@@ -0,0 +1,113 @@
@page
@model _2021_backend.Pages.Message.IndexModel
@{
}
@{
ViewData["Title"] = "发送短信";
}
<h5 class="text-red">
<strong>@Html.DisplayFor(model => Model.Errmsg)</strong>
</h5>
<h3><strong>发送短信</strong></h3>
<form method="post">
<input type="hidden" asp-for="pageid" />
<input type="submit" value="拉取5天内的回复短信" class="btn btn-primary" asp-page-handler="Pull" />
<input type="submit" value="发送报名确认短信" class="btn btn-primary" asp-page-handler="Sign" />
<input type="submit" value="发送确认短信" class="btn btn-primary" asp-page-handler="ResultAccept" />
<input type="submit" value="发送拒绝短信" class="btn btn-primary" asp-page-handler="ResultReject" />
</form>
<br />
<h3><strong>短信记录</strong></h3>
<hr />
<form method="post" class="form-inline">
<input type="hidden" asp-for="pageid" />
<div class="m-2">
<label class="form-check-label">
<input class="form-check-input" asp-for="showSend" />发出的短信
</label>
</div>
<div class="m-2">
<label class="form-check-label">
<input class="form-check-input" asp-for="showReceive" /> 收到的短信
</label>
</div>
<label asp-for="SearchString" class="control-label">按名字筛选</label>
<div class="m-2">
<input type="text" class="form-control" id="searchString" placeholder="输入部分姓名" asp-for="SearchString" name="SearchString">
</div>
<input type="submit" class="btn btn-primary" value="Go!" />
</form>
<table class="table">
<thead>
<tr>
<th>
发送者
</th>
<th>
学生姓名
</th>
<th>
发送时间
</th>
<th>
短信类型
</th>
<th>
短信内容
</th>
</tr>
</thead>
<tbody>
@if (Model.Messages.Count == 0)
{
@:暂无短信
}
else
{
@foreach (var e in Model.Messages)
{
<tr>
<td>
@Html.DisplayFor(it => e.Sender)
</td>
<td>
@{
var stu = Model.Context.Students.Find(e.Host);
string name = stu.Name;
@Html.DisplayFor(it => name)
}
</td>
<td>
@{
var str = e.SendTime.ToString("MM月dd日 hh:mm:ss");
@Html.DisplayFor(it => str)
}
</td>
<td>
@Html.DisplayFor(it => e.Type)
</td>
<td>
@if (e.Type == _2021_backend.Models.SMSType.Reply)
{
@Html.DisplayFor(it => e.Data[0])
}
</td>
</tr>
}
}
</tbody>
</table>
<nav>
<ul class="pagination">
<li class="page-item @(Model.pageid==0 ? "disabled" : "")"><a class="page-link" asp-route-pageId="@(Model.pageid-1) " >Prev</a></li>
@for (int i = 0; i < Model.PageCount; i++)
{
<li class="page-item @(Model.pageid==i ? "active" : "")"><a class="page-link" asp-route-pageId="@i" >@i</a></li>
}
<li class="page-item @(Model.pageid>=Model.PageCount -1? "disabled" : "")"><a class="page-link" asp-route-pageId="@(Model.pageid+1)" >Next</a></li>
</ul>
</nav>
+135
View File
@@ -0,0 +1,135 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Message
{
public class IndexModel : PageModel
{
public readonly _2021_backend.Data.BackendContext Context;
[BindProperty]
public string Errmsg { get; set; }
[BindProperty]
public string SearchString { get; set; }
[BindProperty]
public bool showSend { get; set; }
[BindProperty]
public bool showReceive { get; set; }
[BindProperty]
public int pageid { get; set; }
public static int pageSize = 30;
public List<SMS> Messages { get; set; }
public int PageCount { get; set; }
public IndexModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public IActionResult Construct(int PageId)
{
List<Guid> stus;
IQueryable<Guid> q;
if (!String.IsNullOrEmpty(SearchString)) q = from e in Context.Students where e.Name.Contains(SearchString) select e.Guid;
else q = from e in Context.Students select e.Guid;
stus = q.ToList();
var q2 = from e in Context.SMS where stus.Contains(e.Host) select e;
if (showReceive && !showSend) q2 = from e in q2 where e.Type == SMSType.Reply select e;
else if (!showReceive && showSend) q2 = from e in q2 where e.Type != SMSType.Reply select e;
Messages = q2.ToList();
Messages.Sort((SMS a, SMS b) => b.SendTime.CompareTo(a.SendTime));
int cnt = Messages.Count;
PageCount = (int)Math.Ceiling((double)cnt / (double)pageSize);
if (PageId >= PageCount) PageId = PageCount - 1;
if (PageId < 0) PageId = 0;
pageid = PageId;
int count = (PageId + 1) * pageSize > cnt ? (cnt - PageId * pageSize) : pageSize;
Messages = Messages.GetRange(PageId * pageSize, count);
return Page();
}
public async Task<IActionResult> OnGetAsync(int PageId)
{
return Construct(PageId);
}
public async Task<IActionResult> OnPostAsync(int PageId)
{
return Construct(PageId);
}
public async void OnPostPullAsync(int PageId)
{
var stu = Context.Students.ToList();
foreach (var e in stu)
{
await Utils.TencentSMS.Pull(Context, e, true);
}
Construct(PageId);
}
public async Task<IActionResult> OnPostSignAsync(int PageId)
{
var stu = Context.Students.ToList();
foreach (var e in stu)
{
if (e.Status == status.刚报名)
await Utils.TencentSMS.Send(Context, SMSType.Signed, e, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
}
return Construct(PageId);
}
public async Task<IActionResult> OnPostResultRejectAsync(int PageId)
{
var stu = Context.Students.ToList();
foreach (var e in stu)
{
if (e.Status == status.不通过)
{
if (!Context.SMS.Any(it => it.Host == e.Guid && it.Type == SMSType.Reject))
await Utils.TencentSMS.Send(Context, SMSType.Reject, e, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
}
}
return Construct(PageId);
}
public async Task<IActionResult> OnPostResultAccpetAsync(int PageId)
{
var stu = Context.Students.ToList();
foreach (var e in stu)
{
if (e.Status == status.通过)
{
if (!Context.SMS.Any(it => it.Host == e.Guid && it.Type == SMSType.Accept))
await Utils.TencentSMS.Send(Context, SMSType.Accept, e, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
}
}
return Construct(PageId);
}
}
}
+10
View File
@@ -0,0 +1,10 @@
@page
@model _2021_backend.Pages.MigrateModel
@{
ViewData["Title"] = "Migrate";
}
<h1>Migrate</h1>
<form method="post">
<input type="submit" value="Migrate" class="btn btn-danger"/>
</form>
+29
View File
@@ -0,0 +1,29 @@
using _2021_backend.Data;
using _2021_backend.Models;
using _2021_backend.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using NPOI.HPSF;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages
{
public class MigrateModel : PageModel
{
private readonly BackendContext _context;
public MigrateModel(BackendContext context)
{
_context = context;
}
public async Task<IActionResult> OnPost(string value)
{
_context.Database.Migrate();
return RedirectToPage("./Index");
}
}
}
+8
View File
@@ -0,0 +1,8 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "关于";
}
<h1>@ViewData["Title"]</h1>
<p>该后端由<a href="https://itszzz.top">Azuk 443</a>设计开发,2021技术小组合作贡献,使用问题请联系EVA Tech</p>
+24
View File
@@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages
{
public class PrivacyModel : PageModel
{
private readonly ILogger<PrivacyModel> _logger;
public PrivacyModel(ILogger<PrivacyModel> logger)
{
_logger = logger;
}
public void OnGet()
{
}
}
}
+64
View File
@@ -0,0 +1,64 @@
@page
@model _2021_backend.Pages.Sessions.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>InterviewTime</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="InterviewTime.Day" class="control-label"></label>
<input asp-for="InterviewTime.Day" class="form-control" />
<span asp-validation-for="InterviewTime.Day" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="InterviewTime.BeginTime" class="control-label"></label>
<input asp-for="InterviewTime.BeginTime" class="form-control" />
<span asp-validation-for="InterviewTime.BeginTime" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="InterviewTime.Place" class="control-label"></label>
<select asp-for="InterviewTime.Place" class="form-control">
<option value="200">200</option>
<option value="204">204</option>
</select>
<span asp-validation-for="InterviewTime.Place" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="InterviewTime.Capacity" class="control-label"></label>
<input asp-for="InterviewTime.Capacity" class="form-control" />
<span asp-validation-for="InterviewTime.Capacity" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="InterviewTime.SendSMS" /> @Html.DisplayNameFor(model => model.InterviewTime.SendSMS)
</label>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="CreateTwo" /> @Html.DisplayNameFor(model => model.CreateTwo)
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+80
View File
@@ -0,0 +1,80 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Sessions
{
public class CreateModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
[Display(Name = "同时创建200和204场次")]
[BindProperty]
public bool CreateTwo { get; set; }
[BindProperty]
public Session InterviewTime { get; set; }
[BindProperty]
[Display(Name = "活动官")]
public string ChiefGuid { get; set; }
public List<SelectListItem> ChiefList { get; set; }
public CreateModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public async Task<IActionResult> OnGet()
{
var qlst = from e in Context.Users select (new SelectListItem { Value = e.Guid.ToString(), Text = e.Name, Selected = false, Disabled = false });
var lst = qlst.ToList().Distinct().ToList();
ChiefList = lst;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
InterviewTime.Students = new List<Guid>();
InterviewTime.Chiefs = new List<Guid>();
Session interviewTimeSecond = new Session();
if (CreateTwo)
{
string anotherPlace = InterviewTime.Place == "200" ? "204" : "200";
Session tmp = Context.Sessions.FirstOrDefault(r => r.Place == anotherPlace && r.Day == InterviewTime.Day && InterviewTime.BeginTime == r.BeginTime);
if (tmp == null)
{
interviewTimeSecond = new Session()
{
Day = InterviewTime.Day,
BeginTime = InterviewTime.BeginTime,
Place = anotherPlace,
Chiefs = new List<Guid>(),
SendSMS = InterviewTime.SendSMS,
Students = new List<Guid>(),
Capacity = InterviewTime.Capacity
};
Context.Add(interviewTimeSecond);
Context.SaveChanges();
}
}
Context.Sessions.Add(InterviewTime);
Context.SaveChanges();
return RedirectToPage("./Index");
}
}
}
+41
View File
@@ -0,0 +1,41 @@
@page
@model _2021_backend.Pages.Sessions.DeleteModel
@{
ViewData["Title"] = "Delete";
}
<h1>Delete</h1>
<h3>你确定要把这场删掉吗?</h3>
<div>
<h4>删除场次</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.InterviewTime.Day)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.InterviewTime.Day)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.InterviewTime.BeginTime)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.InterviewTime.BeginTime)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.InterviewTime.Capacity)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.InterviewTime.Capacity)
</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="InterviewTime.Guid" />
<input type="submit" value="确定删除" class="btn btn-danger" /> |
<a asp-page="./Index">Back to List</a>
</form>
</div>
+77
View File
@@ -0,0 +1,77 @@
using _2021_backend.Data;
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Sessions
{
public class DeleteModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public DeleteModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Session InterviewTime { get; set; }
public async Task<IActionResult> OnGetAsync(string? id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
InterviewTime = Context.Sessions.Find(guid);
if (InterviewTime == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string? id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
InterviewTime = await Context.Sessions.FindAsync(guid);
if (InterviewTime != null)
{
if (InterviewTime.Students.Count > 0)
{
foreach (var x in InterviewTime.Students)
{
Student stu = Context.Students.Find(x);
if (stu != null)
{
stu.InterviewTime = Guid.Empty;
stu.Timelist.RemoveAll(it => it == guid);
}
Context.SaveChanges();
}
}
foreach(var x in Context.Students)
{
x.Timelist.RemoveAll(it => it == guid);
}
Context.Sessions.Remove(InterviewTime);
Context.SaveChanges();
}
return RedirectToPage("./Index");
}
}
}
+69
View File
@@ -0,0 +1,69 @@
@page
@model _2021_backend.Pages.Sessions.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>InterviewTime</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CurSession.Day)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.CurSession.Day)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CurSession.BeginTime)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.CurSession.BeginTime)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CurSession.Place)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.CurSession.Place)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CurSession.Chiefs)
</dt>
<dd class="col-sm-10">
@{
var nm = "";
foreach (var e in Model.CurSession.Chiefs)
{
nm += Model.Context.Users.Find(e).Name + " ";
}
@Html.DisplayFor(model => nm);
}
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CurSession.Capacity)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.CurSession.Capacity)
</dd>
<dt class="col-sm-2">
已经报名人数
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.CurSession.Students.Count)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.CurSession.SendSMS)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.CurSession.SendSMS)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="@Model.CurSession.Guid">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
+39
View File
@@ -0,0 +1,39 @@
using _2021_backend.Data;
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Sessions
{
public class DetailsModel : PageModel
{
public _2021_backend.Data.BackendContext Context;
public DetailsModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public Session CurSession { get; set; }
public async Task<IActionResult> OnGetAsync(string? id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
CurSession = Context.Sessions.Find(guid);
if (CurSession == null)
{
return NotFound();
}
return Page();
}
}
}
+152
View File
@@ -0,0 +1,152 @@
@page
@model _2021_backend.Pages.Sessions.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>编辑</h1>
<h4>InterviewTime</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="CurSession.Guid" />
<input type="hidden" asp-for="CurGuid">
<div class="form-group">
<label asp-for="newDay" class="control-label"></label>
<input asp-for="newDay" class="form-control" />
<span asp-validation-for="CurSession.Day" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="newTime" class="control-label"></label>
<input asp-for="newTime" class="form-control" />
<span asp-validation-for="CurSession.BeginTime" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="newPlace" class="control-label"></label>
<input asp-for="newPlace" class="form-control" />
<span asp-validation-for="CurSession.Place" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="newCapacity" class="control-label"></label>
<input asp-for="newCapacity" class="form-control" />
<span asp-validation-for="CurSession.Capacity" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="CurSession.SendSMS" /> @Html.DisplayNameFor(model => model.CurSession.SendSMS)
</label>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<hr />
<h4>该时段的活动者</h4>
<form method="post">
<label class="col-sm-2">添加一个</label>
<select asp-items=Model.Stulist id="stuselect" asp-for="addedStu" class="col-sm-2"></select>
<input type="hidden" asp-for="CurGuid" />
<input type="submit" value="Go!" class="btn btn-primary" style="margin-left:5px" asp-page-handler="Add" />
</form>
<br />
<table class="table">
<thead>
<tr>
<th>学号</th>
<th>姓名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (var it in Model.CurSession.Students)
{
<tr>
@{
var stu = Model.Context.Students.Find(it);
if (stu != null)
{
var id = stu.Stuid;
<td>@Html.DisplayFor(model=>id)</td>
<td>@Html.DisplayFor(model=>stu.Name)</td>
<td>
<a asp-page="/Students/Details" asp-route-idstr=@stu.Guid.ToString() class="btn btn-primary">详细信息</a>
<div style="float:left">
<form method="post">
<input type="hidden" asp-for="CurGuid">
<input type="submit" value="删除" class="btn btn-danger" asp-page-handler="Delete" asp-route-id=@stu.Guid.ToString() />
</form>
</div>
</td>
}
}
</tr>
}
</tbody>
</table>
<hr />
<h4>活动官们</h4>
<form method="post">
<label class="col-sm-2">添加一个</label>
<select id="chiefselect"asp-items=Model.ChiefList asp-for="addedChief" class="col-sm-2"></select>
<input type="hidden" asp-for="CurGuid" />
<input type="submit" value="Go!" class="btn btn-primary" style="margin-left:5px" asp-page-handler="AddChief" />
</form>
<br />
<table class="table">
<thead>
<tr>
<th>姓名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (var it in Model.CurSession.Chiefs)
{
<tr>
@{
var chf = Model.Context.Users.Find(it);
if (chf != null)
{
<td>@Html.DisplayFor(model=>chf.Name)</td>
<td>
<div style="float:left">
<form method="post">
<input type="hidden" asp-for="CurGuid">
<input type="submit" value="删除" class="btn btn-danger" asp-page-handler="DeleteChief" asp-route-id=@chf.Guid.ToString() />
</form>
</div>
</td>
}
}
</tr>
}
</tbody>
</table>
<div>
<a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js"></script>
<script type="text/javascirpt" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css" />
<script>
$(function(){
$("#chiefselect").select2();
$("#stuselect").select2();
});
</script>
}
+188
View File
@@ -0,0 +1,188 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Sessions
{
public class EditModel : PageModel
{
public _2021_backend.Data.BackendContext Context;
public EditModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Session CurSession { get; set; }
[BindProperty]
public string CurGuid { get; set; }
[BindProperty]
public string ChiefSearch { get; set; }
public List<SelectListItem> ChiefList { get; set; }
public List<SelectListItem> Stulist { get; set; }
[BindProperty]
public Guid addedChief { get; set; }
[BindProperty]
public string addedStu { get; set; }
[BindProperty]
public string ChiefName { get; set; }
[BindProperty]
[Display(Name ="活动地点")]
[RegularExpression(@"^20[04]$", ErrorMessage = "200或204")]
[Required()]
public string newPlace { get; set; }
[BindProperty]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
[Required()]
public DateTime newDay { get; set; }
[BindProperty]
[DataType(DataType.Time)]
[DisplayFormat(DataFormatString = "{0:t}", ApplyFormatInEditMode = true)]
[Required()]
public DateTime newTime { get; set; }
[BindProperty]
[Required()]
public bool sendSMS { get; set; }
[BindProperty]
public int newCapacity { get; set; }
public IActionResult Construct(string id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
CurGuid = id;
CurSession = Context.Sessions.Find(guid);
newDay = CurSession.Day;
newTime = CurSession.BeginTime;
newCapacity = CurSession.Capacity;
sendSMS = CurSession.SendSMS;
newPlace = CurSession.Place;
if (CurSession == null) return RedirectToPage("./Index", new { errmsg = "未找到该活动场次" });
var qlst = from e in Context.Users select (new SelectListItem { Value = e.Guid.ToString(), Text = e.Name, Selected = false, Disabled = false });
ChiefList = qlst.ToList().Distinct().ToList();
var slst = from e in Context.Students where e.InterviewTime == Guid.Empty select new SelectListItem { Value = e.Guid.ToString(), Text = e.Name, Selected = false, Disabled = false };
Stulist = slst.ToList().Distinct().ToList();
return Page();
}
public async Task<IActionResult> OnGetAsync(string id)
{
return Construct(id);
}
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
var ssn = Context.Sessions.Find(Guid.Parse(CurGuid));
ssn.SendSMS = sendSMS;
ssn.Day = newDay;
ssn.BeginTime = newTime;
ssn.Capacity = newCapacity;
ssn.Place = newPlace;
Context.SaveChanges();
return RedirectToPage("./Index");
}
public async Task<IActionResult> OnPostDeleteAsync(string id)
{
CurSession = Context.Sessions.Find(Guid.Parse(CurGuid));
var guid = Guid.Parse(id);
if (!string.IsNullOrEmpty(id))
{
if (Context.Students.Any(it => it.Guid == guid))
{
Context.Students.Find(guid).InterviewTime = Guid.Empty;
CurSession.Students.RemoveAll(it => it == guid);
}
Context.SaveChanges();
}
return Construct(CurGuid);
}
public async Task<IActionResult> OnPostAddAsync()
{
CurSession = Context.Sessions.Find(Guid.Parse(CurGuid));
var guid = Guid.Parse(addedStu);
if (!string.IsNullOrEmpty(addedStu))
{
if (Context.Students.Any(it => it.Guid == guid))
{
var stu = Context.Students.Find(guid);
if(stu.InterviewTime != Guid.Empty)
{
var oldtime = Context.Sessions.Find(stu.InterviewTime);
if(oldtime != null)
{
oldtime.Students.RemoveAll(s => s == stu.Guid);
Context.SaveChanges();
}
}
stu.InterviewTime = CurSession.Guid;
stu.Status = status.已选时间;
CurSession.Students.Add(guid);
}
Context.SaveChanges();
}
return Construct(CurGuid);
}
public async Task<IActionResult> OnPostAddChiefAsync()
{
CurSession = Context.Sessions.Find(Guid.Parse(CurGuid));
if (Context.Users.Any(it => it.Guid == addedChief))
{
CurSession.Chiefs.Add(addedChief);
}
Context.SaveChanges();
return Construct(CurGuid);
}
public async Task<IActionResult> OnPostDeleteChiefAsync(string id)
{
var guid = Guid.Parse(id);
CurSession = Context.Sessions.Find(Guid.Parse(CurGuid));
if (CurSession.Chiefs.Contains(guid))
{
CurSession.Chiefs.Remove(guid);
}
Context.SaveChanges();
return Construct(CurGuid);
}
private bool InterviewTimeExists(Guid id)
{
return Context.Sessions.Any(e => e.Guid == id);
}
}
}
+167
View File
@@ -0,0 +1,167 @@
@page
@model _2021_backend.Pages.Sessions.IndexModel
@{
ViewData["Title"] = "活动时间管理";
}
<h5 class="text-red">
<strong>@Html.DisplayFor(model => Model.Errmsg)</strong>
</h5>
<h5><strong>全部活动场次</strong></h5>
<a asp-page="./Create" class="btn btn-outline-info m-2">创建新的场次</a>
<a asp-page="./Export" class="btn btn-outline-info m-2">导出</a>
<form class="form-inline" method="post">
<div class="m-2">
筛选日期
<select asp-for="Day" asp-items="Model.DayList" class="form-control">
<option value="">全部</option>
</select>
</div>
<div class="m-2">
筛选场次
<select asp-for="Room" class="form-control">
<option value="">全部</option>
<option value="200">200</option>
<option value="204">204</option>
</select>
</div>
<div class="m-2">
<label class="form-check-label">
只显示未满场次
<input class="form-check-input" asp-for="onlyShowUnFull" />
</label>
</div>
<input type="submit" value="筛选" class="btn btn-outline-primary m-2" />
<input type="submit" value="自动生成新的排班" class="btn btn-outline-warning m-2" asp-page-handler="Arrange" />
<input type="submit" value="全部清空" class="btn btn-outline-danger m-2" asp-page-handler="ClearAll" />
<input type="submit" value="整理一下" class="btn btn-outline-info m-2" asp-page-handler="Tidy" />
<input type="submit" value="重置全部场次" class="btn btn-outline-danger m-2" asp-page-handler="ResetAll" />
<input type="submit" value="保存当前结果" class="btn btn-outline-danger m-2" asp-page-handler="Save" />
<div class="m-2">
加载存档
<select asp-for="savename" class="form-control" asp-items="Model.Files">
</select>
</div>
<input type="submit" value="Go!" class="btn btn-outline-danger m-2" asp-page-handler="Load" />
@*<input type="submit" value="保存这个结果!" class="btn btn-outline-warning m-2" asp-page-handler="Save"/>
<div class="m-2">
加载以前的结果
<select asp-for="TargetIndex" class="form-control" asp-items="@Model.SaveNames">
</select>
</div>*@
@*<input type="submit" value="Load!" class="btn btn-outline-primary m-2" asp-page-handler="Load"/>*@
</form>
<table class="table">
<thead>
<tr>
<th>
序号
</th>
<th>
@Html.DisplayNameFor(model => model.LoadedSessions[0].Day)
</th>
<th>
@Html.DisplayNameFor(model => model.LoadedSessions[0].BeginTime)
</th>
<th>
@Html.DisplayNameFor(model => model.LoadedSessions[0].Place)
</th>
<th>
@Html.DisplayNameFor(model => model.LoadedSessions[0].Chiefs)
</th>
<th>
剩余可用人数
</th>
<th>
容量
</th>
<th>
@Html.DisplayNameFor(model => model.LoadedSessions[0].SendSMS)
</th>
<th>
参与者
</th>
<th>
操作
</th>
</tr>
</thead>
<tbody>
@{
var idx = 0;
}
@foreach (var item in Model.LoadedSessions)
{
<tr class="@{
if (item.Day.Date.Add(item.BeginTime.TimeOfDay).CompareTo(DateTime.Now) < 0)
@("table-secondary")
else if (item.Students.Count == item.Capacity)
@("table-warning")
else if(item.Place=="200")
@("table-success")
else
@("table-info")
} ">
<td>
@{
idx++;
@Html.DisplayFor(mi => idx)
}
</td>
<td>
@Html.DisplayFor(modelItem => item.Day)
</td>
<td>
@Html.DisplayFor(modelItem => item.BeginTime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Place)
</td>
<td>
@{
var str = "";
foreach (var i in item.Chiefs)
{
str += Model.Context.Users.Find(i).Name + " ";
}
@Html.DisplayFor(modelItem => str)
;
}
</td>
<td>
@Html.DisplayFor(modelItem => item.Capacity)
</td>
<td>
@{
var cnt = item.Capacity - item.Students.Count;
@Html.DisplayFor(modelItem => cnt)
}
</td>
<td>
@Html.DisplayFor(modelItem => item.SendSMS)
</td>
<td>
@foreach (var it in item.Students)
{
var q = Model.Context.Students.Find(it);
var s = q.Name;
<a asp-page="/Students/Details" asp-route-idstr=@it.ToString()>@Html.DisplayFor(modelItem => s)</a>
@:&nbsp
}
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.Guid">编辑</a> |
<a asp-page="./Delete" asp-route-id="@item.Guid">删除</a> |
<a asp-page-handler="Reset" asp-route-id="@item.Guid">重置</a>
</td>
</tr>
}
</tbody>
</table>
+283
View File
@@ -0,0 +1,283 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Text.Json;
using System.IO;
namespace _2021_backend.Pages.Sessions
{
public class IndexModel : PageModel
{
public readonly _2021_backend.Data.BackendContext Context;
public IndexModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public List<Session> LoadedSessions { get; set; }
public SelectList DayList { get; set; }
[BindProperty(SupportsGet = true)]
public string Room { get; set; }
[BindProperty]
public string Errmsg { get;set; }
[BindProperty]
public string savename { get; set; }
[BindProperty(SupportsGet = true)]
public bool onlyShowUnFull { get; set; }
[BindProperty(SupportsGet = true)]
public DateTime Day { get; set; }
[BindProperty]
public int TargetIndex { get; set; }
public SelectList Files { get; set; }
public IActionResult Construct(string errmsg)
{
Errmsg = errmsg;
var q = from s in Context.Sessions select s;
if (Day != DateTime.MinValue)
{
q = from t in q where t.Day == Day select t;
}
if (Room == "200" || Room == "204")
{
q = from t in q where t.Place == Room select t;
}
if (onlyShowUnFull)
{
q = from t in q where t.Capacity != t.Students.Count select t;
}
LoadedSessions = q.ToList();
LoadedSessions.Sort((Session a, Session b) =>
{
var x = a.Day.Date.Add(a.BeginTime.TimeOfDay).CompareTo(DateTime.Now);
var y = b.Day.Date.Add(b.BeginTime.TimeOfDay).CompareTo(DateTime.Now);
if (x != y) return y - x;
else
{
var z = a.Day.Date.Add(a.BeginTime.TimeOfDay).CompareTo(b.Day.Date.Add(b.BeginTime.TimeOfDay));
if (z != 0) return z;
else
{
if (a.BeginTime < b.BeginTime) return -1;
else if (a.BeginTime > b.BeginTime) return 1;
else if (a.Place == "200") return -1;
else if (a.Place == "204") return 1;
return 0;
}
}
});
var l = from it in LoadedSessions select it.Day;
DayList = new SelectList(l.Distinct());
if (!Directory.Exists("./saves")) Directory.CreateDirectory("./saves");
Files = new SelectList(Directory.GetFiles("./saves").ToList());
//Console.WriteLine(Files);
return Page();
}
public async Task<IActionResult> OnGetAsync(string errmsg)
{
return Construct(errmsg);
}
public async Task<IActionResult> OnGetResetAsync(Guid id)
{
if(Context.Sessions.Any(it => it.Guid == id))
{
var s = Context.Sessions.Find(id);
foreach(var st in s.Students)
{
var e = Context.Students.Find(st);
e.Status = status.需调整时间;
e.InterviewTime = Guid.Empty;
}
s.Students.Clear();
}
Context.SaveChanges();
return Construct("");
}
public async Task<IActionResult> OnPost()
{
return Construct("");
}
//public async Task<IActionResult> OnPostLoadAsync()
//{
// return Construct("");
//}
//public async Task<IActionResult> OnPostSaveAsync()
//{
// return Construct("");
//}
public async Task<IActionResult> OnPostArrangeAsync()
{
if (Utils.Arranger.Arrange(Context)) return Construct("");
else return Construct("排班失败,无法满足条件");
}
public async Task<IActionResult> OnPostClearAllAsync()
{
foreach(var s in Context.Students)
{
s.InterviewTime = Guid.Empty;
s.Status = status.需调整时间;
s.Timelist.Clear();
}
Context.SaveChanges();
foreach(var s in Context.Sessions)
{
Context.Sessions.Remove(s);
}
Context.SaveChanges();
return Construct("");
}
public async Task<IActionResult> OnPostResetAllAsync()
{
var stus = Context.Students.ToList();
foreach (var s in stus)
{
if(s.Status == status.已选时间)
{
s.InterviewTime = Guid.Empty;
s.Timelist.RemoveAll(it => !Context.Sessions.Any(k => k.Guid == it));
s.Timelist.Sort((Guid a, Guid b) =>
{
var x = Context.Sessions.Find(a);
var y = Context.Sessions.Find(b);
var k1 = x.Day.CompareTo(y.Day);
var k2 = x.BeginTime.CompareTo(y.BeginTime);
return k1 != 0 ? k1 : k2;
});
}
}
Context.SaveChanges();
foreach (var s in Context.Sessions)
{
s.Students.Clear();
}
Context.SaveChanges();
return Construct("");
}
public async Task<IActionResult> OnPostSaveAsync()
{
var lst = Context.Sessions.ToList();
var str = JsonSerializer.Serialize(lst);
Console.WriteLine("Saving arrangement: " + str);
if(!Directory.Exists("./saves")) Directory.CreateDirectory("./saves/");
System.IO.File.WriteAllText($"./saves/{DateTime.Now.ToString("MM-dd-hh-mm-ss")}.txt", str);
return Construct("");
}
public async Task<IActionResult> OnPostTidyAsync()
{
var stus = Context.Students.ToList();
var sess = Context.Sessions.ToList();
foreach(var i in stus)
{
var tm = i.Timelist;
var ntm = new List<Session>();
foreach(var j in tm)
{
var k = sess.Find(it => it.Guid == j);
ntm.Add(k);
}
ntm.Sort((Session a,Session b) =>
{
var x = a.Day.CompareTo(b.Day);
var y = a.BeginTime.CompareTo(b.BeginTime);
return x != 0 ? x : y;
});
List<Guid> nl = new List<Guid>();
foreach(var j in ntm)
{
if(i.Status != status.不通过 && i.Status != status.通过 && i.Status != status.已确认时间)
{
if (j.Day.Date.Add(j.BeginTime.TimeOfDay).CompareTo(DateTime.Now) < 0 || (j.Students.Count >= j.Capacity && !j.Students.Any(k => k ==i.Guid) )) continue;
nl.Add(j.Guid);
}
else
{
nl.Add(j.Guid);
}
}
i.Timelist = nl;
}
Context.SaveChanges();
return Construct("");
}
public async Task<IActionResult> OnPostLoadAsync()
{
var str = "";
List<Session> loads = new List<Session>();
if (!string.IsNullOrEmpty(savename)) str = System.IO.File.ReadAllText(savename);
loads = JsonSerializer.Deserialize<List<Session>>(str);
var stus = Context.Students.ToList();
foreach (var s in stus)
{
if (s.Status == status.已选时间)
{
s.InterviewTime = Guid.Empty;
s.Timelist.RemoveAll(it => !Context.Sessions.Any(k => k.Guid == it));
s.Timelist.Sort((Guid a, Guid b) =>
{
var x = Context.Sessions.Find(a);
var y = Context.Sessions.Find(b);
var k1 = x.Day.CompareTo(y.Day);
var k2 = x.BeginTime.CompareTo(y.BeginTime);
return k1 != 0 ? k1 : k2;
});
}
}
Context.SaveChanges();
foreach (var s in Context.Sessions)
{
s.Students.Clear();
}
Context.SaveChanges();
foreach(var item in loads)
{
Session s = Context.Sessions.Find(item.Guid);
if(s != null)
{
s.BeginTime = item.BeginTime;
s.Day = item.Day;
s.Capacity = item.Capacity;
s.SendSMS = item.SendSMS;
s.Chiefs = item.Chiefs;
s.Students = new List<Guid>();
foreach(var s2 in item.Students)
{
if (Context.Students.Any(k => k.Guid == s2))
{
Context.Students.Find(s2).InterviewTime = item.Guid;
s.Students.Add(s2);
}
}
}
}
Context.SaveChanges();
return Construct("");
}
}
}
+86
View File
@@ -0,0 +1,86 @@
@using _2021_backend.Utils;
@using System.Security.Claims;
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - 2021 精品活动后台</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container-fluid">
<a class="navbar-brand" asp-area="" asp-page="/Index">2021纳新后台</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
@if (HttpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
{
<div class="form-inline my-2 my-lg-0 nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Account/Logout">登出</a>
</div>
}
else
{
<div class="form-inline my-2 my-lg-0 nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Account/Login">登录</a>
</div>
}
@if (HttpContextAccessor.HttpContext.User.Identity.IsAuthenticated)
{
<div class="form-inline my-2 my-lg-0">
<span class="nav-item">欢迎您,@(HttpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name).Value)</span>
</div>
}
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Index">首页</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Students/Index">已报名学生</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Submissions/Index">提交记录</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Message/Index">短信</a>
</li>
@if (HttpContextAccessor.HttpContext.User.HasClaim(EvaClaimTypes.IsManager, "true"))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Users/Index">后台用户管理</a>
</li>
}
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-page="/Sessions/Index">活动排班</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container-fluid">
<main role="main" class="pb-3">
@RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2021-backend <a asp-area="" asp-page="/Privacy">关于</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
@RenderSection("Scripts", required: false)
</body>
</html>
@@ -0,0 +1,2 @@
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
+79
View File
@@ -0,0 +1,79 @@
@page
@model _2021_backend.Pages.Students.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>创建</h1>
<h4>学生</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Student.Name" class="control-label"></label>
<input asp-for="Student.Name" class="form-control" />
<span asp-validation-for="Student.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Stuid" class="control-label"></label>
<input asp-for="Student.Stuid" class="form-control" />
<span asp-validation-for="Student.Stuid" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Sex" class="control-label"></label>
<select asp-for="Student.Sex" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.sex))"></select>
<span asp-validation-for="Student.Sex" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Yard" class="control-label"></label>
<select asp-for="Student.Yard" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.yard))"></select>
<span asp-validation-for="Student.Yard" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Grade" class="control-label"></label>
<select asp-for="Student.Grade" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.grade))"></select>
<span asp-validation-for="Student.Grade" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Major" class="control-label"></label>
<input asp-for="Student.Major" class="form-control" />
<span asp-validation-for="Student.Major" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Email" class="control-label"></label>
<input asp-for="Student.Email" class="form-control" />
<span asp-validation-for="Student.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Tel" class="control-label"></label>
<input asp-for="Student.Tel" class="form-control" />
<span asp-validation-for="Student.Tel" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Status" class="control-label"></label>
<select asp-for="Student.Status" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.status))"></select>
<span asp-validation-for="Student.Status" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.RegisterTime" class="control-label"></label>
<input asp-for="Student.RegisterTime" class="form-control" />
<span asp-validation-for="Student.RegisterTime" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">返回列表</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+48
View File
@@ -0,0 +1,48 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Students
{
public class CreateModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public CreateModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public IActionResult OnGet()
{
Student = new Student();
return Page();
}
[BindProperty]
[Required(ErrorMessage = "该项不能为空")]
public Student Student { get; set; }
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (Context.Students.Any(t => (t.Name == Student.Name || t.Stuid == Student.Stuid || t.Tel == Student.Tel)))
{
return RedirectToPage("./Index", new { pageId = 0, errInfo = "该学生已经存在" });
}
Context.Students.Add(Student);
await Context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
}
+82
View File
@@ -0,0 +1,82 @@
@page
@model _2021_backend.Pages.Students.DeleteModel
@{
ViewData["Title"] = "Delete";
}
<h1>删除</h1>
<h3>你确定要删除该项目吗?</h3>
<div>
<h4>学生</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Stuid)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Stuid)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Sex)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Sex)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Grade)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Grade)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Major)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Major)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Email)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Email)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Tel)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Tel)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Status)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Status)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.LastSubmission)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.LastSubmission)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.RegisterTime)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.RegisterTime)
</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="Student.Guid" />
<input type="submit" value="删除" class="btn btn-danger" /> |
<a asp-page="./Index">返回列表</a>
</form>
</div>
+67
View File
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Students
{
public class DeleteModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public DeleteModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Student Student { get; set; }
public async Task<IActionResult> OnGetAsync(string? idstr)
{
if (idstr == null)
{
return NotFound();
}
Guid id = Guid.Parse(idstr);
Student = await Context.Students.FirstOrDefaultAsync(m => m.Guid == id);
if (Student == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string? idstr)
{
if (idstr == null)
{
return NotFound();
}
Guid id = Guid.Parse(idstr);
Student = await Context.Students.FindAsync(id);
if (Student != null)
{
var q = from e in Context.Sessions where e.Students.Contains(id) select e;
var lst = q.ToList();
foreach(var it in lst)
{
it.Students.RemoveAll(k => k == id);
}
Context.Students.Remove(Student);
Context.SaveChanges();
}
return RedirectToPage("./Index");
}
}
}
+370
View File
@@ -0,0 +1,370 @@
@page
@model _2021_backend.Pages.Students.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h1>@Html.DisplayFor(model=> Model.Student.Name)</h1>
<div>
<h4>详细信息</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Stuid)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Stuid)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Sex)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Sex)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Grade)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Grade)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Major)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Major)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Email)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Email)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Tel)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Tel)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.Status)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.Status)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Student.RegisterTime)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Student.RegisterTime)
</dd>
</dl>
</div>
<h5>此人的最终得分 : @Html.DisplayFor(model => model.Student.Score)</h5>
<form method="post" class="form-inline m-2">
<input type="hidden" asp-for="Student.Guid" />
<div class="mb-2">
操作
</div>
<div class="mb-2">
<input type="submit" value="通过" class="btn btn-info" style="margin:5px" asp-page-handler="Accept" />
</div>
<div class="mb-2">
<input type="submit" value="拒绝" class="btn btn-danger" style="margin:5px" asp-page-handler="Reject" />
</div>
<div class="mb-2">
给他打分
<input asp-for="score" class="form-control"/>
<input type="submit" value="打" class="btn btn-warning" style="margin:5px" asp-page-handler="Rank" />
</div>
</form>
<br />
<h4>
看看大家怎么说
</h4>
<table class="table">
<thead>
<tr>
<th> @Html.DisplayNameFor(model => model.CommentSample.Operator)</th>
<th> @Html.DisplayNameFor(model => model.CommentSample.Content)</th>
<th> @Html.DisplayNameFor(model => model.CommentSample.AddTime)</th>
</tr>
</thead>
<tbody>
@foreach (var cmt in Model.CurComments)
{
<tr>
@{
var usr = Model.Context.Users.Find(cmt.Operator);
<td>
@Html.DisplayFor(model => usr.Name)
</td>
<td>
@Html.DisplayFor(model => cmt.Content)
</td>
<td>
@Html.DisplayFor(model => cmt.AddTime)
</td>
}
</tr>
}
</tbody>
</table>
<h4>
添加评论
</h4>
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<textarea asp-for="NewComment" class="form-control" rows="5"></textarea>
<span asp-validation-for="NewComment" class="text-danger"></span>
</div>
<div class="form-group">
<input type="hidden" asp-for="Student.Guid" />
<input type="submit" value="→" class="btn btn-primary btn-sm" />
</div>
</form>
<br />
<h4>
场次
</h4>
<h4>
最终场次 : @{
if (Model.Interviewtime == null)
{
<div class="text-danger">尚未确定活动场次</div>
<hr />
}
else
{
<div class="text-info">
@{
var val = Model.Interviewtime.Place + " " + Model.Interviewtime.Day.ToString("MM月dd日") + " " + Model.Interviewtime.BeginTime.ToString("hh:mm");
@Html.DisplayFor(model => val)
}
</div>
}
}
</h4>
<table class="table">
<thead>
<tr >
<th>地点</th>
<th>日期</th>
<th>时间</th>
<th>总容量</th>
<th>剩余人数</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.Student.Timelist.Count; i++)
{
var it = Model.Student.Timelist[i];
var dt = Model.Context.Sessions.Find(it);
if (dt.Capacity > dt.Students.Count || dt.Students.Contains(Model.Student.Guid))
{
<tr>
<td>
@{
@Html.DisplayFor(model => dt.Place)
}
</td>
<td>
@{
var s1 = dt.Day.ToString("MM-dd");
@Html.DisplayFor(model => s1)
}
</td>
<td>
@{
var s2 = dt.BeginTime.ToString("hh-mm");
@Html.DisplayFor(model => s2)
}
</td>
<td>
@{
var s4 = dt.Capacity.ToString();
@Html.DisplayFor(model => s4)
}
</td>
<td>
@{
var num = (dt.Capacity - dt.Students.Count()).ToString();
@Html.DisplayFor(model => num)
}
</td>
<td>
<form method="post" class="form-inline">
<input type="hidden" asp-for="Student.Guid" />
<a asp-page="/Sessions/Edit" asp-route-id="@it.ToString()" class="btn btn-sm btn-primary">场次详情</a>
<input type="submit" asp-page-handler="Select" asp-route-stu="@Model.Student.Guid" asp-route-time="@it.ToString()" class="btn btn-sm btn-warning" value="选择这个" />
</form>
</td>
</tr>
}
}
</tbody>
</table>
<h4>
Ta的短信
</h4>
<form method="post">
<input type="hidden" asp-for="Student.Guid" />
<input type="submit" value="拉取5天内的回复短信" class="btn btn-primary" asp-page-handler="Pull" />
<input type="submit" value="发送报名确认短信" class="btn btn-primary" asp-page-handler="Sign" />
<input type="submit" value="发送活动场次确认短信" class="btn btn-primary" asp-page-handler="Time" />
<input type="submit" value="发送活动结果短信" class="btn btn-primary" asp-page-handler="Result" />
</form>
<table class="table">
<thead>
<tr>
<th>
发送时间
</th>
<th>
短信类型
</th>
<th>
短信内容
</th>
</tr>
</thead>
<tbody>
@foreach (var msg in Model.Messages)
{
<tr>
<td>
@{
var str = msg.SendTime.ToString("MM-dd hh:mm:ss");
@Html.DisplayFor(it => str)
}
</td>
<td>
@{
var s = Enum.GetName(typeof(_2021_backend.Models.SMSType), msg.Type);
@Html.DisplayFor(it=> s)
}
</td>
<td>
@{
string s2 = "";
foreach (var e in msg.Data)
{
if (!string.IsNullOrEmpty(e)) s2 += " " + e;
}
@Html.DisplayFor(it => s2)
}
</td>
</tr>
}
</tbody>
</table>
<h4>
Ta的提交记录
</h4>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Stuid)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Sex)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Yard)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Grade)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Major)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Email)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Tel)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.Address)
</th>
<th>
@Html.DisplayNameFor(model => model.SubmissionSample.SubmitTime)
</th>
<th>
Operation
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Student.Submissions)
{
var sub = Model.Context.Submissions.Find(item);
<tr>
<td>
@Html.DisplayFor(modelItem => sub.Name)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Stuid)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Sex)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Yard)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Grade)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Major)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Email)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Tel)
</td>
<td>
@Html.DisplayFor(modelItem => sub.Address)
</td>
<td>
@Html.DisplayFor(modelItem => sub.SubmitTime)
</td>
<td>
<a asp-page="/Submissions/Edit" asp-route-strid="@sub.Guid">Edit</a> |
<a asp-page="/Submissions/Details" asp-route-strid="@sub.Guid">Details</a>
</td>
</tr>
}
</tbody>
</table>
<div>
<a asp-page="./Edit" asp-route-idstr="@Model.Student.Guid">编辑信息</a> |
<a asp-page="./Index">返回列表</a>
</div>
+204
View File
@@ -0,0 +1,204 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace _2021_backend.Pages.Students
{
public class DetailsModel : PageModel
{
public _2021_backend.Data.BackendContext Context;
public DetailsModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Student Student { get; set; }
[BindProperty]
public int score { get; set; }
public List<Session> Sessions { get; set; }
public List<Submission> Submissions { get; set; }
public List<Comment> CurComments { get; set; }
public Session Interviewtime { get; set; }
public Comment CommentSample { get; set; }
public Submission SubmissionSample { get; set; }
[Display(Name = "评论内容")]
[BindProperty]
[Required(ErrorMessage = "该项不能为空")]
public string NewComment { get; set; }
public List<SMS> Messages { get; set; }
public IActionResult Construct(string? idstr)
{
if (idstr == null)
{
return NotFound();
}
Guid id = Guid.Parse(idstr);
Student = Context.Students.Find(id);
if (Student == null)
{
Console.WriteLine("Student not found.");
return NotFound();
}
Sessions = new List<Session>();
Submissions = new List<Submission>();
Interviewtime = Context.Sessions.Find(Student.InterviewTime);
foreach (var it in Student.Timelist)
{
var tm = Context.Sessions.Find(it);
if (tm == null) Console.WriteLine("null encountered in timelist!");
Sessions.Add(tm);
}
Messages = Context.SMS.Where(it => it.Host == id).ToList();
CurComments = Context.Comments.Where(cmt => cmt.Student == Student.Guid).ToList();
Sessions.Sort((Session a, Session b) => {
var x = a.Day.CompareTo(b.Day);
var y = a.BeginTime.CompareTo(b.BeginTime);
var z = a.Place.CompareTo(b.Place);
return (x != 0 ? x : y != 0 ? y : z != 0 ? z : 0);
});
Console.WriteLine("Page construction finished.");
return Page();
}
public async Task<IActionResult> OnGetAsync(string? idstr)
{
Console.WriteLine("getting student " + idstr);
return Construct(idstr);
}
public async Task<IActionResult> OnPostAsync()
{
if (!string.IsNullOrWhiteSpace(NewComment))
{
var cmt = new Comment();
cmt.Student = Student.Guid;
cmt.Content = NewComment;
cmt.Operator = Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value);
var stu = Context.Students.Find(Student.Guid);
stu.Comments.Add(cmt.Guid);
Context.Comments.Add(cmt);
Context.SaveChanges();
}
Construct(Student.Guid.ToString());
return RedirectToPage(new { idstr = Student.Guid.ToString() });
}
public async Task<IActionResult> OnPostAcceptAsync()
{
Student = Context.Students.Find(Student.Guid);
Student.Status = status.通过;
Context.SaveChanges();
CurComments = Context.Comments.Where(cmt => cmt.Student == Student.Guid).ToList();
Messages = Context.SMS.Where(it => it.Host == Student.Guid).ToList();
Construct(Student.Guid.ToString());
return RedirectToPage(new { idstr = Student.Guid.ToString() });
}
public async Task<IActionResult> OnPostRejectAsync()
{
Student = Context.Students.Find(Student.Guid);
Student.Status = status.不通过;
Context.SaveChanges();
Student.Score = 0;
CurComments = Context.Comments.Where(cmt => cmt.Student == Student.Guid).ToList();
Messages = Context.SMS.Where(it => it.Host == Student.Guid).ToList();
Construct(Student.Guid.ToString());
return RedirectToPage(new { idstr = Student.Guid.ToString() });
}
public async Task<IActionResult> OnPostSelectAsync(Guid stu, Guid time)
{
var st = Context.Students.Find(stu);
if (st != null)
{
if (Context.Sessions.Any(it => it.Guid == time))
{
var tm = Context.Sessions.Find(time);
if (tm.Students.Count < tm.Capacity)
{
if (st.InterviewTime != Guid.Empty)
{
var tmold = Context.Sessions.Find(st.InterviewTime);
if (tmold != null)
{
tmold.Students.RemoveAll(it => it == st.Guid);
Context.SaveChanges();
}
}
tm.Students.Add(stu);
st.InterviewTime = time;
if (st.Status != status.不通过 && st.Status != status.通过) st.Status = status.已选时间;
Context.SaveChanges();
}
}
}
return Construct(Student.Guid.ToString());
}
public async Task<IActionResult> OnPostPullAsync()
{
await Utils.TencentSMS.Pull(Context, Context.Students.Find(Student.Guid), true);
return Construct(Student.Guid.ToString());
}
public async Task<IActionResult> OnPostRankAsync()
{
var s = Context.Students.Find(Student.Guid);
s.Score = score;
s.Status = status.已评分;
Context.SaveChanges();
return Construct(Student.Guid.ToString());
}
public async Task<IActionResult> OnPostResultAsync()
{
var stu = Context.Students.Find(Student.Guid);
if (stu.Status == status.通过)
await Utils.TencentSMS.Send(Context, SMSType.Accept, stu, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
else if (stu.Status == status.不通过)
await Utils.TencentSMS.Send(Context, SMSType.Reject, stu, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
return Construct(Student.Guid.ToString());
}
public async Task<IActionResult> OnPostSignAsync()
{
var stu = Context.Students.Find(Student.Guid);
await Utils.TencentSMS.Send(Context, SMSType.Signed, stu, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
return Construct(Student.Guid.ToString());
}
public async Task<IActionResult> OnPostSelectTimeAsync()
{
var stu = Context.Students.Find(Student.Guid);
await Utils.TencentSMS.Send(Context, SMSType.TimeSelect, stu, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
stu.Status = status.需调整时间;
return Construct(Student.Guid.ToString());
}
public async Task<IActionResult> OnPostTimeAsync()
{
var stu = Context.Students.Find(Student.Guid);
await Utils.TencentSMS.Send(Context, SMSType.TimeSet, stu, Context.Users.Find(Guid.Parse(User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Sid).Value)).Name);
stu.Status = status.已确认时间;
Context.SaveChanges();
return Construct(Student.Guid.ToString());
}
}
}
+80
View File
@@ -0,0 +1,80 @@
@page
@model _2021_backend.Pages.Students.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>编辑详细信息</h1>
<h4>学生</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Student.Guid" />
<div class="form-group">
<label asp-for="Student.Name" class="control-label"></label>
<input asp-for="Student.Name" class="form-control" />
<span asp-validation-for="Student.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Stuid" class="control-label"></label>
<input asp-for="Student.Stuid" class="form-control" />
<span asp-validation-for="Student.Stuid" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Sex" class="control-label"></label>
<select asp-for="Student.Sex" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.sex))"></select>
<span asp-validation-for="Student.Sex" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Yard" class="control-label"></label>
<select asp-for="Student.Yard" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.yard))"></select>
<span asp-validation-for="Student.Yard" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Grade" class="control-label"></label>
<select asp-for="Student.Grade" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.grade))"></select>
<span asp-validation-for="Student.Grade" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Major" class="control-label"></label>
<input asp-for="Student.Major" class="form-control" />
<span asp-validation-for="Student.Major" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Email" class="control-label"></label>
<input asp-for="Student.Email" class="form-control" />
<span asp-validation-for="Student.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Tel" class="control-label"></label>
<input asp-for="Student.Tel" class="form-control" />
<span asp-validation-for="Student.Tel" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.RegisterTime" class="control-label"></label>
<input asp-for="Student.RegisterTime" class="form-control" />
<span asp-validation-for="Student.RegisterTime" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Student.Status" class="control-label"></label>
<select asp-for="Student.Status" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.status))"></select>
<span asp-validation-for="Student.Status" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">返回列表</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+61
View File
@@ -0,0 +1,61 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Students
{
public class EditModel : PageModel
{
public readonly _2021_backend.Data.BackendContext Context;
public EditModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Student Student { get; set; }
public async Task<IActionResult> OnGetAsync(string? idstr)
{
if (idstr == null)
{
return NotFound();
}
Guid id = Guid.Parse(idstr);
Student = await Context.Students.AsNoTracking().FirstOrDefaultAsync(m => m.Guid == id);
if (Student == null)
{
return NotFound();
}
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
var stu = Context.Students.Find(Student.Guid);
stu.Status = Student.Status;
stu.Email = Student.Email;
stu.Name = Student.Name;
stu.Stuid = Student.Stuid;
stu.Tel = Student.Tel;
stu.Grade = Student.Grade;
stu.Sex = Student.Sex;
stu.Yard = Student.Yard;
Context.SaveChanges();
return RedirectToPage("./Index");
}
private bool StudentExists(Guid id)
{
return Context.Students.Any(e => e.Guid == id);
}
}
}
+155
View File
@@ -0,0 +1,155 @@
@page
@model _2021_backend.Pages.Students.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>报了名的xpy们</h1>
<p>
<a asp-page="Create">手动添加一个</a>
</p>
<h5 class="text-red">
<strong>@Html.DisplayFor(model => Model.errmsg)</strong>
</h5>
<form class="form-inline m-2" method="post">
<div class="form-group mx-sm-0 m-2">
<input type="text" class="form-control" id="searchString" placeholder="输入部分学号或姓名" asp-for="SearchString" name="SearchString">
</div>
<div class="form-group mx-sm-0 m-2">
<input type="text" class="form-control" id="SearchTel" placeholder="电话号码" asp-for="SearchTel" name="SearchTel">
</div>
<div class="form-group mx-sm-0 m-2">
<input type="text" class="form-control" id="SearchQQ" placeholder="QQ号码" asp-for="SearchQQ" name="SearchQQ">
</div>
<div class="m-2">
年级
<select asp-for="Grade" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.grade))" class="form-control">
</select>
</div>
<div class="m-2">
状态
<select asp-for="StatusSel" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.status))" class="form-control">
</select>
</div>
<button type="submit" class="btn btn-outline-primary m-2">搜索</button>
</form>
<table class="table">
<thead>
<tr>
<th>
Index
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Stuid)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Sex)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Yard)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Grade)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Major)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Status)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Exp)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].Score)
</th>
<th>
@Html.DisplayNameFor(model => model.Student[0].RegisterTime)
</th>
<th></th>
</tr>
</thead>
<tbody>
@{
var n = 0;
@foreach (var item in Model.Student)
{
n++;
<tr class="@{
switch(item.Status){
case _2021_backend.Models.status.不通过:
@("table-danger")
break;
case _2021_backend.Models.status.通过:
@("table-success")
break;
case _2021_backend.Models.status.刚报名:
@("")
break;
case _2021_backend.Models.status.已评分:
@("table-primary")
break;
}
}">
<td>
@{
var s = (Model.PageId * IndexModel.PageSize + n).ToString();
@Html.DisplayFor(it => s)
}
</td>
<td>
<a asp-page="./Details" asp-route-idstr="@item.Guid.ToString()"> @Html.DisplayFor(modelItem => item.Name)</a>
</td>
<td>
<a asp-page="./Details" asp-route-idstr="@item.Guid.ToString()"> @Html.DisplayFor(modelItem => item.Stuid)</a>
</td>
<td>
@Html.DisplayFor(modelItem => item.Sex)
</td>
<td>
@Html.DisplayFor(modelItem => item.Yard)
</td>
<td>
@Html.DisplayFor(modelItem => item.Grade)
</td>
<td>
@Html.DisplayFor(modelItem => item.Major)
</td>
<td>
@Html.DisplayFor(modelItem => item.Status)
</td>
<td>
@Html.DisplayFor(modelItem => item.Exp)
</td>
<td>
@Html.DisplayFor(modelItem => item.Score)
</td>
<th>
@Html.DisplayFor(modelItem => item.RegisterTime)
</th>
<td>
<a asp-page="./Edit" asp-route-idstr="@item.Guid.ToString()">编辑资料</a> |
<a asp-page="./Details" asp-route-idstr="@item.Guid.ToString()">审阅</a> |
<a asp-page="./Delete" asp-route-idstr="@item.Guid.ToString()">删除</a>
</td>
</tr>
}
}
</tbody>
</table>
<nav>
<ul class="pagination">
<li class="page-item @(Model.PageId==0 ? "disabled" : "")"><a class="page-link" asp-route-pageId="@(Model.PageId-1) " asp-route-Grade="@Model.Grade" asp-route-SearchString="@Model.SearchString" asp-route-StatusSel="@Model.StatusSel" asp-route-SearchQQ="@Model.SearchQQ">Prev</a></li>
@for (int i = 0; i < Model.PageCount; i++)
{
<li class="page-item @(Model.PageId==i ? "active" : "")"><a class="page-link" asp-route-pageId="@i" asp-route-Grade="@Model.Grade" asp-route-SearchString="@Model.SearchString" asp-route-StatusSel="@Model.StatusSel" asp-route-SearchQQ="@Model.SearchQQ">@i</a></li>
}
<li class="page-item @(Model.PageId>=Model.PageCount -1? "disabled" : "")"><a class="page-link" asp-route-pageId="@(Model.PageId+1)" asp-route-Grade="@Model.Grade" asp-route-SearchString="@Model.SearchString" asp-route-StatusSel="@Model.StatusSel" asp-route-SearchQQ="@Model.SearchQQ">Next</a></li>
</ul>
</nav>
+97
View File
@@ -0,0 +1,97 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using System;
using System.IO.Compression;
using System.Collections.Generic;
using System.Linq;
using _2021_backend.Utils;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Students
{
public class IndexModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public static int PageSize { get; set; }
public int PageCount { get; set; }
public int PageId { get; set; }
public string errmsg { get; set; }
[BindProperty(SupportsGet = true)]
public string SearchString { get; set; }
[BindProperty(SupportsGet = true)]
public grade Grade { get; set; }
[BindProperty(SupportsGet = true)]
public string SearchQQ { get; set; }
[BindProperty(SupportsGet = true)]
public string SearchTel { get; set; }
[BindProperty(SupportsGet = true)]
public status StatusSel { get; set; } = status.暂缺;
public IndexModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public List<Student> Student { get; set; }
public IActionResult Construct(int pageId, string errInfo)
{
PageSize = 30;
if (string.IsNullOrEmpty(errInfo))
{
errmsg = "";
}
else
{
errmsg = errInfo;
}
if (pageId == null) pageId = 0;
IQueryable<Student> q;
if (!string.IsNullOrEmpty(SearchString))
{
q = Context.Students.Where(s => (s.Name.Contains(SearchString) || s.Stuid.Contains(SearchString)));
}
else
{
q = Context.Students;
}
if (Grade != grade.暂缺) q = q.Where(it => it.Grade == Grade);
if (StatusSel != status.暂缺) q = q.Where(it => it.Status == StatusSel);
if (!String.IsNullOrEmpty(SearchTel)) q = q.Where(it => it.Tel.Contains(SearchTel));
if (!String.IsNullOrEmpty(SearchQQ)) q = q.Where(it => it.Email.Contains(SearchQQ));
Student = q.ToList();
Student.Sort((Student a, Student b) =>
{
return -a.RegisterTime.CompareTo(b.RegisterTime);
});
int cnt = Student.Count;
PageCount = (int)Math.Ceiling((double)cnt / (double)PageSize);
if (pageId >= PageCount) pageId = PageCount - 1;
if (pageId < 0) pageId = 0;
PageId = (int)pageId;
int count = (PageId + 1) * PageSize > cnt ? (cnt - PageId * PageSize) : PageSize;
Student = Student.GetRange(PageId * PageSize, count);
return Page();
}
public async Task<IActionResult> OnGetAsync(int? pageId, string errInfo)
{
if (pageId == null) pageId = 0;
return Construct((int)pageId, errInfo);
}
public async Task<IActionResult> OnPostAsync(int? pageId, string errInfo)
{
if (pageId == null) pageId = 0;
return Construct((int)pageId, errInfo);
}
}
}
+74
View File
@@ -0,0 +1,74 @@
@page
@model _2021_backend.Pages.Submissions.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>创建</h1>
<h4>提交记录</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Submission.Name" class="control-label"></label>
<input asp-for="Submission.Name" class="form-control" />
<span asp-validation-for="Submission.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Stuid" class="control-label"></label>
<input asp-for="Submission.Stuid" class="form-control" />
<span asp-validation-for="Submission.Stuid" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Sex" class="control-label"></label>
<select asp-for="Submission.Sex" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.sex))"></select>
<span asp-validation-for="Submission.Sex" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Yard" class="control-label"></label>
<select asp-for="Submission.Yard" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.yard))"></select>
<span asp-validation-for="Submission.Yard" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Grade" class="control-label"></label>
<select asp-for="Submission.Grade" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.grade))"></select>
<span asp-validation-for="Submission.Grade" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Major" class="control-label"></label>
<input asp-for="Submission.Major" class="form-control" />
<span asp-validation-for="Submission.Major" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Email" class="control-label"></label>
<input asp-for="Submission.Email" class="form-control" />
<span asp-validation-for="Submission.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Tel" class="control-label"></label>
<input asp-for="Submission.Tel" class="form-control" />
<span asp-validation-for="Submission.Tel" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Address" class="control-label"></label>
<input asp-for="Submission.Address" class="form-control" />
<span asp-validation-for="Submission.Address" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">返回列表</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+57
View File
@@ -0,0 +1,57 @@
using _2021_backend.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.Linq;
using System.Threading.Tasks;
namespace _2021_backend.Pages.Submissions
{
public class CreateModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public CreateModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public IActionResult OnGet()
{
Submission = new Submission();
return Page();
}
[BindProperty]
public Submission Submission { get; set; }
// To protect from overposting attacks, see https://aka.ms/RazorPagesCRUD
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var q = Context.Students.Where(stu => (stu.Name == Submission.Name || stu.Tel == Submission.Tel || stu.Stuid == Submission.Stuid));
Student stu;
if (q.Count() == 0)
{
stu = Student.create(Submission);
stu.Status = status.刚报名;
var q2 = from e in Context.Sessions select e.Guid;
var lst = q2.ToList();
stu.Timelist = lst;
Context.Students.Add(stu);
}
else
{
stu = q.FirstOrDefault();
stu.Update(Submission);
}
Submission.Host = stu.Guid;
Context.Submissions.Add(Submission);
Context.SaveChanges();
return RedirectToPage("./Index");
}
}
}
+76
View File
@@ -0,0 +1,76 @@
@page
@model _2021_backend.Pages.Submissions.DeleteModel
@{
ViewData["Title"] = "Delete";
}
<h1>删除</h1>
<h3>你确定要删除该项目吗?</h3>
<div>
<h4>提交记录</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Stuid)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Stuid)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Sex)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Sex)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Grade)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Grade)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Major)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Major)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Email)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Email)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Tel)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Tel)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Address)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Address)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.SubmitTime)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.SubmitTime)
</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="Submission.Guid" />
<input type="submit" value="删除" class="btn btn-danger" asp-route-id="@Model.Submission.Guid.ToString()"/> |
<a asp-page="./Index">返回列表</a>
</form>
</div>
+63
View File
@@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Submissions
{
public class DeleteModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public DeleteModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Submission Submission { get; set; }
public async Task<IActionResult> OnGetAsync(string? strid)
{
Guid id = Guid.Parse(strid);
if (id == null)
{
return NotFound();
}
Submission = Context.Submissions.FirstOrDefault(m => m.Guid == id);
if (Submission == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(Guid? id)
{
if (id == null)
{
return NotFound();
}
Submission = Context.Submissions.Find(id);
if (Submission != null)
{
var stu = Context.Students.Find(Submission.Host);
if (stu != null)
{
stu.Submissions.Remove(Submission.Guid);
}
Context.Submissions.Remove(Submission);
Context.SaveChanges();
}
return RedirectToPage("./Index");
}
}
}
+79
View File
@@ -0,0 +1,79 @@
@page
@model _2021_backend.Pages.Submissions.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>Submission</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Stuid)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Stuid)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Sex)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Sex)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Yard)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Yard)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Grade)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Grade)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Major)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Major)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Email)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Email)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Tel)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Tel)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.Address)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.Address)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.Submission.SubmitTime)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.Submission.SubmitTime)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="@Model.Submission.Guid">Edit</a> |
<a asp-page="./Index">返回列表</a>
</div>
+41
View File
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Submissions
{
public class DetailsModel : PageModel
{
private readonly _2021_backend.Data.BackendContext _context;
public DetailsModel(_2021_backend.Data.BackendContext context)
{
_context = context;
}
public Submission Submission { get; set; }
public async Task<IActionResult> OnGetAsync(string? strid)
{
if (strid == null)
{
return NotFound();
}
Guid id = Guid.Parse(strid);
Submission = await _context.Submissions.FirstOrDefaultAsync(m => m.Guid == id);
if (Submission == null)
{
return NotFound();
}
return Page();
}
}
}
+75
View File
@@ -0,0 +1,75 @@
@page
@model _2021_backend.Pages.Submissions.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>编辑详细信息</h1>
<h4>提交记录</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Submission.Guid" />
<div class="form-group">
<label asp-for="Submission.Name" class="control-label"></label>
<input asp-for="Submission.Name" class="form-control" />
<span asp-validation-for="Submission.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Stuid" class="control-label"></label>
<input asp-for="Submission.Stuid" class="form-control" />
<span asp-validation-for="Submission.Stuid" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Sex" class="control-label"></label>
<select asp-for="Submission.Sex" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.sex))"></select>
<span asp-validation-for="Submission.Sex" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Grade" class="control-label"></label>
<select asp-for="Submission.Grade" class="form-control" asp-items="@Html.GetEnumSelectList(typeof(_2021_backend.Models.grade))"></select>
<span asp-validation-for="Submission.Grade" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Major" class="control-label"></label>
<input asp-for="Submission.Major" class="form-control" />
<span asp-validation-for="Submission.Major" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Email" class="control-label"></label>
<input asp-for="Submission.Email" class="form-control" />
<span asp-validation-for="Submission.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Tel" class="control-label"></label>
<input asp-for="Submission.Tel" class="form-control" />
<span asp-validation-for="Submission.Tel" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.Address" class="control-label"></label>
<input asp-for="Submission.Address" class="form-control" />
<span asp-validation-for="Submission.Address" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Submission.SubmitTime" class="control-label"></label>
<input asp-for="Submission.SubmitTime" class="form-control" />
<span asp-validation-for="Submission.SubmitTime" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">返回列表</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+78
View File
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Submissions
{
public class EditModel : PageModel
{
public readonly _2021_backend.Data.BackendContext Context;
public EditModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
[BindProperty]
public Submission Submission { get; set; }
public async Task<IActionResult> OnGetAsync(string? strid)
{
Guid id = Guid.Parse(strid);
if (id == null)
{
return NotFound();
}
Submission = await Context.Submissions.FirstOrDefaultAsync(m => m.Guid == id);
if (Submission == null)
{
return NotFound();
}
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
Context.Attach(Submission).State = EntityState.Modified;
try
{
await Context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!SubmissionExists(Submission.Guid))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool SubmissionExists(Guid id)
{
return Context.Submissions.Any(e => e.Guid == id);
}
}
}
+95
View File
@@ -0,0 +1,95 @@
@page
@model _2021_backend.Pages.Submissions.IndexModel
@{
ViewData["Title"] = "Index";
}
<h1>全部提交记录</h1>
<p>
<a asp-page="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Stuid)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Sex)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Grade)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Major)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Email)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Tel)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].Address)
</th>
<th>
@Html.DisplayNameFor(model => model.Submission[0].SubmitTime)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Submission)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Stuid)
</td>
<td>
@Html.DisplayFor(modelItem => item.Sex)
</td>
<td>
@Html.DisplayFor(modelItem => item.Grade)
</td>
<td>
@Html.DisplayFor(modelItem => item.Major)
</td>
<td>
@Html.DisplayFor(modelItem => item.Email)
</td>
<td>
@Html.DisplayFor(modelItem => item.Tel)
</td>
<td>
@Html.DisplayFor(modelItem => item.Address)
</td>
<td>
@Html.DisplayFor(modelItem => item.SubmitTime)
</td>
<td>
<a asp-page="./Edit" asp-route-strid="@item.Guid.ToString()">编辑</a> |
<a asp-page="./Details" asp-route-strid="@item.Guid.ToString()">详细信息</a> |
<a asp-page="./Delete" asp-route-strid="@item.Guid.ToString()">删除</a>
</td>
</tr>
}
</tbody>
</table>
<nav>
<ul class="pagination">
<li class="page-item @(Model.PageId==0 ? "disabled" : "")"><a class="page-link" asp-route-pageId="@(Model.PageId-1) ">Prev</a></li>
@for (int i = 0; i < Model.PageCount; i++)
{
<li class="page-item @(Model.PageId==i ? "active" : "")"><a class="page-link" asp-route-pageId="@i">@i</a></li>
}
<li class="page-item @(Model.PageId>=Model.PageCount -1? "disabled" : "")"><a class="page-link" asp-route-pageId="@(Model.PageId+1)" >Next</a></li>
</ul>
</nav>
+42
View File
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Submissions
{
public class IndexModel : PageModel
{
private readonly _2021_backend.Data.BackendContext Context;
public static int PageSize = 30;
public int PageCount { get; set; }
public int PageId { get; set; }
public IndexModel(_2021_backend.Data.BackendContext context)
{
Context = context;
}
public List<Submission> Submission { get;set; }
public async Task OnGetAsync(int pageId)
{
var q = from e in Context.Submissions orderby e.SubmitTime select e;
Submission = await q.ToListAsync();
Submission.Sort((a,b)=>b.SubmitTime.CompareTo(a.SubmitTime));
int cnt = Submission.Count;
PageCount = (int)Math.Ceiling((double)cnt / (double)PageSize);
if (pageId >= PageCount) pageId = PageCount - 1;
if (pageId < 0) pageId = 0;
PageId = (int)pageId;
int count = (PageId + 1) * PageSize > cnt ? (cnt - PageId * PageSize) : PageSize;
Submission = Submission.GetRange(PageId * PageSize, count);
}
}
}
+49
View File
@@ -0,0 +1,49 @@
@page
@model _2021_backend.Pages.Users.CreateModel
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="NowUser.stuID" class="control-label"></label>
<input asp-for="NowUser.stuID" class="form-control" />
<span asp-validation-for="NowUser.stuID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="NowUser.Name" class="control-label"></label>
<input asp-for="NowUser.Name" class="form-control" />
<span asp-validation-for="NowUser.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="NowUser.Secret" class="control-label"></label>
<input asp-for="NowUser.Secret" class="form-control" />
<span asp-validation-for="NowUser.Secret" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="NowUser.isManager" /> @Html.DisplayNameFor(model => model.NowUser.isManager)
</label>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+58
View File
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using _2021_backend.Data;
using _2021_backend.Models;
using Microsoft.EntityFrameworkCore;
namespace _2021_backend.Pages.Users
{
public class CreateModel : PageModel
{
private readonly _2021_backend.Data.BackendContext _context;
public IList<Submission> Record { get; set; }
public int PageCount { get; set; }
public int PageId { get; set; }
[BindProperty(SupportsGet =true,Name ="search")]
public string SearchString { get; set; }
public CreateModel(_2021_backend.Data.BackendContext context)
{
_context = context;
}
public IActionResult OnGet()
{
return Page();
}
[BindProperty]
public User NowUser { get; set; }
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (await _context.Users.AsNoTracking().Where(u => u.stuID == NowUser.stuID).FirstOrDefaultAsync() != null)
{
}
else
{
NowUser.Secret = Utils.EvaCryptoHelper.Password2Secret(NowUser.Secret);
_context.Users.Add(NowUser);
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
}
}
+41
View File
@@ -0,0 +1,41 @@
@page
@model _2021_backend.Pages.Users.DeleteModel
@{
ViewData["Title"] = "Delete";
}
<h1>Delete</h1>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>User</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.stuID)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.User.stuID)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.User.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.isManager)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.User.isManager)
</dd>
</dl>
<form method="post">
<input type="hidden" asp-for="User.Guid" />
<input type="submit" value="Delete" class="btn btn-danger" /> |
<a asp-page="./Index">Back to List</a>
</form>
</div>
+61
View File
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Users
{
public class DeleteModel : PageModel
{
private readonly _2021_backend.Data.BackendContext _context;
public DeleteModel(_2021_backend.Data.BackendContext context)
{
_context = context;
}
[BindProperty]
public new User User { get; set; }
public async Task<IActionResult> OnGetAsync(string id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
User = _context.Users.Find(guid);
if (User == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
User = _context.Users.Find(id);
if (User != null)
{
_context.Users.Remove(User);
await _context.SaveChangesAsync();
}
return RedirectToPage("./Index");
}
}
}
+43
View File
@@ -0,0 +1,43 @@
@page
@model _2021_backend.Pages.Users.DetailsModel
@{
ViewData["Title"] = "Details";
}
<h1>Details</h1>
<div>
<h4>User</h4>
<hr />
<dl class="row">
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.stuID)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.User.stuID)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.Name)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.User.Name)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.Secret)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model=>model.SECRET)
</dd>
<dt class="col-sm-2">
@Html.DisplayNameFor(model => model.User.isManager)
</dt>
<dd class="col-sm-10">
@Html.DisplayFor(model => model.User.isManager)
</dd>
</dl>
</div>
<div>
<a asp-page="./Edit" asp-route-id="@Model.User.Guid">Edit</a> |
<a asp-page="./Index">Back to List</a>
</div>
+41
View File
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Users
{
public class DetailsModel : PageModel
{
private readonly _2021_backend.Data.BackendContext _context;
public DetailsModel(_2021_backend.Data.BackendContext context)
{
_context = context;
}
public string SECRET = "EVa N13 @!@";
public new User User { get; set; }
public async Task<IActionResult> OnGetAsync(string id)
{
Guid guid = Guid.Parse(id);
if (id == null)
{
return NotFound();
}
User = _context.Users.Find(guid);
if (User == null)
{
return NotFound();
}
return Page();
}
}
}
+50
View File
@@ -0,0 +1,50 @@
@page
@model _2021_backend.Pages.Users.EditModel
@{
ViewData["Title"] = "Edit";
}
<h1>Edit</h1>
<h4>User</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="USER.Guid" />
<div class="form-group">
<label asp-for="USER.stuID" class="control-label"></label>
<input asp-for="USER.stuID" class="form-control" />
<span asp-validation-for="USER.stuID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="USER.Name" class="control-label"></label>
<input asp-for="USER.Name" class="form-control" />
<span asp-validation-for="USER.Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="USER.Secret" class="control-label"></label>
<input asp-for="USER.Secret" class="form-control" />
<span asp-validation-for="USER.Secret" class="text-danger"></span>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" asp-for="USER.isManager" /> @Html.DisplayNameFor(model => model.USER.isManager)
</label>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="./Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
+101
View File
@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Users
{
public class EditModel : PageModel
{
private readonly _2021_backend.Data.BackendContext _context;
public EditModel(_2021_backend.Data.BackendContext context)
{
_context = context;
}
[BindProperty]
public new User USER { get; set; }
private string _secret { get; set; }
public async Task<IActionResult> OnGetAsync(string? id)
{
if (id == null)
{
return NotFound();
}
Guid guid = Guid.Parse(id);
USER = _context.Users.Find(guid);
if (USER == null)
{
return NotFound();
}
_secret = USER.Secret;
USER.Secret = string.Empty;
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
if (await _context.Users.AsNoTracking().Where(u => u.stuID == USER.stuID).CountAsync() > 0
&& (await _context.Users.AsNoTracking().Where(u => u.stuID == USER.stuID).FirstOrDefaultAsync()).Guid != USER.Guid
)
return new ConflictResult();
if (USER.Secret == null || USER.Secret == String.Empty)
{
var user = await _context.Users.AsNoTracking().Where(u => u.Guid == USER.Guid).FirstOrDefaultAsync();
user.Name = USER.Name;
user.stuID = USER.stuID;
user.isManager = USER.isManager;
_context.Attach(user).State = EntityState.Modified;
}
else
{
var user = await _context.Users.AsNoTracking().Where(u => u.Guid == USER.Guid).FirstOrDefaultAsync();
user.Name = USER.Name;
user.stuID = USER.stuID;
user.isManager = USER.isManager;
user.Secret = Utils.EvaCryptoHelper.Password2Secret(USER.Secret);
_context.Attach(user).State = EntityState.Modified;
}
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!UserExists(USER.Guid))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("./Index");
}
private bool UserExists(Guid id)
{
return _context.Users.Any(e => e.Guid == id);
}
}
}
+50
View File
@@ -0,0 +1,50 @@
@page
@model _2021_backend.Pages.Users.IndexModel
@{
ViewData["Title"] = "Index";
}
<h4>用户管理</h4>
<p>
<a asp-page="Create">新加一个好兄弟</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.User[0].stuID)
</th>
<th>
@Html.DisplayNameFor(model => model.User[0].Name)
</th>
<th>
@Html.DisplayNameFor(model => model.User[0].isManager)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.User) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.stuID)
</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.isManager)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.Guid">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.Guid">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.Guid">Delete</a>
</td>
</tr>
}
</tbody>
</table>
+29
View File
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using _2021_backend.Data;
using _2021_backend.Models;
namespace _2021_backend.Pages.Users
{
public class IndexModel : PageModel
{
private readonly _2021_backend.Data.BackendContext _context;
public IndexModel(_2021_backend.Data.BackendContext context)
{
_context = context;
}
public string SECRET = "EVa N13 @!@";
public new IList<User> User { get;set; }
public async Task OnGetAsync()
{
User = await _context.Users.ToListAsync();
}
}
}
+3
View File
@@ -0,0 +1,3 @@
@using _2021_backend
@namespace _2021_backend.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
+3
View File
@@ -0,0 +1,3 @@
@{
Layout = "_Layout";
}