#### What type of PR is this?
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
1. 简化 Snapshot 的指责,去除 Snapshot 中关于 version,publishTime 等与发布相关的东西,Snapshot本身没有发布概念
2. 对应修改文章和自定义页面,将版本的概念转移到拥有 Snapshot 的模型上,如 Post 和 SinglePage
⚠️此 PR 为破坏性更新,对旧数据不兼容,可能导致旧数据文章内容无法显示问题
Console 端需要做出一些修改:
- 将文章发布前调用保存内容的 API 修改为 `/posts/{name}/content`
- 将自定义页面发布前调用保存内容的 API 修改为 `/singlepages/{name}/content`
发布接口提供了一个 `async` 参数,默认值为 `false`此时发布API需要等待发布成功后才返回结果,如果等待超时则提示`Publishing wait timeout.`, 如果传递 `async=true` 表示异步发布,更新完数据就成功,reconciler 在后台慢慢执行。
#### Special notes for your reviewer:
how to test it?
1. 新创建一篇文章,测试点击保存是否成功
2. 新创建一篇文章,测试编辑内容后直接发布是否成功
3. 测试发布过的文章的取消发布状态是否显示未发布状态
4. 对于 Snapshot,新建文章点保存会创建一个snapshot,点击发布则是更新之前点保存创建的一条,所以记录数不会多,发布之后进入编辑随便写点内容直接点发布后查询snapshot则会多一条记录。
5. 文章的 status 里的 conditions 最新添加的都在第一个即头插入,如果连续两次发布则不会在增加 condition,长度超过20条会把旧的 condition 删除掉
6. 自定义页面上同
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
Action Required: 简化 Snapshot 模型的职责,去除版本相关属性
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
优化文章和自定义页面的保存内容和发布逻辑。详情可查阅:https://github.com/halo-dev/halo/pull/2709
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
测试流程:
1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/2709 分支。
2. 测试文章和自定义页面的新建、更新内容,以及发布。
#### Does this PR introduce a user-facing change?
```release-note
优化文章和自定义页面的保存内容和发布逻辑。
```
#### What type of PR is this?
/kind bug
/kind regression
/area core
/milestone 2.0
#### What this PR does / why we need it:
When we try to upgrade a theme, error will appear like below:
```java
2022-11-18T15:45:35.130+08:00 ERROR 18136 --- [oundedElastic-1] a.w.r.e.AbstractErrorWebExceptionHandler : [26de12d5-51] 500 Server Error for HTTP POST "/apis/api.console.halo.run/v1alpha1/themes/theme-earth/upgrade"
java.io.IOException: Pipe closed
at java.base/java.io.PipedInputStream.read(PipedInputStream.java:307) ~[na:na]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Assembly trace from producer [reactor.core.publisher.MonoFlatMap] :
reactor.core.publisher.Mono.flatMap(Mono.java:3080)
run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:72)
Error has been observed at the following site(s):
*____________Mono.flatMap ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:72)
|_ Mono.doOnNext ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:82)
|_ Mono.map ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:88)
|_ Mono.doOnNext ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:89)
|_ Mono.flatMap ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:98)
|_ Mono.doOnNext ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:103)
|_ Mono.flatMap ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:112)
|_ Mono.doFinally ⇢ at run.halo.app.core.extension.theme.ThemeServiceImpl.upgrade(ThemeServiceImpl.java:113)
*____________Mono.flatMap ⇢ at run.halo.app.core.extension.theme.ThemeEndpoint.upgrade(ThemeEndpoint.java:180)
|_ Mono.flatMap ⇢ at run.halo.app.core.extension.theme.ThemeEndpoint.upgrade(ThemeEndpoint.java:187)
```
This might be caused by PR <https://github.com/halo-dev/halo/pull/2704>.
#### Special notes for your reviewer:
Steps to test:
1. Upgrade any theme
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
This PR enables adding more workers for controller to speed up reconciliations. Default woker count is 1 for one controller.
**What's next?**
- [ ] Enable configuring worker count for every controller in configuration properties.
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/2708
#### Special notes for reviewers
You can see there are more threads for post controller in the following screenshot:

