-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
852 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
@page "/admin/friendlinks" | ||
@using Jonty.Blog.BlazorApp.Response.Blog.Params | ||
|
||
<AdminLayout> | ||
@if (friendlinks == null) | ||
{ | ||
<Loading /> } | ||
else | ||
{ | ||
<div class="post-wrap categories"> | ||
<h2 class="post-title">- FriendLinks -</h2> | ||
@if (friendlinks.Success && friendlinks.Result.Any()) | ||
{ | ||
<div class="categories-card"> | ||
@foreach (var item in friendlinks.Result) | ||
{ | ||
<div class="card-item"> | ||
<div class="categories"> | ||
<NavLink title="❌删除" @onclick="@(async () => await DeleteAsync(item.Id))">❌</NavLink> | ||
<NavLink title="📝编辑" @onclick="@(() => ShowBox(item))">📝</NavLink> | ||
<NavLink target="_blank" href="@item.LinkUrl"> | ||
<h3>@item.Title</h3> | ||
</NavLink> | ||
</div> | ||
</div>} | ||
<div class="card-item"> | ||
<div class="categories"> | ||
<NavLink><h3 @onclick="@(() => ShowBox())">📒~~~ 新增友链 ~~~📒</h3></NavLink> | ||
</div> | ||
</div> | ||
</div> } | ||
else | ||
{ | ||
<ErrorTip />} | ||
</div> | ||
|
||
<Box OnClickCallback="@SubmitAsync" Open="@Open"> | ||
<div class="box-item"> | ||
<b>Title:</b><input type="text" @bind="@title" @bind:event="oninput" /> | ||
</div> | ||
<div class="box-item"> | ||
<b>LinkUrl:</b><input type="text" @bind="@linkUrl" @bind:event="oninput" /> | ||
</div> | ||
</Box>} | ||
</AdminLayout> | ||
|
||
@code { /// <summary> | ||
/// 默认隐藏Box | ||
/// </summary> | ||
private bool Open { get; set; } = false; | ||
|
||
/// <summary> | ||
/// 新增或者更新时候的友链字段值 | ||
/// </summary> | ||
private string title, linkUrl; | ||
|
||
/// <summary> | ||
/// 更新友链的Id值 | ||
/// </summary> | ||
private int id; | ||
|
||
/// <summary> | ||
/// API返回的友链列表数据 | ||
/// </summary> | ||
private ServiceResult<IEnumerable<QueryFriendLinkForAdminDto>> friendlinks; | ||
|
||
/// <summary> | ||
/// 初始化 | ||
/// </summary> | ||
/// <returns></returns> | ||
protected override async Task OnInitializedAsync() | ||
{ | ||
var token = await Common.GetStorageAsync("token"); | ||
Http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}"); | ||
|
||
friendlinks = await FetchData(); | ||
} | ||
|
||
/// <summary> | ||
/// 获取数据 | ||
/// </summary> | ||
/// <returns></returns> | ||
private async Task<ServiceResult<IEnumerable<QueryFriendLinkForAdminDto>>> FetchData() | ||
{ | ||
return await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryFriendLinkForAdminDto>>>("/blog/admin/friendlinks"); | ||
} | ||
|
||
/// <summary> | ||
/// 删除分类 | ||
/// </summary> | ||
/// <param name="id"></param> | ||
/// <returns></returns> | ||
private async Task DeleteAsync(int id) | ||
{ | ||
Open = false; | ||
|
||
// 弹窗确认 | ||
bool confirmed = await Common.InvokeAsync<bool>("confirm", "\n💥💢真的要干掉这个该死的友链吗💢💥"); | ||
|
||
if (confirmed) | ||
{ | ||
var response = await Http.DeleteAsync($"/blog/friendlink?id={id}"); | ||
|
||
var result = await response.Content.ReadFromJsonAsync<ServiceResult>(); | ||
|
||
if (result.Success) | ||
{ | ||
friendlinks = await FetchData(); | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// 显示box,绑定字段 | ||
/// </summary> | ||
/// <param name="dto"></param> | ||
private void ShowBox(QueryFriendLinkForAdminDto dto = null) | ||
{ | ||
Open = true; | ||
id = 0; | ||
|
||
// 新增 | ||
if (dto == null) | ||
{ | ||
title = null; | ||
linkUrl = null; | ||
} | ||
else // 更新 | ||
{ | ||
id = dto.Id; | ||
title = dto.Title; | ||
linkUrl = dto.LinkUrl; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// 确认按钮点击事件 | ||
/// </summary> | ||
/// <returns></returns> | ||
private async Task SubmitAsync() | ||
{ | ||
var input = new EditFriendLinkInput() | ||
{ | ||
Title = title.Trim(), | ||
LinkUrl = linkUrl.Trim() | ||
}; | ||
|
||
if (string.IsNullOrEmpty(input.Title) || string.IsNullOrEmpty(input.LinkUrl)) | ||
{ | ||
return; | ||
} | ||
|
||
var responseMessage = new HttpResponseMessage(); | ||
|
||
if (id > 0) | ||
responseMessage = await Http.PutAsJsonAsync($"/blog/friendlink?id={id}", input); | ||
else | ||
responseMessage = await Http.PostAsJsonAsync("/blog/friendlink", input); | ||
|
||
var result = await responseMessage.Content.ReadFromJsonAsync<ServiceResult>(); | ||
if (result.Success) | ||
{ | ||
friendlinks = await FetchData(); | ||
Open = false; | ||
} | ||
} } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
@page "/admin/post" | ||
@page "/admin/post/{id:int}" | ||
|
||
<link href="./editor.md/css/editormd.css" rel="stylesheet" /> | ||
|
||
<AdminLayout> | ||
@if (isLoading) | ||
{ | ||
<Loading /> } | ||
else | ||
{ | ||
<div class="post-box"> | ||
<div class="post-box-item"> | ||
<input type="text" placeholder="标题" autocomplete="off" @bind="@input.Title" @bind:event="oninput" @onclick="@(() => { Open = false; })" /> | ||
<input type="text" placeholder="作者" autocomplete="off" @bind="@input.Author" @bind:event="oninput" @onclick="@(() => { Open = false; })" /> | ||
</div> | ||
<div class="post-box-item"> | ||
<input type="text" placeholder="URL" autocomplete="off" @bind="@input.Url" @bind:event="oninput" @onclick="@(() => { Open = false; })" /> | ||
<input type="text" placeholder="时间" autocomplete="off" @bind="@input.CreationTime" @bind:format="yyyy-MM-dd HH:mm:sss" @bind:event="oninput" @onclick="@(() => { Open = false; })" /> | ||
</div> | ||
<div id="editor"> | ||
<textarea style="display:none;">@input.Markdown</textarea> | ||
</div> | ||
|
||
<Box OnClickCallback="@SubmitAsync" Open="@Open" ButtonText="发布"> | ||
<div class="box-item"> | ||
<b>分类:</b> | ||
@if (categories.Success && categories.Result.Any()) | ||
{ | ||
@foreach (var item in categories.Result) | ||
{ | ||
<label><input type="radio" name="category" value="@item.Id" @onchange="@(() => { input.CategoryId = item.Id; })" checked="@(item.Id == input.CategoryId)" />@item.CategoryName</label>}} | ||
</div> | ||
<div class="box-item"></div> | ||
<div class="box-item"> | ||
<b>标签:</b> | ||
<input type="text" @bind="@tags" @bind:event="oninput" /> | ||
</div> | ||
</Box> | ||
</div>} | ||
</AdminLayout> | ||
|
||
@code { /// <summary> | ||
/// 定义一个委托方法,用于组件实例方法调用 | ||
/// </summary> | ||
private static Func<Task> action; | ||
|
||
/// <summary> | ||
/// 默认隐藏Box | ||
/// </summary> | ||
private bool Open { get; set; } = false; | ||
|
||
/// <summary> | ||
/// 修改时的文章Id | ||
/// </summary> | ||
[Parameter] | ||
public int? Id { get; set; } | ||
|
||
/// <summary> | ||
/// 格式化的标签 | ||
/// </summary> | ||
private string tags { get; set; } | ||
|
||
/// <summary> | ||
/// 默认显示加载中 | ||
/// </summary> | ||
private bool isLoading = true; | ||
|
||
/// <summary> | ||
/// 文章新增或者修改输入参数 | ||
/// </summary> | ||
private PostForAdminDto input; | ||
|
||
/// <summary> | ||
/// API返回的分类列表数据 | ||
/// </summary> | ||
private ServiceResult<IEnumerable<QueryCategoryForAdminDto>> categories; | ||
|
||
/// <summary> | ||
/// 初始化 | ||
/// </summary> | ||
/// <returns></returns> | ||
protected override async Task OnInitializedAsync() | ||
{ | ||
action = ChangeOpenStatus; | ||
|
||
var token = await Common.GetStorageAsync("token"); | ||
Http.DefaultRequestHeaders.Add("Authorization", $"Bearer {token}"); | ||
|
||
if (Id.HasValue) | ||
{ | ||
var post = await Http.GetFromJsonAsync<ServiceResult<PostForAdminDto>>($"/blog/admin/post?id={Id}"); | ||
|
||
if (post.Success) | ||
{ | ||
var _post = post.Result; | ||
input = new PostForAdminDto | ||
{ | ||
Title = _post.Title, | ||
Author = _post.Author, | ||
Url = _post.Url, | ||
Html = _post.Html, | ||
Markdown = _post.Markdown, | ||
CategoryId = _post.CategoryId, | ||
Tags = _post.Tags, | ||
CreationTime = _post.CreationTime | ||
}; | ||
|
||
tags = string.Join(",", input.Tags); | ||
} | ||
} | ||
else | ||
{ | ||
input = new PostForAdminDto() | ||
{ | ||
Author = "Jonty", | ||
CreationTime = DateTime.Now | ||
}; | ||
} | ||
|
||
categories = await Http.GetFromJsonAsync<ServiceResult<IEnumerable<QueryCategoryForAdminDto>>>("/blog/admin/categories"); | ||
|
||
// 渲染编辑器 | ||
await Common.InvokeAsync("window.func.renderEditor"); | ||
|
||
// 关闭加载 | ||
isLoading = !isLoading; | ||
} | ||
|
||
/// <summary> | ||
/// 改变Open状态,通知组件渲染 | ||
/// </summary> | ||
private async Task ChangeOpenStatus() | ||
{ | ||
Open = true; | ||
|
||
var markdown = await Common.InvokeAsync<string>("editor.getMarkdown"); | ||
var html = await Common.InvokeAsync<string>("editor.getHTML"); | ||
|
||
if (string.IsNullOrEmpty(input.Title) || string.IsNullOrEmpty(input.Url) || | ||
string.IsNullOrEmpty(input.Author) || string.IsNullOrEmpty(markdown) || | ||
string.IsNullOrEmpty(html)) | ||
{ | ||
await Alert(); | ||
} | ||
|
||
input.Html = html; | ||
input.Markdown = markdown; | ||
|
||
StateHasChanged(); | ||
} | ||
|
||
/// <summary> | ||
/// 暴漏给JS执行,弹窗确认框 | ||
/// </summary> | ||
[JSInvokable("showbox")] | ||
public static void ShowBox() | ||
{ | ||
action.Invoke(); | ||
} | ||
|
||
/// <summary> | ||
/// 确认按钮点击事件 | ||
/// </summary> | ||
/// <returns></returns> | ||
private async Task SubmitAsync() | ||
{ | ||
if (string.IsNullOrEmpty(tags) || input.CategoryId == 0) | ||
{ | ||
await Alert(); | ||
} | ||
|
||
input.Tags = tags.Split(","); | ||
|
||
var responseMessage = new HttpResponseMessage(); | ||
|
||
if (Id.HasValue) | ||
responseMessage = await Http.PutAsJsonAsync($"/blog/post?id={Id}", input); | ||
else | ||
responseMessage = await Http.PostAsJsonAsync("/blog/post", input); | ||
|
||
var result = await responseMessage.Content.ReadFromJsonAsync<ServiceResult>(); | ||
if (result.Success) | ||
{ | ||
await Common.NavigateTo("/admin/posts"); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// alert提示 | ||
/// </summary> | ||
/// <returns></returns> | ||
private async Task Alert() | ||
{ | ||
Open = false; | ||
|
||
await Common.InvokeAsync("alert", "\n💥💢好像漏了点什么吧💢💥"); | ||
return; | ||
} } |
Oops, something went wrong.