Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
niltor committed Apr 7, 2024
2 parents 98105be + 63a3259 commit c6db6b9
Show file tree
Hide file tree
Showing 15 changed files with 278 additions and 95 deletions.
5 changes: 2 additions & 3 deletions Content/ASP.NET Core/使用EPPlus导入导出Excel示例.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# 使用EPPlus导入导出Excel示例

# 使用EPPlus导入导出Excel示例

```csharp

Expand Down Expand Up @@ -96,4 +95,4 @@ public class ExcelService
}
}

```
```
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# 关于EF Core更新速度随时间越来越慢的解决办法

## 概要
本篇主要介绍使用 `context.ChangeTracker.Clear() `方法,在通过循环进行批量更新时,通过手动清除跟踪实体以提高性能的示例。

本篇主要介绍使用 `context.ChangeTracker.Clear()`方法,在通过循环进行批量更新时,通过手动清除跟踪实体以提高性能的示例。

## 背景

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# 如何部署ASP.NET Core 到Linux服务器

我们开发的最终目的,是将开发后的东西发布网络上,以便自己及其他人使用。

本篇博客介绍如果在 linux 上部署 ASP.NET Core应用,使用nginx+systemd 来管理我们的应用。


## 准备

- Ubuntu 20.04
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 记录一次ASP.NET Core Out Of Memory问题的处理

## 概要

记录一次生产环境的异常事件,运维监控到CPU突然占用100%,其中一个docker 容器崩掉,经过一段时间的观察和搜索,最终通过 AppDomain.FirstChanceException去定位问题,因为错误使用了 LoggerFactory.Create而产生的Out of memory错误。

## 背景
Expand Down
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
"Name": "Niltor Blog", // 博客名称,显示在主页顶部导航
"Description": "🗽 for freedom",// 说明,显示在主页顶部中间
"AuthorName": "Ater", // 作者名称,显示在博客列表
"BaseHref": "/blazor-blog/" // 子目录
"BaseHref": "/blazor-blog/", // 子目录
"Domain": "https://aterdev.github.io" // 域名,生成sitemap使用,不生成则留空
}
```

Expand Down Expand Up @@ -103,23 +104,27 @@ fork之后,你将拥有所有的自定义权限,因为所有的源代码都

此外,你可以安装(可选)

- tailwindcss,用来生成css样式内容
- http-server,用来启动本地静态内容,以便调试
- http-server,用来启动本地静态内容,以便调试。
- tailwindcss,用来生成css样式内容。
- typescript,以便使用`tsc`命令。

### 运行项目

1. 预览项目
1. 打开终端,在`WebApp`目录下执行`http-server`,然后在浏览器中打开`http://127.0.0.1:8080`
2. 生成静态内容。
1. 在根目录下执行`dotnet run --project ./Lib/BuildSite ./Content ./WebApp`,以生成最新的静态内容。
1. 在根目录下执行`dotnet run --project ./src/BuildSite ./Content ./WebApp`,以生成最新的静态内容。
2. 或者直接运行根目录下的`build.ps1`脚本。
3. 刷新浏览器,可看到最新生成的内容。

如果你使用`tailwindcss`,可在`WebApp`下执行`npx tailwindcss -o ./css/app.css --watch`
> [!TIP]
> 如果你使用`Tailwindcss`,可在`WebApp`下执行`npx tailwindcss -o ./css/app.css --watch`
>
> 如果你使用`Typescript`,可在`WebApp`下执行`tsc -w`
### 自定义主页内容

主页内容模板位于`Lib\BuildSite\template\index.html.tpl`,其中包括以下变量:
主页内容模板位于`src\BuildSite\template\index.html.tpl`,其中包括以下变量:

|模板变量 |说明 |
|---------|---------|
Expand All @@ -142,7 +147,7 @@ fork之后,你将拥有所有的自定义权限,因为所有的源代码都

### 自定义博客展示页

博客页内容模板位于`Lib\BuildSite\template\blog.html.tpl`,其中包括以下变量:
博客页内容模板位于`src\BuildSite\template\blog.html.tpl`,其中包括以下变量:

|模板变量 |说明 |
|---------|---------|
Expand Down
8 changes: 4 additions & 4 deletions WebApp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My Blog</title>
<title>EasyBlog</title>
<meta name="description" content="🗽to be a human" />
<base href="/" />
<link rel="stylesheet" href="/css/app.css" />
<link rel="stylesheet" href="/css/markdown.css" />
<link rel="icon" type="image/png" href="/favicon.ico" />
<script>const baseUrl = '';</script>
<script>const baseUrl = '/';</script>
<script src="/js/index.js"></script>
</head>