#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/milestone 2.0
#### What this PR does / why we need it:
支持删除附件分组和存储策略。
删除策略的逻辑为:删除前会根据策略查询附件,如果有附件,则无法删除,否则可以删除。
删除附件的逻辑为:
1. 选择`删除并将附件移动至未分组`时,会在前端批量调用更新附件的接口,将所有附件的 `groupRef` 置空。
2. 选择`删除并同时删除附件`时,会在前端批量调用删除附件接口。
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/2706
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
测试方式:
1. 需要执行 `pnpm build:packages`
2. 创建若干存储策略,并在部分存储策略中上传附件,再对存储策略做删除处理,需要满足以下情况:
1. 已包含附件的策略会提示不允许删除。
2. 未包含附件的策略可以删除
3. 创建若干分组,并在部分分组中上传附件,再对分组做删除处理,需要满足以下情况:
1. 选择`删除并将附件移动至未分组`时,检查分组是否被删除,且里面的附件是否已经被移动到未分组。
2. 选择`删除并同时删除附件`时,检查分组是否被删除,且里面的附件是否被删除。
#### Does this PR introduce a user-facing change?
<!--
如果当前 Pull Request 的修改不会造成用户侧的任何变更,在 `release-note` 代码块儿中填写 `NONE`。
否则请填写用户侧能够理解的 Release Note。如果当前 Pull Request 包含破坏性更新(Break Change),
Release Note 需要以 `action required` 开头。
If no, just write "NONE" in the release-note block below.
If yes, a release note is required:
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
-->
```release-note
支持删除附件分组和存储策略。
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
主题和插件支持获取 `halo.external-url` 配置信息
#### Which issue(s) this PR fixes:
Fixes#2711
#### Special notes for your reviewer:
how to test it?
1. 在主题中使用`<p th:text="${site.url}"></p>` 可以正确显示
2. 在插件中可以依赖注入 ExternalUrlSupplier
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
主题和插件支持获取外部访问地址配置
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
使用 metadata.generateName 代替 uuid 为 metadata.name 生成值。
Ref https://github.com/halo-dev/halo/pull/2563
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
测试方式:
1. 需要 `pnpm install`
2. 测试登录以及所有需要创建更新资源的业务模块。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.0
#### What this PR does / why we need it:
修复上一个 PR 没有拉取最新代码合并后导致无法构建的问题
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/milestone 2.0
#### What this PR does / why we need it:
附件管理支持排序筛选,适配:https://github.com/halo-dev/halo/pull/2705
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/2627
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
测试方式:
1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/2705 分支。
2. Console 需要 `pnpm install`
3. 上传若干附件,检查排序筛选之后的结果是否符合预期。
#### Does this PR introduce a user-facing change?
```release-note
附件管理支持排序筛选
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.0
#### What this PR does / why we need it:
将所有 Finder 的返回值都修改为 Mono 或 Flux
#### Which issue(s) this PR fixes:
Fixes#2671
#### Special notes for your reviewer:
how to test it?
切换几个主题都点一下,没有报错即为正常
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
主题端 Finder 支持 Reactive API
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
更新所有依赖的修订版本。
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
#### Does this PR introduce a user-facing change?
```release-note
更新所有依赖的修订版本。
```
#### What type of PR is this?
/kind bug
/area core
#### What this PR does / why we need it:
Before this, `CounterMeterHandler#stop` will encounter an error when Halo is graceful shutdown due to database closed before.
```java
2022-11-16T15:52:17.904+08:00 DEBUG 21324 --- [ionShutdownHook] r.halo.app.metrics.CounterMeterHandler : Persist counter meters to database before destroy...
2022-11-16T15:52:17.910+08:00 ERROR 21324 --- [ionShutdownHook] r.halo.app.metrics.CounterMeterHandler : Persist counter meters to database failed.
org.springframework.dao.DataAccessResourceFailureException: Failed to obtain R2DBC Connection
at org.springframework.r2dbc.connection.ConnectionFactoryUtils.lambda$getConnection$0(ConnectionFactoryUtils.java:88) ~[spring-r2dbc-6.0.0-RC4.jar:6.0.0-RC4]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
```
#### Special notes for your reviewer:
Steps to test:
1. Start Halo and then stop it
2. See the log detail
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.0
#### What this PR does / why we need it:
1. Initialize default theme when we detect the theme root has no themes here. This process won't stop Halo starting up if error occurs.
2. Refactor ThemeEndpoint with ThemeService to make it reusable.
Default theme configuration is as following:
```yaml
halo:
theme:
initializer:
disabled: false
location: classpath:themes/theme-earth.zip
```
#### Which issue(s) this PR fixes:
Fixes https://github.com/halo-dev/halo/issues/2700
#### Special notes for your reviewer:
Steps to test:
1. Delete all themes at console if installed
2. Restart Halo and check the log
4. Check the theme root folder `~/halo-next/themes`
5. Try to access index page and you will see the default theme
#### Does this PR introduce a user-facing change?
```release-note
在首次启动 Halo 时初始化默认主题
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.0
#### What this PR does / why we need it:
This PR refines the role template of posts to allow post managers to unpublish and recycle a specific post.
Before that, post managers will be forbidden to unpublishing and recycling posts. You can see the screenshot below:

After that, we can unpublish and recycle posts successfully. You can see the screenshot below:

#### Special notes for your reviewer:
Steps to test manually:
1. Create a `Role` with `Posts Management` permission
2. Create an `User` with the role bound
3. Login with the `User`
4. Create a `Post` and publish it
5. Unpublish the post and Recycle it
#### Does this PR introduce a user-facing change?
```release-note
修复无法“取消发布”和“删除”文章的错误
```
#### What type of PR is this?
/kind documentation
#### What this PR does / why we need it:
1. 更新 2.0.0 的版本号。
2. 更新文档的版本号描述。
3. 更新标语。
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
发布 Console 2.0.0-beta.1
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.0
#### What this PR does / why we need it:
This PR mainly implement full-text search of posts and provide extension point for other search engine.
Meanwhile, I implement ExtensionGetter to get implemention(s) of extension point from system ConfigMap.
But there still are something to do here:
- [x] Udpate documents when posts are published or posts are becoming unpublic.
- [x] Delete documents when posts are unpublished or deleted.
Because I'm waiting for https://github.com/halo-dev/halo/pull/2659 got merged.
I create two endpoints:
1. For full-text search of post
```bash
curl -X 'GET' \
'http://localhost:8090/apis/api.halo.run/v1alpha1/indices/post?keyword=halo&limit=10000&highlightPreTag=%3CB%3E&highlightPostTag=%3C%2FB%3E' \
-H 'accept: */*'
```
1. For refreshing indices
```bash
curl -X 'POST' \
'http://localhost:8090/apis/api.console.halo.run/v1alpha1/indices/post' \
-H 'accept: */*' \
-d ''
```
#### Which issue(s) this PR fixes:
Fixes #https://github.com/halo-dev/halo/issues/2637
#### Special notes for your reviewer:
#### Does this PR introduce a user-facing change?
```release-note
提供文章全文搜索功能并支持搜索引擎扩展
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
重构文章发布/取消发布/放入回收站的逻辑。适配 https://github.com/halo-dev/halo/pull/2675
#### Special notes for your reviewer:
测试方式:
1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/2675 的分支。
2. Console 需要 `pnpm install`。
3. 测试文章发布/取消发布/放入回收站。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
Bump Spring Boot to 3.0.0-RC2.
See https://github.com/spring-projects/spring-boot/releases/tag/v3.0.0-RC2 for more.
#### Does this PR introduce a user-facing change?
```release-note
升级 Spring Boot 至 3.0.0-RC2
```
#### What type of PR is this?
/kind feature
/milestone 2.0
/area core
#### What this PR does / why we need it:
主题端提供判断插件是否已经启用的方法
#### Which issue(s) this PR fixes:
Fixes#2677
#### Special notes for your reviewer:
how to test it?
在主题端使用 `${pluginFinder.available(your-plugin-name)}` 来查看某个插件是否已经启用,如果是则得到 true ,否则 false,如果插件没有安装也得到 false
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
主题端支持获取插件启用状态
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
重构文章和自定义页面的发布流程。
Ref https://github.com/halo-dev/halo/pull/2659
1. 修改文章、自定义页面标识发布状态的字段名。
2. 修改初始化页面中创建文章和自定义页面的逻辑,取消使用发布接口,改为直接将 `spec.publish` 设置为 `true`
3. 列表支持检测发布状态。
#### Special notes for your reviewer:
测试方式:
1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/2659 分支。
2. Console 需要 `pnpm install && pnpm build:packages`
3. 测试文章和自定义页面的发布、保存等流程。需要完整测试整个流程。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
/area core
/kind api-change
#### What this PR does / why we need it:
- 通过修改 `spec.publish=true` 且 `spec.releasedSnapshot = spec.headSnapshot` 来实现通过 reconciler 异步发布
- Snapshot 中的 subjectRef 类型改为了 Ref 类型,因为之前的 Snapshot.SubjectRef 只包含了 kind 和 name 可能会冲突
#### Which issue(s) this PR fixes:
Fixes#2650
#### Special notes for your reviewer:
how to test it?
1. 通过 `POST /apis/console.halo.run/v1alpha1/posts` 创建文章并将 `spec.publish=true`,创建后查询可以看到 `spec.baseSnapshot`、`spec.headSnapshot`、`spec.releasedSnapshot` 三个值都相等,且 `status.phase=PUBLISHED`(此过程相当于创建即发布没有保存过程)
2. 先通过 `POST /apis/console.halo.run/v1alpha1/posts` 创建一篇草稿(`spec.publish=false`),在获取它并设置 `spec.publish=true` ,更新后期望文章为发布状态 `spec.headSnapshot`, `spec.releasedSnapshot` 都不等于空且等于 `spec.baseSnapshot`),且 `spec.version=1`(此过程相当于先保存后发布且之前从未发布过)
3. 在步骤2的基础上修改`spec.releasedSnapshot=spec.headSnapshot`并更新,期望 `spec.version=2`且`spec.releasedSnapshot` 对应的 Snapshot 数据具有 publishTime(此过程相当于发布后编辑内容在发布的场景)
4. 自定义页面亦如是
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
重构文章发布以解决创建与发布 API 几乎同时调用时无法成功发布文章的问题
```
#### What type of PR is this?
/kind improvement
#### What this PR does / why we need it:
升级 `@halo-dev/richtext-editor`。重构编辑器的结构,目前可以在外部添加菜单项和指令,意味着可以被扩展。
添加 tiptap 拓展的方式:
```
pnpm install @tiptap/extension-character-count
```
然后在创建 Editor 实例的时候需要将拓展添加到 extensions 数组,如:
```ts
const editor = useEditor({
content: props.modelValue,
extensions: [
...
ExtensionCharacterCount,
],
});
```
最终如果要通过我们的插件机制来拓展编辑器,那么就需要对 extensions 提供可拓展点。
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
重构获取系统初始化状态的方式,之前会在每个路由切换前获取,在一定程度上会导致路由切换时卡顿。此 PR 改为仅在首次加载页面的时候调用接口获取,并保留状态由 pinia 管理。
#### Special notes for your reviewer:
测试方式:
1. 需要使用未初始化的 Halo。
2. 测试在未初始化前是否会自动切换到初始化页面。
3. 测试初始化之后是否还会跳转到初始化页面。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
重构主题预览弹框,支持选择主题以及针对主题进行设置。
todolist:
- [x] 支持保存之后自动刷新预览区域。
- [x] 优化 Tabs 组件,支持横向滚动以解决设置项过多时,选项卡的样式问题。
#### Screenshots:
https://user-images.githubusercontent.com/21301288/200233823-fe317efe-536a-47a9-9495-efdde39be7ca.mp4
#### Special notes for your reviewer:
测试方式:
1. 需要先执行 `pnpm build:packages`
2. 进入主题管理,点击右上角的预览即可打开主题预览窗口
#### Does this PR introduce a user-facing change?
```release-note
重构主题预览弹框,支持选择主题以及针对主题进行设置。
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.0
#### What this PR does / why we need it:
修复日志 while 循环导致 cpu 占用高的问题
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
发布 Halo 2.0 第四个 alpha 版本的 Console 部分。
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/milestone 2.0
#### What this PR does / why we need it:
修复一些因使用不当导致的 Vue warn。
#### Screenshots:
<img width="832" alt="image" src="https://user-images.githubusercontent.com/21301288/199663758-e29f48c4-0c33-4c78-913f-2364ce4b5fbe.png">
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind bug
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
修复 Halo 异常停止时日志服务线程无法中断的问题
#### Special notes for your reviewer:
how to test it?
使用 mysql 启动 halo 但不启动 mysql,此时 halo 会无法链接 mysql
期望现象:Halo 服务终止,异常现象:Halo 抛异常但 Netty 服务器不会停止
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
修复 Halo 异常停止时日志服务线程无法中断的问题
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
插件 logo 支持配置外部 URL 或相对于 resources 的路径
Console 端展示插件 logo 时使用的字段需要使用 status.logo 而非 spec.logo
#### Which issue(s) this PR fixes:
Fixes#2651
#### Special notes for your reviewer:
how to test it?
1. 插件配置 logo 为外部 url 例如 https://guqing.xyz/avatar
2. 安装此插件后不会注册 ReverseProxy 规则
3. logo 配置为相对于 resources 的路径例如:/logo.png
4. 安装此插件后可以访问到 /plugins/{your-plugin-name}/assets/logo.png
5. 开发模式启动插件后,修改了 plugin.yaml 中的 spec.logo 则也会更新 ReverseProxy 的 rule
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
插件 Logo 支持配置外部 URL 或相对于 resources 的路径
```
#### What type of PR is this?
/kind feature
/milestone 2.0
#### What this PR does / why we need it:
支持管理已删除的文章和自定义页面,优化删除的逻辑。
Fixes https://github.com/halo-dev/halo/issues/2647
#### Special notes for your reviewer:
/cc @halo-dev/sig-halo-console
测试方式:
1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/2648
2. 测试文章和自定义页面的删除功能,以及回收站的管理功能。
#### Does this PR introduce a user-facing change?
```release-note
支持管理已删除的文章和自定义页面,优化删除的逻辑。
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
如果配置了 halo.externalUrl 则 permalink 生成时会自动加上 external url
#### Which issue(s) this PR fixes:
Fixes #
#### Special notes for your reviewer:
how to test it?
1. 配置 `halo.externalUrl` 并启动
2. 创建几篇文章、标签、分类、自定义页面
3. console 端能看到访问路径自动带上了 external url 并且通过访问路径能正确访问到相应资源
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
文章/分类/标签的访问路径自动追加外部访问地址
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.0
#### What this PR does / why we need it:
菜单和分类数列表加强健壮性,防止因为 children 字段存在垃圾数据时导致 NPE 问题
#### Which issue(s) this PR fixes:
a part of #2643
#### Special notes for your reviewer:
how to test it?
1. 创建一个层级结构菜单,比如
```
A
|-B
|-C
```
2. 删除菜单 C 然后访问主题端首页不会发生以下异常信息
```
Caused by: java.lang.NullPointerException: Cannot invoke "run.halo.app.theme.finders.vo.MenuItemVo.setParentName(String)" because "childNode" is null
```
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
修复获取菜单和分类列表时会出现 NPE 的问题
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.0
#### What this PR does / why we need it:
修复文章和自定义页面的 labels 在文章标记为删除状态时没有更新的问题
#### Which issue(s) this PR fixes:
A part of #2647
#### Special notes for your reviewer:
how to test it?
1. 创建文章
2. 由于没有发布,此时访问文章的 permalink 访问不到
3. 发布文章,可以正常访问
4. 更新文章的 `spec.deleted=true`,在访问文章期望404,并且 `metadata.labels` 中的数据正确
5. 自定义页面亦如是
/cc @halo-dev/sig-halo
#### Does this PR introduce a user-facing change?
```release-note
None
```