refactor: 个人中心页面改变密码功能完成

This commit is contained in:
Argo Window10 2019-12-13 21:51:48 +08:00
parent f0fb88d86f
commit 5cd8fc1629
9 changed files with 182 additions and 81 deletions

View File

@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System;
using System.Linq.Expressions;
namespace Bootstrap.Admin.Components
{
/// <summary>
///
/// </summary>
public class EqualToValidator : ValidatorComponentBase
{
/// <summary>
///
/// </summary>
public EqualToValidator()
{
ErrorMessage = "你的输入不相同";
}
/// <summary>
///
/// </summary>
[Parameter]
public string Value { get; set; } = "";
/// <summary>
///
/// </summary>
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
/// <summary>
///
/// </summary>
/// <param name="propertyValue"></param>
/// <param name="context"></param>
/// <param name="results"></param>
public override void Validate(object? propertyValue, ValidationContext context, List<ValidationResult> results)
{
var val = propertyValue?.ToString() ?? "";
if (val != Value)
results.Add(new ValidationResult(ErrorMessage, new string[] { context.MemberName }));
}
}
}

View File

@ -13,7 +13,7 @@ namespace Bootstrap.Admin.Components
public class LgbEditFormBase : ComponentBase
{
/// <summary>
///
/// 获得/设置 Id 用于内部 Label-For
/// </summary>
[Parameter]
public string Id { get; set; } = "";

View File

@ -1,4 +1,5 @@
using System;
using Microsoft.AspNetCore.Components;
using System;
using System.Linq;
namespace Bootstrap.Admin.Components
@ -8,6 +9,18 @@ namespace Bootstrap.Admin.Components
/// </summary>
public class LgbInputTextBase : ValidateInputBase<string>
{
/// <summary>
///
/// </summary>
[Parameter]
public string ColumnClass { get; set; } = "col-sm-6";
/// <summary>
///
/// </summary>
[Parameter]
public string InputType { get; set; } = "text";
/// <summary>
///
/// </summary>

View File

@ -24,6 +24,9 @@ namespace Microsoft.AspNetCore.Builder
_displayNameCache.TryAdd((typeof(BootstrapDict), nameof(BootstrapDict.Name)), "字典名称");
_displayNameCache.TryAdd((typeof(BootstrapDict), nameof(BootstrapDict.Code)), "字典代码");
_displayNameCache.TryAdd((typeof(BootstrapDict), nameof(BootstrapDict.Define)), "字典类型");
_displayNameCache.TryAdd((typeof(BootstrapUser), nameof(BootstrapUser.UserName)), "登录名称");
_displayNameCache.TryAdd((typeof(BootstrapUser), nameof(BootstrapUser.DisplayName)), "显示名称");
return services;
}

View File

@ -7,24 +7,24 @@
<span>演示系统禁止更改管理员显示名称</span>
</div>
</ConditionComponent>
<form class="form-inline">
<LgbEditForm class="form-inline" Id="Profile" Model="User" OnValidSubmit="SaveDisplayName">
<div class="row">
<div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="userName">登录名称</label>
<input type="text" class="form-control ignore" value="@Model?.UserName" readonly />
</div>
<div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="DisplayName">显示名称</label>
<input type="text" class="form-control" @bind="@DisplayName" placeholder="不可为空20字以内" maxlength="20" data-valid="true" />
</div>
<LgbInputText ColumnClass="col-sm-6 col-md-auto" @bind-Value="@User.DisplayName" placeholder="不可为空16字以内" maxlength="16">
<RequiredValidator />
<StringLengthValidator Length="16" />
</LgbInputText>
</div>
</form>
<ConditionComponent Inverse="true">
<div class="modal-footer">
<button class="btn btn-secondary" type="button" @onclick="SaveDisplayName"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</ConditionComponent>
</LgbEditForm>
</div>
<ConditionComponent Inverse="true">
<div class="card-footer">
<button class="btn btn-secondary" type="button" onclick="$.submitForm(this)"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</ConditionComponent>
</div>
</AuthorizateComponent>
<div class="card" asp-auth="savePassword" asp-condition="!@Model?.External">
@ -35,30 +35,31 @@
<span>演示系统禁止更改管理员密码</span>
</div>
</ConditionComponent>
<form class="form-inline">
<LgbEditForm class="form-inline" Id="Profile" Model="Password" OnValidSubmit="SavePassword">
<div class="row">
<div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="currentPassword">原密码: </label>
<input type="password" class="form-control" autocomplete="off" placeholder="原密码" maxlength="16" data-valid="true" />
</div>
<LgbInputText InputType="password" ColumnClass="col-sm-6 col-md-auto" @bind-Value="@Password.Password" autocomplete="off" placeholder="原密码" maxlength="16">
<RequiredValidator />
<StringLengthValidator Length="16" />
</LgbInputText>
</div>
<div class="row">
<div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="newPassword">新密码: </label>
<input type="password" class="form-control" autocomplete="off" placeholder="新密码" maxlength="16" data-valid="true" />
</div>
<div class="form-group col-sm-6 col-md-auto">
<label class="control-label" for="confirmPassword">确认密码: </label>
<input type="password" class="form-control" autocomplete="off" placeholder="与新密码一致" maxlength="16" data-valid="true" />
</div>
<LgbInputText InputType="password" ColumnClass="col-sm-6 col-md-auto" @bind-Value="@Password.NewPassword" autocomplete="off" placeholder="新密码" maxlength="16">
<RequiredValidator />
<StringLengthValidator Length="16" />
</LgbInputText>
<LgbInputText InputType="password" ColumnClass="col-sm-6 col-md-auto" @bind-Value="@Password.ConfirmPassword" autocomplete="off" placeholder="与新密码一致" maxlength="16">
<RequiredValidator />
<StringLengthValidator Length="16" />
<EqualToValidator @bind-Value="@Password.NewPassword" />
</LgbInputText>
</div>
</form>
<ConditionComponent Inverse="true">
<div class="modal-footer">
<button class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</ConditionComponent>
</LgbEditForm>
</div>
<ConditionComponent Inverse="true">
<div class="card-footer">
<button class="btn btn-secondary" type="button" onclick="$.submitForm(this)"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</ConditionComponent>
</div>
<div class="card" asp-auth="saveApp">
<div class="card-header">默认应用</div>
@ -74,9 +75,9 @@
</div>
</div>
</div>
<div class="modal-footer">
<button id="btnSaveApp" data-method="app" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</div>
<div class="card-footer">
<button id="btnSaveApp" data-method="app" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</div>
<div class="card" asp-auth="saveTheme">
@ -97,9 +98,9 @@
</div>
</div>
</div>
<div class="modal-footer">
<button id="btnSaveCss" data-method="profileCss" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</div>
<div class="card-footer">
<button id="btnSaveCss" data-method="profileCss" class="btn btn-secondary" type="button"><i class="fa fa-save"></i><span>保存</span></button>
</div>
</div>
<div class="card" asp-auth="saveIcon">
@ -114,6 +115,9 @@
</div>
</div>
<Toast @ref="Toast"></Toast>
@code {
/// <summary>
///
@ -123,25 +127,41 @@
protected ProfilesModel? Model { get; set; }
protected string DisplayName { get; set; } = "";
protected bool IsDemo { get; set; } = false;
protected BootstrapUser User { get; set; } = new BootstrapUser();
protected PasswordModel Password { get; set; } = new PasswordModel();
protected override void OnInitialized()
{
Model = new ProfilesModel(RootLayout?.UserName);
DisplayName = Model.DisplayName;
IsDemo = Model?.IsDemo ?? false;
var user = DataAccess.UserHelper.RetrieveUserByUserName(Model?.UserName);
if (user != null) User = user;
}
private void SaveDisplayName()
private void SaveDisplayName(EditContext context)
{
if (!string.IsNullOrEmpty(Model?.UserName) && !string.IsNullOrEmpty(DisplayName))
if (!string.IsNullOrEmpty(User.UserName) && Bootstrap.DataAccess.UserHelper.SaveDisplayName(User.UserName, User.DisplayName))
{
if (Bootstrap.DataAccess.UserHelper.SaveDisplayName(Model.UserName, DisplayName))
{
RootLayout?.OnDisplayNameChanged(DisplayName);
}
RootLayout?.OnDisplayNameChanged(User.DisplayName);
}
}
private void SavePassword(EditContext context)
{
Bootstrap.DataAccess.UserHelper.ChangePassword(User.UserName, Password.Password, Password.NewPassword);
}
protected class PasswordModel
{
[DisplayName("原密码")]
public string Password { get; set; } = "";
[DisplayName("新密码")]
public string NewPassword { get; set; } = "";
[DisplayName("确认密码")]
public string ConfirmPassword { get; set; } = "";
}
}

View File

@ -1,8 +1,8 @@
@inherits LgbInputTextBase
<div class="form-group col-sm-6">
<div class="@($"form-group {ColumnClass}")">
<label class="control-label" for="@Id">@DisplayName</label>
<input Id="@Id" data-original-title="@ErrorMessage" class="@($"form-control {CssClass} {ValidCss}")" placeholder="@PlaceHolder" maxlength=@MaxLength type="text" @bind="Value" @oninput="EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
<input Id="@Id" data-original-title="@ErrorMessage" class="@($"form-control {CssClass} {ValidCss}")" placeholder="@PlaceHolder" maxlength=@MaxLength type="@InputType" @bind="Value" @oninput="EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
<CascadingValue Value="this" IsFixed="true">
@ChildContent
</CascadingValue>

View File

@ -18,48 +18,50 @@
</div>
</div>
<table class="table table-striped table-bordered table-hover table-selected">
<thead>
<tr>
@if (ShowLineNo)
{
<th class="table-col-lineno">行号</th>
}
@if (ShowCheckbox)
{
<th class="table-col-checkbox"><Checkbox TItem="TItem" SetCheckCallback="CheckState" ToggleCallback="ToggleCheck"></Checkbox></th>
}
@TableHeader?.Invoke(EditModel)
@if (ShowButtons)
{
<th>@ButtonTemplateHeaderText</th>
}
</tr>
</thead>
<tbody>
@for (int index = 0; index < Items.Count(); index++)
{
<div class="table-wrapper">
<table class="table table-striped table-bordered table-hover table-selected">
<thead>
<tr>
@if (ShowLineNo)
{
<td class="table-col-lineno">@(index + 1 + (PageIndex - 1) * PageItems)</td>
<th class="table-col-lineno">行号</th>
}
@if (ShowCheckbox)
{
<td class="table-col-checkbox"><Checkbox TItem="TItem" Item="Items.ElementAt(index)" SetCheckCallback="item => SelectedItems.Contains(item) ? CheckBoxState.Checked : CheckBoxState.UnChecked" ToggleCallback="ToggleCheck"></Checkbox></td>
<th class="table-col-checkbox"><Checkbox TItem="TItem" SetCheckCallback="CheckState" ToggleCallback="ToggleCheck"></Checkbox></th>
}
@RowTemplate?.Invoke(Items.ElementAt(index))
@TableHeader?.Invoke(EditModel)
@if (ShowButtons)
{
<td>@ButtonTemplate?.Invoke(Items.ElementAt(index))</td>
<th>@ButtonTemplateHeaderText</th>
}
</tr>
}
</tbody>
<tfoot>
<tr>@TableFooter</tr>
</tfoot>
</table>
</thead>
<tbody>
@for (int index = 0; index < Items.Count(); index++)
{
<tr>
@if (ShowLineNo)
{
<td class="table-col-lineno">@(index + 1 + (PageIndex - 1) * PageItems)</td>
}
@if (ShowCheckbox)
{
<td class="table-col-checkbox"><Checkbox TItem="TItem" Item="Items.ElementAt(index)" SetCheckCallback="item => SelectedItems.Contains(item) ? CheckBoxState.Checked : CheckBoxState.UnChecked" ToggleCallback="ToggleCheck"></Checkbox></td>
}
@RowTemplate?.Invoke(Items.ElementAt(index))
@if (ShowButtons)
{
<td>@ButtonTemplate?.Invoke(Items.ElementAt(index))</td>
}
</tr>
}
</tbody>
<tfoot>
<tr>@TableFooter</tr>
</tfoot>
</table>
</div>
<Pagination PageItems="PageItems" TotalCount="TotalCount" PageIndex="PageIndex" OnPageClick="PageClick" OnPageItemsChange="PageItemsChange"></Pagination>
</div>

View File

@ -14,6 +14,7 @@
@using Microsoft.Extensions.Configuration
@using Microsoft.JSInterop
@using Longbow.Web.Mvc
@using System.ComponentModel
@using System.Linq
@using System.Net
@using System.Net.Http

View File

@ -130,6 +130,16 @@ nav .dropdown .nav-link-close.dropdown-toggle:after {
margin-bottom: 0;
}
.table-wrapper {
border-radius: 4px;
overflow: auto;
margin-bottom: 1rem;
}
.table-wrapper .table {
margin-bottom: 0;
}
.pagination-bar {
flex: 1 1 auto;
margin-bottom: 1rem;
@ -220,3 +230,8 @@ nav .dropdown .nav-link-close.dropdown-toggle:after {
margin-bottom: 15px;
font-size: 1.125rem;
}
.card-footer {
text-align: right;
padding: 0.5rem 1rem;
}