<body class="dark:bg-neutral-900">
<div class="text-white py-4 bg-gray-600 dark:bg-neutral-800">
<div class="container mx-auto flex items-center justify-between">
<a href="/" class="text-2xl font-semibold hidden sm:block">My Blog</a>
<a href="/" class="text-2xl font-semibold hidden sm:block">EasyBlog</a>
<span class="hidden sm:block">🗽to be a human</span>
<div class="flex items-center">
<input id="searchText" placeholder="博客标题" class="px-4 py-2 border border-gray-600 rounded-lg dark:bg-neutral-800 text-white focus:outline-none" />
Expand Down Expand Up @@ -86,7 +86,7 @@
<div class="dark:bg-neutral-800 py-4 fixed bottom-0 w-full bg-gray-200">
<div class="container mx-auto text-center">
<p class="text-neutral-600 dark:text-neutral-300">
My Blog
EasyBlog
<a class="text-blue-600" target="_blank" href="https://github.com/AterDev/blazor-blog">Powered by Ater Blog</a>
</p>
</div>
Expand Down
11 changes: 6 additions & 5 deletions WebApp/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ class Index {
catalogs = [];
webInfo;
constructor() {
document.addEventListener('DOMContentLoaded', () => this.init());
}
init() {
this.getData();
this.addEvent();
}
getData() {
fetch(BaseUrl + 'data/blogs.json')
Expand Down Expand Up @@ -151,8 +156,4 @@ class Index {
return '刚刚';
}
}
const index = new Index();
document.addEventListener('DOMContentLoaded', function () {
index.getData();
index.addEvent();
});
new Index();
108 changes: 56 additions & 52 deletions WebApp/js/markdown.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,58 @@
document.addEventListener('DOMContentLoaded', function () {
// support mermaind
if (typeof mermaid !== 'undefined') {
mermaid.initialize({ startOnLoad: true });
}

const languageDivs = document.querySelectorAll('div[class^="language-"]');

const copyContent = `&#128203;copy code`;
// 为每个代码片段添加复制图标
languageDivs.forEach(languageDiv => {
const language = languageDiv.className.split(' ')[0].split('-')[1];

const codeActionBar = document.createElement('div');
codeActionBar.classList.add('code-action-bar', 'flex', 'justify-between');

codeActionBar.innerHTML = `<span>${language}</span><span class="copy-icon">${copyContent}</span>`;
languageDiv.parentNode.insertBefore(codeActionBar, languageDiv);

const copyIcon = codeActionBar.querySelector('.copy-icon');
// 点击复制图标时复制代码片段到剪贴板
copyIcon.addEventListener('click', () => {
// 复制代码片段的内容到剪贴板
// get pre tag element innertext from codeSnippet
const textToCopy = languageDiv.querySelector('pre').innerText;
navigator.clipboard.writeText(textToCopy)
.then(() => {
// 复制成功后将图标更改为对号
copyIcon.innerHTML = '&#10003 copied!';

// 2秒后恢复图标为原始状态
setTimeout(() => {
copyIcon.innerHTML = copyContent;
}, 1000);
const mermaid = window.mermaid;
const nomnoml = window.nomnoml;
class MarkdownHandler {
copyContent = '&#128203;copy code';
constructor() {
document.addEventListener('DOMContentLoaded', () => this.init());
}
init() {
this.initMermaid();
this.initCodeCopy();
this.initNomnoml();
}
initMermaid() {
if (typeof mermaid !== 'undefined') {
mermaid.initialize({ startOnLoad: true });
}
}
initCodeCopy() {
const languageDivs = document.querySelectorAll('div[class^="language-"]');
languageDivs.forEach(languageDiv => this.addCopyIcon(languageDiv));
}
addCopyIcon(languageDiv) {
const language = languageDiv.className.split(' ')[0].split('-')[1];
const codeActionBar = document.createElement('div');
codeActionBar.classList.add('code-action-bar', 'flex', 'justify-between');
codeActionBar.innerHTML = `<span>${language}</span><span class="copy-icon">${this.copyContent}</span>`;
languageDiv.parentNode.insertBefore(codeActionBar, languageDiv);
const copyIcon = codeActionBar.querySelector('.copy-icon');
copyIcon.addEventListener('click', () => this.copyCode(languageDiv, copyIcon));
}
copyCode(languageDiv, copyIcon) {
const textToCopy = languageDiv.querySelector('pre').innerText;
navigator.clipboard.writeText(textToCopy)
.then(() => {
copyIcon.innerHTML = '&#10003 copied!';
setTimeout(() => {
copyIcon.innerHTML = this.copyContent;
}, 1000);
})
.catch(err => {
console.error('Failed to copy: ', err);
.catch(err => {
console.error('Failed to copy: ', err);
});

});
});

var nomnomlDivs = document.querySelectorAll('.nomnoml');
if (nomnomlDivs.length > 0) {
const nomnomlDiv = nomnomlDivs[0];
const content = nomnomlDiv.textContent;
nomnomlDiv.innerHTML = '';

const canvas = document.createElement('canvas');
nomnoml.draw(canvas, content);
nomnomlDiv.appendChild(canvas);
}

});
}
initNomnoml() {
if (typeof nomnoml !== 'undefined') {
var nomnomlDivs = document.querySelectorAll('.nomnoml');
if (nomnomlDivs.length > 0) {
const nomnomlDiv = nomnomlDivs[0];
const content = nomnomlDiv.textContent;
nomnomlDiv.innerHTML = '';
const canvas = document.createElement('canvas');
nomnoml.draw(canvas, content);
nomnomlDiv.appendChild(canvas);
}
}
}
}
new MarkdownHandler();
15 changes: 15 additions & 0 deletions WebApp/sitemap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://aterdev.github.io/EasyBlog/blogs/introduction.html</loc>
<lastmod>2024-04-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://aterdev.github.io/EasyBlog/blogs/Markdown%E6%94%AF%E6%8C%81%E7%A4%BA%E4%BE%8B.html</loc>
<lastmod>2024-04-01</lastmod>
<changefreq>daily</changefreq>
<priority>0.9</priority>
</url>
</urlset>
12 changes: 7 additions & 5 deletions WebApp/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ class Index {
catalogs: Catalog[] = [];
webInfo!: WebInfo;
constructor() {
document.addEventListener('DOMContentLoaded', () => this.init());
}

init(){
this.getData();
this.addEvent();
}

getData(): void {
Expand Down Expand Up @@ -184,8 +190,4 @@ class Index {
}
}

const index = new Index();
document.addEventListener('DOMContentLoaded', function () {
index.getData();
index.addEvent();
});
new Index();
75 changes: 75 additions & 0 deletions WebApp/ts/markdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// @ts-ignore
const mermaid = window.mermaid;
// @ts-ignore
const nomnoml = window.nomnoml;


class MarkdownHandler {
private copyContent: string = '&#128203;copy code';

constructor() {
document.addEventListener('DOMContentLoaded', () => this.init());
}

private init(): void {
this.initMermaid();
this.initCodeCopy();
this.initNomnoml();
}

private initMermaid(): void {

if (typeof mermaid !== 'undefined') {
mermaid.initialize({ startOnLoad: true });
}
}

private initCodeCopy(): void {
const languageDivs = document.querySelectorAll('div[class^="language-"]');
languageDivs.forEach(languageDiv => this.addCopyIcon(languageDiv));
}

private addCopyIcon(languageDiv: Element): void {
const language = languageDiv.className.split(' ')[0].split('-')[1];

const codeActionBar = document.createElement('div');
codeActionBar.classList.add('code-action-bar', 'flex', 'justify-between');

codeActionBar.innerHTML = `<span>${language}</span><span class="copy-icon">${this.copyContent}</span>`;
languageDiv.parentNode!.insertBefore(codeActionBar, languageDiv);

const copyIcon = codeActionBar.querySelector('.copy-icon');
copyIcon!.addEventListener('click', () => this.copyCode(languageDiv, copyIcon));
}

private copyCode(languageDiv: Element, copyIcon: Element | null): void {
const textToCopy = languageDiv.querySelector('pre')!.innerText;
navigator.clipboard.writeText(textToCopy)
.then(() => {
copyIcon!.innerHTML = '&#10003 copied!';
setTimeout(() => {
copyIcon!.innerHTML = this.copyContent;
}, 1000);
})
.catch(err => {
console.error('Failed to copy: ', err);
});
}

private initNomnoml(): void {
if (typeof nomnoml !== 'undefined') {
var nomnomlDivs = document.querySelectorAll('.nomnoml');
if (nomnomlDivs.length > 0) {
const nomnomlDiv = nomnomlDivs[0];
const content = nomnomlDiv.textContent!;
nomnomlDiv.innerHTML = '';

const canvas = document.createElement('canvas');
nomnoml.draw(canvas, content);
nomnomlDiv.appendChild(canvas);
}
}
}
}

new MarkdownHandler();
Loading

0 comments on commit c6db6b9

Please sign in to comment.