Compare commits

...

3 Commits

Author SHA1 Message Date
AirboZH fb880f776f
Merge f16d73f8b4 into 9b3f00dab0 2024-05-06 18:46:26 +08:00
guqing 9b3f00dab0
fix: extension resources weren't deleted as expected on initialization (#5859)
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.16.x

#### What this PR does / why we need it:
修复初始化时未按预期删除自定义资源

#### Does this PR introduce a user-facing change?
```release-note
修复初始化时未按预期删除自定义资源
```
2024-05-06 08:21:34 +00:00
AirboZH f16d73f8b4
feat: category include childrenCategories 2024-04-23 10:39:05 +08:00
9 changed files with 82 additions and 7 deletions

View File

@ -59,6 +59,8 @@ public class Category extends AbstractExtension {
private Integer priority;
private List<String> children;
private boolean independent;
}
@JsonIgnore

View File

@ -15,6 +15,7 @@ import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.halo.app.extension.ExtensionUtil;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.extension.Unstructured;
import run.halo.app.infra.properties.HaloProperties;
@ -96,7 +97,13 @@ public class ExtensionResourceInitializer implements ApplicationListener<Applica
extension.getMetadata().setVersion(existingExt.getMetadata().getVersion());
return extensionClient.update(extension);
})
.switchIfEmpty(Mono.defer(() -> extensionClient.create(extension)));
.switchIfEmpty(Mono.defer(() -> {
if (ExtensionUtil.isDeleted(extension)) {
// skip deleted extension
return Mono.empty();
}
return extensionClient.create(extension);
}));
}
private List<Resource> listResources(String location) {

View File

@ -1,7 +1,9 @@
package run.halo.app.theme.finders.impl;
import static run.halo.app.extension.index.query.QueryFactory.all;
import static run.halo.app.extension.index.query.QueryFactory.and;
import static run.halo.app.extension.index.query.QueryFactory.equal;
import static run.halo.app.extension.index.query.QueryFactory.or;
import java.util.Comparator;
import java.util.List;
@ -15,12 +17,14 @@ import org.springframework.lang.NonNull;
import org.springframework.util.Assert;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import run.halo.app.core.extension.content.Category;
import run.halo.app.core.extension.content.Post;
import run.halo.app.extension.ListOptions;
import run.halo.app.extension.ListResult;
import run.halo.app.extension.PageRequestImpl;
import run.halo.app.extension.ReactiveExtensionClient;
import run.halo.app.extension.exception.ExtensionNotFoundException;
import run.halo.app.extension.index.query.Query;
import run.halo.app.extension.index.query.QueryFactory;
import run.halo.app.extension.router.selector.FieldSelector;
import run.halo.app.extension.router.selector.LabelSelector;
@ -141,13 +145,45 @@ public class PostFinderImpl implements PostFinder {
@Override
public Mono<ListResult<ListedPostVo>> listByCategory(Integer page, Integer size,
String categoryName) {
var fieldQuery = QueryFactory.all();
if (StringUtils.isNotBlank(categoryName)) {
fieldQuery = and(fieldQuery, equal("spec.categories", categoryName));
}
var listOptions = new ListOptions();
listOptions.setFieldSelector(FieldSelector.of(fieldQuery));
return postPublicQueryService.list(listOptions, getPageRequest(page, size));
var pageRequest = getPageRequest(page, size);
if (StringUtils.isNotBlank(categoryName)) {
return childrenCategoryQuery(categoryName).flatMap(fieldQuery -> {
listOptions.setFieldSelector(FieldSelector.of(fieldQuery));
return postPublicQueryService.list(listOptions, pageRequest);
});
} else {
return postPublicQueryService.list(listOptions, pageRequest);
}
}
private Mono<Query> childrenCategoryQuery(String categoryName) {
if (categoryName == null) {
return Mono.empty();
}
return traverseCategories(categoryName)
.map(childrenCategory -> equal("spec.categories", childrenCategory))
.collect(Collectors.toList())
.flatMap(this::mergeQuery);
}
Mono<Query> mergeQuery(List<Query> childrenQueryList) {
if (childrenQueryList.size() < 2) {
return Mono.just(and(all(), childrenQueryList.get(0)));
}
return Mono.just(
or(childrenQueryList.get(0), childrenQueryList.get(1), childrenQueryList)
);
}
private Flux<String> traverseCategories(String categoryName) {
return client.fetch(Category.class, categoryName).expand(
rootCategory -> Flux.fromIterable(rootCategory.getSpec().getChildren())
.flatMap(childCategory -> client.fetch(Category.class, childCategory)
.filter(category -> !category.getSpec().isIndependent()))
).map(category -> category.getMetadata().getName());
}
@Override

View File

@ -55,6 +55,7 @@ const initialFormState: Category = {
template: "",
priority: 0,
children: [],
isIndependent: false,
},
status: {},
apiVersion: "content.halo.run/v1alpha1",
@ -279,6 +280,17 @@ const { handleGenerateSlug } = useSlugify(
type="select"
name="template"
></FormKit>
<FormKit
v-model="formState.spec.independent"
:label="
$t('core.post_category.editing_modal.fields.independent.label')
"
:help="
$t('core.post_category.editing_modal.fields.independent.help')
"
type="checkbox"
name="includeChildren"
></FormKit>
<FormKit
v-model="formState.spec.cover"
:help="$t('core.post_category.editing_modal.fields.cover.help')"

View File

@ -28,6 +28,12 @@ export interface CategorySpec {
'children'?: Array<string>;
/**
*
* @type {boolean}
* @memberof CategorySpec
*/
'independent'?: boolean;
/**
*
* @type {string}
* @memberof CategorySpec
*/

View File

@ -359,6 +359,9 @@ core:
refresh_message: Regenerate slug based on display name.
template:
label: Custom template
independent:
label: Independent Category
help: Articles and the number of articles will not be counted towards the parent category.
cover:
label: Cover
help: Theme adaptation is required to support

View File

@ -303,6 +303,9 @@ core:
refresh_message: Regenerar slug basado en el nombre para mostrar.
template:
label: Plantilla personalizada
independent:
label: Categoría independiente
help: El número de artículos y artículos no se incluirá en la categoría padre.
cover:
label: Portada
help: Se requiere adaptación del tema para ser compatible

View File

@ -359,6 +359,9 @@ core:
refresh_message: 根据名称重新生成别名
template:
label: 自定义模板
independent:
label: 独立分类
help: 文章和文章数将不计入父级分类
cover:
label: 封面图
help: 需要主题适配以支持

View File

@ -339,6 +339,9 @@ core:
refresh_message: 根據名稱重新生成別名
template:
label: 自定義模板
independent:
label: 獨立分類
help: 文章和文章數將不計入父級分類
cover:
label: 封面圖
help: 需要主題適配以支持