!58 增加功能:Blazor 个人中心增加保存应用与样式功能
Merge pull request !58 from Argo/dev-blazor-wip
This commit is contained in:
commit
9ca7df8578
|
@ -30,6 +30,12 @@ namespace Bootstrap.Admin.Components
|
|||
[Parameter]
|
||||
public string AuthKey { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否显示
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool? Condition { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 子控件
|
||||
/// </summary>
|
||||
|
@ -61,6 +67,7 @@ namespace Bootstrap.Admin.Components
|
|||
render = ComponentAuthorization?.Authorizate(user, url.ToMvcMenuUrl(), AuthKey) ?? false;
|
||||
}
|
||||
}
|
||||
else if (Condition.HasValue) render = Condition.Value;
|
||||
else render = RootLayout?.Model.IsDemo ?? false;
|
||||
if (Inverse) render = !render;
|
||||
if (render) builder.AddContent(0, ChildContent);
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bootstrap.Admin.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Dropdown 组件
|
||||
/// </summary>
|
||||
public class DropdownBase : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 获得/设置 绑定数据集合
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public IEnumerable<SelectedItem> Items { get; set; } = new SelectedItem[0];
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 选中项实例
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public SelectedItem Value { get; set; } = new SelectedItem();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 选中项改变回调方法
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public EventCallback<SelectedItem> ValueChanged { get; set; }
|
||||
}
|
||||
}
|
|
@ -29,90 +29,86 @@
|
|||
</ConditionComponent>
|
||||
</div>
|
||||
</AuthorizateComponent>
|
||||
<div class="card" asp-auth="savePassword" asp-condition="!@Model?.External">
|
||||
<div class="card-header">修改密码</div>
|
||||
<div class="card-body">
|
||||
<ConditionComponent>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<span>演示系统禁止更改管理员密码</span>
|
||||
<ConditionComponent Condition="@(Model?.External ?? false)" Inverse="true">
|
||||
<ConditionComponent AuthKey="savePassword">
|
||||
<div class="card">
|
||||
<div class="card-header">修改密码</div>
|
||||
<div class="card-body">
|
||||
<ConditionComponent>
|
||||
<div class="alert alert-danger" role="alert">
|
||||
<span>演示系统禁止更改管理员密码</span>
|
||||
</div>
|
||||
</ConditionComponent>
|
||||
<LgbEditForm class="form-inline" Id="Profile" Model="Password" OnValidSubmit="SavePassword">
|
||||
<div class="row">
|
||||
<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">
|
||||
<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>
|
||||
</LgbEditForm>
|
||||
</div>
|
||||
</ConditionComponent>
|
||||
<LgbEditForm class="form-inline" Id="Profile" Model="Password" OnValidSubmit="SavePassword">
|
||||
<div class="row">
|
||||
<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">
|
||||
<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>
|
||||
</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>
|
||||
<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>
|
||||
</ConditionComponent>
|
||||
</div>
|
||||
<div class="card" asp-auth="saveApp">
|
||||
<div class="card-header">默认应用</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="app" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" value="@Model?.AppId">@Model?.AppName</button>
|
||||
<div class="dropdown-menu">
|
||||
@foreach (var app in Model?.Applications ?? new KeyValuePair<string, string>[0])
|
||||
{
|
||||
<a href="#" data-val="@app.Key">@app.Value</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</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">
|
||||
<div class="card-header">网站样式</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info" role="alert">
|
||||
<span>注意:本设置将覆盖<b><a class="badge-pill" href="./Settings">网站设置</a></b>中设置的网站样式</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="btn-group" role="group">
|
||||
<button id="css" class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown" data-default-val="" value="@Model?.Css">默认样式</button>
|
||||
<div class="dropdown-menu">
|
||||
<a href="#" data-val="">默认样式</a>
|
||||
@foreach (var css in Model?.Themes ?? new Bootstrap.Security.BootstrapDict[0])
|
||||
{
|
||||
<a href="#" data-val="@css.Code">@css.Name</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</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">
|
||||
<div class="card-header">修改头像</div>
|
||||
<div class="card-body">
|
||||
<form enctype="multipart/form-data">
|
||||
</ConditionComponent>
|
||||
<ConditionComponent AuthKey="saveApp">
|
||||
<div class="card">
|
||||
<div class="card-header">默认应用</div>
|
||||
<div class="card-body">
|
||||
<div class="form-group">
|
||||
<input id="fileIcon" type="file" data-init="@Model?.Size" data-file="@Model?.FileName">
|
||||
<div class="btn-group" role="group">
|
||||
<Dropdown @bind-Value="@SelectedApp" Items="@Apps"></Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<img class="card-img d-none" src="@Model?.Icon.ToBlazorLink()" />
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button class="btn btn-secondary" type="button" @onclick="SaveApp"><i class="fa fa-save"></i><span>保存</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ConditionComponent>
|
||||
<ConditionComponent AuthKey="saveTheme">
|
||||
<div class="card">
|
||||
<div class="card-header">网站样式</div>
|
||||
<div class="card-body">
|
||||
<div class="alert alert-info" role="alert">
|
||||
<span>注意:本设置将覆盖<b><a class="badge-pill" href="@("~/Admin/Settings".ToBlazorMenuUrl())">网站设置</a></b>中设置的网站样式</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<Dropdown @bind-Value="@SelectedTheme" Items="@Themes"></Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<button class="btn btn-secondary" type="button" @onclick="SaveTheme"><i class="fa fa-save"></i><span>保存</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</ConditionComponent>
|
||||
<ConditionComponent AuthKey="saveIcon">
|
||||
<div class="card">
|
||||
<div class="card-header">修改头像</div>
|
||||
<div class="card-body">
|
||||
<form enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<input id="fileIcon" type="file" data-init="@Model?.Size" data-file="@Model?.FileName">
|
||||
</div>
|
||||
</form>
|
||||
<img class="card-img d-none" src="@Model?.Icon.ToBlazorLink()" />
|
||||
</div>
|
||||
</div>
|
||||
</ConditionComponent>
|
||||
<Toast @ref="Toast" Id="toast_profile"></Toast>
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
using System.ComponentModel;
|
||||
using Bootstrap.Admin.Components;
|
||||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.Admin.Shared;
|
||||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.Security;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Pages.Admin.Components
|
||||
{
|
||||
|
@ -44,13 +48,51 @@ namespace Bootstrap.Pages.Admin.Components
|
|||
[DisplayName("显示名称")]
|
||||
public string DisplayName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Toast 组件实例
|
||||
/// </summary>
|
||||
protected Toast? Toast { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 选中的样式项
|
||||
/// </summary>
|
||||
protected SelectedItem SelectedTheme { get; set; } = new SelectedItem();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 选中的应用程序
|
||||
/// </summary>
|
||||
protected SelectedItem SelectedApp { get; set; } = new SelectedItem();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 应用程序集合
|
||||
/// </summary>
|
||||
protected IEnumerable<SelectedItem> Apps { get; set; } = new SelectedItem[0];
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 网站样式集合
|
||||
/// </summary>
|
||||
protected IEnumerable<SelectedItem> Themes { get; set; } = new SelectedItem[0];
|
||||
|
||||
/// <summary>
|
||||
/// 显示提示信息
|
||||
/// </summary>
|
||||
/// <param name="text"></param>
|
||||
/// <param name="ret"></param>
|
||||
protected void ShowMessage(string text, bool ret = true) => Toast?.ShowMessage("个人中心", text, ret ? ToastCategory.Success : ToastCategory.Error);
|
||||
|
||||
/// <summary>
|
||||
/// 组件初始化方法
|
||||
/// </summary>
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Model = new ProfilesModel(RootLayout?.UserName);
|
||||
var user = DataAccess.UserHelper.RetrieveUserByUserName(Model?.UserName);
|
||||
Themes = new SelectedItem[] { new SelectedItem() { Text = "默认样式" } }.Union(Model.Themes.Select(t => new SelectedItem() { Text = t.Name, Value = t.Code }));
|
||||
Apps = Model.Applications.Select(t => new SelectedItem() { Text = t.Value, Value = t.Key });
|
||||
|
||||
SelectedTheme = Themes.First();
|
||||
SelectedApp = Apps.First();
|
||||
|
||||
var user = UserHelper.RetrieveUserByUserName(Model?.UserName);
|
||||
if (user != null) User = user;
|
||||
|
||||
// 直接绑定 User.DisplayName 导致未保存时 UI 的显示名称也会变化
|
||||
|
@ -62,10 +104,18 @@ namespace Bootstrap.Pages.Admin.Components
|
|||
/// </summary>
|
||||
protected void SaveDisplayName(EditContext context)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(User.UserName) && Bootstrap.DataAccess.UserHelper.SaveDisplayName(User.UserName, DisplayName))
|
||||
if (!string.IsNullOrEmpty(User.UserName))
|
||||
{
|
||||
User.DisplayName = DisplayName;
|
||||
RootLayout?.OnDisplayNameChanged(DisplayName);
|
||||
var ret = UserHelper.SaveDisplayName(User.UserName, DisplayName);
|
||||
if (ret)
|
||||
{
|
||||
User.DisplayName = DisplayName;
|
||||
RootLayout?.OnDisplayNameChanged(DisplayName);
|
||||
}
|
||||
|
||||
// 弹窗提示是否保存成功
|
||||
var result = ret ? "成功" : "失败";
|
||||
ShowMessage($"保存显示名称{result}", ret);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,7 +124,35 @@ namespace Bootstrap.Pages.Admin.Components
|
|||
/// </summary>
|
||||
protected void SavePassword(EditContext context)
|
||||
{
|
||||
Bootstrap.DataAccess.UserHelper.ChangePassword(User.UserName, Password.Password, Password.NewPassword);
|
||||
var ret = UserHelper.ChangePassword(User.UserName, Password.Password, Password.NewPassword);
|
||||
|
||||
// 弹窗提示是否保存成功
|
||||
var result = ret ? "成功" : "失败";
|
||||
ShowMessage($"更新密码{result}", ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存默认应用方法
|
||||
/// </summary>
|
||||
protected void SaveApp()
|
||||
{
|
||||
var ret = UserHelper.SaveApp(User.UserName, SelectedApp.Value);
|
||||
|
||||
// 弹窗提示是否保存成功
|
||||
var result = ret ? "成功" : "失败";
|
||||
ShowMessage($"保存默认应用{result}", ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存网站样式方法
|
||||
/// </summary>
|
||||
protected void SaveTheme()
|
||||
{
|
||||
var ret = UserHelper.SaveUserCssByName(User.UserName, SelectedTheme.Value);
|
||||
|
||||
// 弹窗提示是否保存成功
|
||||
var result = ret ? "成功" : "失败";
|
||||
ShowMessage($"保存网站样式{result}", ret);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
@inherits DropdownBase
|
||||
|
||||
<div class="btn-group" role="group">
|
||||
<button class="btn btn-success dropdown-select dropdown-toggle" data-toggle="dropdown">@Value.Text</button>
|
||||
<div class="dropdown-menu">
|
||||
@foreach (var item in Items)
|
||||
{
|
||||
<div class="dropdown-item" @onclick="e => Value = item">@item.Text</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
|
@ -435,7 +435,7 @@ footer {
|
|||
outline: none;
|
||||
}
|
||||
|
||||
.dropdown-select + .dropdown-menu a:hover {
|
||||
.dropdown-select + .dropdown-menu a:hover, .dropdown-select + .dropdown-menu .dropdown-item:hover {
|
||||
background: #007AC0;
|
||||
color: #fff;
|
||||
}
|
||||
|
@ -444,10 +444,11 @@ footer {
|
|||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.176);
|
||||
}
|
||||
|
||||
.dropdown-menu a {
|
||||
.dropdown-menu a, .dropdown-menu .dropdown-item {
|
||||
transition: all .25s linear;
|
||||
padding: 6px 20px;
|
||||
display: block;
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.dropdown-divider {
|
||||
|
|
Loading…
Reference in New Issue