create-halo-plugin-template 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +520 -0
- package/.github/workflows/cd.yaml +20 -0
- package/.github/workflows/ci.yaml +32 -0
- package/.github/workflows/publish-npm.yaml +46 -0
- package/.gitignore +83 -0
- package/LICENSE +674 -0
- package/README.md +191 -0
- package/bin/create-halo-plugin-template.js +3 -0
- package/build.gradle +103 -0
- package/docs/first-npm-release-checklist.md +58 -0
- package/docs/publish-template.md +148 -0
- package/docs/rsbuild-switch.md +90 -0
- package/docs/template-pruning.md +43 -0
- package/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/gradle.properties +1 -0
- package/gradlew +248 -0
- package/gradlew.bat +93 -0
- package/package.json +67 -7
- package/scripts/create-project.mjs +399 -0
- package/scripts/init-template.mjs +281 -0
- package/scripts/publish-check.mjs +97 -0
- package/scripts/release.mjs +278 -0
- package/scripts/verify-template.mjs +407 -0
- package/settings.gradle +7 -0
- package/src/main/java/run/halo/plugintemplate/PluginTemplatePlugin.java +43 -0
- package/src/main/java/run/halo/plugintemplate/config/PluginTemplateConfig.java +14 -0
- package/src/main/java/run/halo/plugintemplate/dto/PluginTemplateChecklistItem.java +30 -0
- package/src/main/java/run/halo/plugintemplate/dto/PluginTemplateFeatureItem.java +30 -0
- package/src/main/java/run/halo/plugintemplate/dto/PluginTemplateOverview.java +73 -0
- package/src/main/java/run/halo/plugintemplate/dto/PluginTemplateStatItem.java +30 -0
- package/src/main/java/run/halo/plugintemplate/endpoint/PluginTemplateConsoleEndpoint.java +33 -0
- package/src/main/java/run/halo/plugintemplate/endpoint/PluginTemplatePublicEndpoint.java +26 -0
- package/src/main/java/run/halo/plugintemplate/endpoint/PluginTemplateUcEndpoint.java +33 -0
- package/src/main/java/run/halo/plugintemplate/endpoint/routes/PluginTemplateOverviewRoutes.java +60 -0
- package/src/main/java/run/halo/plugintemplate/model/PluginTemplateAudience.java +23 -0
- package/src/main/java/run/halo/plugintemplate/query/PluginTemplateOverviewQuery.java +26 -0
- package/src/main/java/run/halo/plugintemplate/reconcile/PluginTemplateSettingsReconciler.java +17 -0
- package/src/main/java/run/halo/plugintemplate/scheme/PluginTemplateRecord.java +43 -0
- package/src/main/java/run/halo/plugintemplate/service/PluginTemplateOverviewService.java +10 -0
- package/src/main/java/run/halo/plugintemplate/service/impl/PluginTemplateOverviewServiceImpl.java +74 -0
- package/src/main/java/run/halo/plugintemplate/setting/PluginTemplateGeneralSetting.java +25 -0
- package/src/main/java/run/halo/plugintemplate/setting/PluginTemplateSettingKeys.java +24 -0
- package/src/main/java/run/halo/plugintemplate/setting/PluginTemplateUiSetting.java +13 -0
- package/src/main/java/run/halo/plugintemplate/utils/PluginTemplateSeeds.java +197 -0
- package/src/main/resources/extensions/roleTemplate-console.yaml +39 -0
- package/src/main/resources/extensions/roleTemplate-uc.yaml +19 -0
- package/src/main/resources/extensions/settings.yaml +47 -0
- package/src/main/resources/logo.png +0 -0
- package/src/main/resources/plugin.yaml +24 -0
- package/src/test/java/run/halo/plugintemplate/PluginTemplatePluginTest.java +34 -0
- package/src/test/java/run/halo/plugintemplate/service/impl/PluginTemplateOverviewServiceImplTest.java +97 -0
- package/ui/build.gradle +41 -0
- package/ui/env.d.ts +2 -0
- package/ui/eslint.config.ts +30 -0
- package/ui/package.json +57 -0
- package/ui/pnpm-lock.yaml +5250 -0
- package/ui/src/api/__tests__/normalizers.spec.ts +65 -0
- package/ui/src/api/generated/.openapi-generator/FILES +23 -0
- package/ui/src/api/generated/.openapi-generator/VERSION +1 -0
- package/ui/src/api/generated/.openapi-generator-ignore +23 -0
- package/ui/src/api/generated/api/plugin-template-console-api.ts +128 -0
- package/ui/src/api/generated/api/plugin-template-uc-api.ts +128 -0
- package/ui/src/api/generated/api.ts +19 -0
- package/ui/src/api/generated/base.ts +86 -0
- package/ui/src/api/generated/common.ts +150 -0
- package/ui/src/api/generated/configuration.ts +110 -0
- package/ui/src/api/generated/git_push.sh +57 -0
- package/ui/src/api/generated/index.ts +18 -0
- package/ui/src/api/generated/models/add-operation.ts +49 -0
- package/ui/src/api/generated/models/copy-operation.ts +49 -0
- package/ui/src/api/generated/models/index.ts +11 -0
- package/ui/src/api/generated/models/json-patch-inner.ts +41 -0
- package/ui/src/api/generated/models/move-operation.ts +49 -0
- package/ui/src/api/generated/models/plugin-template-checklist-item.ts +54 -0
- package/ui/src/api/generated/models/plugin-template-feature-item.ts +54 -0
- package/ui/src/api/generated/models/plugin-template-overview.ts +147 -0
- package/ui/src/api/generated/models/plugin-template-stat-item.ts +54 -0
- package/ui/src/api/generated/models/remove-operation.ts +43 -0
- package/ui/src/api/generated/models/replace-operation.ts +49 -0
- package/ui/src/api/generated/models/test-operation.ts +49 -0
- package/ui/src/api/index.ts +42 -0
- package/ui/src/api/normalizers.ts +65 -0
- package/ui/src/assets/element.scss +24 -0
- package/ui/src/assets/index.css +361 -0
- package/ui/src/assets/logo.svg +1 -0
- package/ui/src/components/PluginTemplateAttachmentTab.vue +69 -0
- package/ui/src/components/PluginTemplateCommonTable.vue +69 -0
- package/ui/src/components/PluginTemplateDashboardWidget.vue +62 -0
- package/ui/src/components/PluginTemplateOverviewPage.vue +254 -0
- package/ui/src/components/ui/PluginUiProvider.vue +40 -0
- package/ui/src/components/ui/UiMetricCard.vue +21 -0
- package/ui/src/components/ui/UiSectionCard.vue +25 -0
- package/ui/src/components/ui/UiStatusPill.vue +18 -0
- package/ui/src/composables/useTemplateOverview.ts +38 -0
- package/ui/src/index.ts +88 -0
- package/ui/src/lib/__tests__/plugin-ui.spec.ts +19 -0
- package/ui/src/lib/plugin-ui.ts +19 -0
- package/ui/src/lib/template.spec.ts +24 -0
- package/ui/src/lib/template.ts +52 -0
- package/ui/src/lib/theme.ts +31 -0
- package/ui/src/types/index.ts +59 -0
- package/ui/src/views/console/ConsoleDashboardView.vue +7 -0
- package/ui/src/views/uc/UcDashboardView.vue +7 -0
- package/ui/tsconfig.app.json +12 -0
- package/ui/tsconfig.json +14 -0
- package/ui/tsconfig.node.json +15 -0
- package/ui/tsconfig.vitest.json +11 -0
- package/ui/vite.config.ts +25 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package run.halo.plugintemplate.endpoint;
|
|
2
|
+
|
|
3
|
+
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
|
|
4
|
+
import org.springframework.web.reactive.function.server.RouterFunction;
|
|
5
|
+
import org.springframework.web.reactive.function.server.ServerResponse;
|
|
6
|
+
import run.halo.app.core.extension.endpoint.CustomEndpoint;
|
|
7
|
+
import run.halo.app.extension.GroupVersion;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Public endpoint placeholder.
|
|
11
|
+
* Add {@code @Component} and real route definitions when the plugin needs a public API surface.
|
|
12
|
+
*/
|
|
13
|
+
public class PluginTemplatePublicEndpoint implements CustomEndpoint {
|
|
14
|
+
|
|
15
|
+
public static final String PUBLIC_GROUP_VERSION = "public.halo-plugin-template.halo.run/v1alpha1";
|
|
16
|
+
|
|
17
|
+
@Override
|
|
18
|
+
public RouterFunction<ServerResponse> endpoint() {
|
|
19
|
+
return SpringdocRouteBuilder.route().build();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@Override
|
|
23
|
+
public GroupVersion groupVersion() {
|
|
24
|
+
return GroupVersion.parseAPIVersion(PUBLIC_GROUP_VERSION);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
package run.halo.plugintemplate.endpoint;
|
|
2
|
+
|
|
3
|
+
import lombok.RequiredArgsConstructor;
|
|
4
|
+
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
|
|
5
|
+
import org.springframework.stereotype.Component;
|
|
6
|
+
import org.springframework.web.reactive.function.server.RequestPredicates;
|
|
7
|
+
import org.springframework.web.reactive.function.server.RouterFunction;
|
|
8
|
+
import org.springframework.web.reactive.function.server.ServerResponse;
|
|
9
|
+
import run.halo.app.core.extension.endpoint.CustomEndpoint;
|
|
10
|
+
import run.halo.app.extension.GroupVersion;
|
|
11
|
+
import run.halo.plugintemplate.endpoint.routes.PluginTemplateOverviewRoutes;
|
|
12
|
+
|
|
13
|
+
@Component
|
|
14
|
+
@RequiredArgsConstructor
|
|
15
|
+
public class PluginTemplateUcEndpoint implements CustomEndpoint {
|
|
16
|
+
|
|
17
|
+
public static final String UC_GROUP_VERSION = "uc.halo-plugin-template.halo.run/v1alpha1";
|
|
18
|
+
public static final String UC_TAG = "PluginTemplateUc";
|
|
19
|
+
|
|
20
|
+
private final PluginTemplateOverviewRoutes overviewRoutes;
|
|
21
|
+
|
|
22
|
+
@Override
|
|
23
|
+
public RouterFunction<ServerResponse> endpoint() {
|
|
24
|
+
return SpringdocRouteBuilder.route()
|
|
25
|
+
.nest(RequestPredicates.path("template-overview"), overviewRoutes::ucRoutes)
|
|
26
|
+
.build();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@Override
|
|
30
|
+
public GroupVersion groupVersion() {
|
|
31
|
+
return GroupVersion.parseAPIVersion(UC_GROUP_VERSION);
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/main/java/run/halo/plugintemplate/endpoint/routes/PluginTemplateOverviewRoutes.java
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
package run.halo.plugintemplate.endpoint.routes;
|
|
2
|
+
|
|
3
|
+
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
|
|
4
|
+
import static run.halo.plugintemplate.endpoint.PluginTemplateConsoleEndpoint.CONSOLE_TAG;
|
|
5
|
+
import static run.halo.plugintemplate.endpoint.PluginTemplateUcEndpoint.UC_TAG;
|
|
6
|
+
|
|
7
|
+
import lombok.RequiredArgsConstructor;
|
|
8
|
+
import org.springdoc.webflux.core.fn.SpringdocRouteBuilder;
|
|
9
|
+
import org.springframework.stereotype.Component;
|
|
10
|
+
import org.springframework.web.reactive.function.server.RouterFunction;
|
|
11
|
+
import org.springframework.web.reactive.function.server.ServerResponse;
|
|
12
|
+
import reactor.core.publisher.Mono;
|
|
13
|
+
import run.halo.plugintemplate.dto.PluginTemplateOverview;
|
|
14
|
+
import run.halo.plugintemplate.model.PluginTemplateAudience;
|
|
15
|
+
import run.halo.plugintemplate.service.PluginTemplateOverviewService;
|
|
16
|
+
|
|
17
|
+
@Component
|
|
18
|
+
@RequiredArgsConstructor
|
|
19
|
+
public class PluginTemplateOverviewRoutes {
|
|
20
|
+
|
|
21
|
+
private final PluginTemplateOverviewService overviewService;
|
|
22
|
+
|
|
23
|
+
public RouterFunction<ServerResponse> consoleRoutes() {
|
|
24
|
+
return buildRoutes(
|
|
25
|
+
PluginTemplateAudience.CONSOLE,
|
|
26
|
+
CONSOLE_TAG,
|
|
27
|
+
"pluginTemplateOverviewForConsole",
|
|
28
|
+
"获取模板在 Console 中的默认能力概览"
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public RouterFunction<ServerResponse> ucRoutes() {
|
|
33
|
+
return buildRoutes(
|
|
34
|
+
PluginTemplateAudience.UC,
|
|
35
|
+
UC_TAG,
|
|
36
|
+
"pluginTemplateOverviewForUc",
|
|
37
|
+
"获取模板在 UC 中的默认能力概览"
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private RouterFunction<ServerResponse> buildRoutes(
|
|
42
|
+
PluginTemplateAudience audience,
|
|
43
|
+
String tag,
|
|
44
|
+
String operationId,
|
|
45
|
+
String description
|
|
46
|
+
) {
|
|
47
|
+
return SpringdocRouteBuilder.route()
|
|
48
|
+
.GET("/summary", request -> summary(audience), builder -> builder
|
|
49
|
+
.operationId(operationId)
|
|
50
|
+
.description(description)
|
|
51
|
+
.tag(tag)
|
|
52
|
+
.response(responseBuilder().implementation(PluginTemplateOverview.class)))
|
|
53
|
+
.build();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private Mono<ServerResponse> summary(PluginTemplateAudience audience) {
|
|
57
|
+
return overviewService.getOverview(audience)
|
|
58
|
+
.flatMap(overview -> ServerResponse.ok().bodyValue(overview));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
package run.halo.plugintemplate.model;
|
|
2
|
+
|
|
3
|
+
public enum PluginTemplateAudience {
|
|
4
|
+
CONSOLE("console", "Console"),
|
|
5
|
+
UC("uc", "User Center"),
|
|
6
|
+
PUBLIC("public", "Public");
|
|
7
|
+
|
|
8
|
+
private final String code;
|
|
9
|
+
private final String label;
|
|
10
|
+
|
|
11
|
+
PluginTemplateAudience(String code, String label) {
|
|
12
|
+
this.code = code;
|
|
13
|
+
this.label = label;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public String getCode() {
|
|
17
|
+
return code;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public String getLabel() {
|
|
21
|
+
return label;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
package run.halo.plugintemplate.query;
|
|
2
|
+
|
|
3
|
+
import io.swagger.v3.oas.annotations.media.Schema;
|
|
4
|
+
import lombok.AllArgsConstructor;
|
|
5
|
+
import lombok.Builder;
|
|
6
|
+
import lombok.Data;
|
|
7
|
+
import lombok.NoArgsConstructor;
|
|
8
|
+
|
|
9
|
+
@Data
|
|
10
|
+
@Builder
|
|
11
|
+
@NoArgsConstructor
|
|
12
|
+
@AllArgsConstructor
|
|
13
|
+
@Schema(name = "PluginTemplateOverviewQuery", description = "模板预留的查询参数对象")
|
|
14
|
+
public class PluginTemplateOverviewQuery {
|
|
15
|
+
|
|
16
|
+
@Schema(description = "关键字")
|
|
17
|
+
private String keyword;
|
|
18
|
+
|
|
19
|
+
@Schema(description = "页码", example = "1")
|
|
20
|
+
@Builder.Default
|
|
21
|
+
private Integer page = 1;
|
|
22
|
+
|
|
23
|
+
@Schema(description = "页大小", example = "10")
|
|
24
|
+
@Builder.Default
|
|
25
|
+
private Integer size = 10;
|
|
26
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package run.halo.plugintemplate.reconcile;
|
|
2
|
+
|
|
3
|
+
import org.slf4j.Logger;
|
|
4
|
+
import org.slf4j.LoggerFactory;
|
|
5
|
+
import org.springframework.stereotype.Component;
|
|
6
|
+
import reactor.core.publisher.Mono;
|
|
7
|
+
|
|
8
|
+
@Component
|
|
9
|
+
public class PluginTemplateSettingsReconciler {
|
|
10
|
+
|
|
11
|
+
private static final Logger log = LoggerFactory.getLogger(PluginTemplateSettingsReconciler.class);
|
|
12
|
+
|
|
13
|
+
public Mono<Void> refresh(String reason) {
|
|
14
|
+
log.debug("Template settings reconciler invoked: {}", reason);
|
|
15
|
+
return Mono.empty();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package run.halo.plugintemplate.scheme;
|
|
2
|
+
|
|
3
|
+
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
|
|
4
|
+
|
|
5
|
+
import io.swagger.v3.oas.annotations.media.Schema;
|
|
6
|
+
import lombok.Data;
|
|
7
|
+
import lombok.EqualsAndHashCode;
|
|
8
|
+
import lombok.ToString;
|
|
9
|
+
import run.halo.app.extension.AbstractExtension;
|
|
10
|
+
import run.halo.app.extension.GVK;
|
|
11
|
+
|
|
12
|
+
@Data
|
|
13
|
+
@EqualsAndHashCode(callSuper = true)
|
|
14
|
+
@ToString(callSuper = true)
|
|
15
|
+
@GVK(
|
|
16
|
+
group = "halo-plugin-template.halo.run",
|
|
17
|
+
version = "v1alpha1",
|
|
18
|
+
kind = "PluginTemplateRecord",
|
|
19
|
+
plural = "pluginTemplateRecords",
|
|
20
|
+
singular = "pluginTemplateRecord"
|
|
21
|
+
)
|
|
22
|
+
public class PluginTemplateRecord extends AbstractExtension {
|
|
23
|
+
|
|
24
|
+
public static final String EXTENSION_NAME_PREFIX = "plugin-template-record-";
|
|
25
|
+
|
|
26
|
+
@Schema(description = "业务主键", requiredMode = REQUIRED)
|
|
27
|
+
private String id;
|
|
28
|
+
|
|
29
|
+
@Schema(description = "标题", requiredMode = REQUIRED)
|
|
30
|
+
private String title;
|
|
31
|
+
|
|
32
|
+
@Schema(description = "描述")
|
|
33
|
+
private String description;
|
|
34
|
+
|
|
35
|
+
@Schema(description = "状态", requiredMode = REQUIRED)
|
|
36
|
+
private String status;
|
|
37
|
+
|
|
38
|
+
@Schema(description = "创建时间")
|
|
39
|
+
private String createTime;
|
|
40
|
+
|
|
41
|
+
@Schema(description = "更新时间")
|
|
42
|
+
private String updateTime;
|
|
43
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
package run.halo.plugintemplate.service;
|
|
2
|
+
|
|
3
|
+
import reactor.core.publisher.Mono;
|
|
4
|
+
import run.halo.plugintemplate.dto.PluginTemplateOverview;
|
|
5
|
+
import run.halo.plugintemplate.model.PluginTemplateAudience;
|
|
6
|
+
|
|
7
|
+
public interface PluginTemplateOverviewService {
|
|
8
|
+
|
|
9
|
+
Mono<PluginTemplateOverview> getOverview(PluginTemplateAudience audience);
|
|
10
|
+
}
|
package/src/main/java/run/halo/plugintemplate/service/impl/PluginTemplateOverviewServiceImpl.java
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
package run.halo.plugintemplate.service.impl;
|
|
2
|
+
|
|
3
|
+
import java.time.Clock;
|
|
4
|
+
import java.time.OffsetDateTime;
|
|
5
|
+
import lombok.RequiredArgsConstructor;
|
|
6
|
+
import org.springframework.stereotype.Service;
|
|
7
|
+
import reactor.core.publisher.Mono;
|
|
8
|
+
import run.halo.app.plugin.ReactiveSettingFetcher;
|
|
9
|
+
import run.halo.plugintemplate.dto.PluginTemplateOverview;
|
|
10
|
+
import run.halo.plugintemplate.model.PluginTemplateAudience;
|
|
11
|
+
import run.halo.plugintemplate.service.PluginTemplateOverviewService;
|
|
12
|
+
import run.halo.plugintemplate.setting.PluginTemplateGeneralSetting;
|
|
13
|
+
import run.halo.plugintemplate.setting.PluginTemplateSettingKeys;
|
|
14
|
+
import run.halo.plugintemplate.setting.PluginTemplateUiSetting;
|
|
15
|
+
import run.halo.plugintemplate.utils.PluginTemplateSeeds;
|
|
16
|
+
|
|
17
|
+
@Service
|
|
18
|
+
@RequiredArgsConstructor
|
|
19
|
+
public class PluginTemplateOverviewServiceImpl implements PluginTemplateOverviewService {
|
|
20
|
+
|
|
21
|
+
private final Clock pluginTemplateClock;
|
|
22
|
+
private final ReactiveSettingFetcher settingFetcher;
|
|
23
|
+
|
|
24
|
+
@Override
|
|
25
|
+
public Mono<PluginTemplateOverview> getOverview(PluginTemplateAudience audience) {
|
|
26
|
+
return Mono.zip(fetchGeneralSetting(), fetchUiSetting())
|
|
27
|
+
.map(tuple -> PluginTemplateSeeds.buildOverview(
|
|
28
|
+
audience,
|
|
29
|
+
tuple.getT1(),
|
|
30
|
+
tuple.getT2(),
|
|
31
|
+
OffsetDateTime.now(pluginTemplateClock).toString()
|
|
32
|
+
));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private Mono<PluginTemplateGeneralSetting> fetchGeneralSetting() {
|
|
36
|
+
return settingFetcher.fetch(PluginTemplateSettingKeys.GENERAL_GROUP, PluginTemplateGeneralSetting.class)
|
|
37
|
+
.map(this::normalizeGeneralSetting)
|
|
38
|
+
.switchIfEmpty(Mono.fromSupplier(PluginTemplateGeneralSetting::new))
|
|
39
|
+
.onErrorReturn(new PluginTemplateGeneralSetting());
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private Mono<PluginTemplateUiSetting> fetchUiSetting() {
|
|
43
|
+
return settingFetcher.fetch(PluginTemplateSettingKeys.UI_GROUP, PluginTemplateUiSetting.class)
|
|
44
|
+
.map(this::normalizeUiSetting)
|
|
45
|
+
.switchIfEmpty(Mono.fromSupplier(PluginTemplateUiSetting::new))
|
|
46
|
+
.onErrorReturn(new PluginTemplateUiSetting());
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private PluginTemplateGeneralSetting normalizeGeneralSetting(PluginTemplateGeneralSetting setting) {
|
|
50
|
+
if (setting.getEnableConsoleDashboard() == null) {
|
|
51
|
+
setting.setEnableConsoleDashboard(PluginTemplateSettingKeys.DEFAULT_ENABLE_CONSOLE_DASHBOARD);
|
|
52
|
+
}
|
|
53
|
+
if (setting.getEnableUcDashboard() == null) {
|
|
54
|
+
setting.setEnableUcDashboard(PluginTemplateSettingKeys.DEFAULT_ENABLE_UC_DASHBOARD);
|
|
55
|
+
}
|
|
56
|
+
if (setting.getEnableAttachmentProvider() == null) {
|
|
57
|
+
setting.setEnableAttachmentProvider(PluginTemplateSettingKeys.DEFAULT_ENABLE_ATTACHMENT_PROVIDER);
|
|
58
|
+
}
|
|
59
|
+
return setting;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private PluginTemplateUiSetting normalizeUiSetting(PluginTemplateUiSetting setting) {
|
|
63
|
+
if (setting.getAccentColor() == null || setting.getAccentColor().isBlank()) {
|
|
64
|
+
setting.setAccentColor(PluginTemplateSettingKeys.DEFAULT_ACCENT_COLOR);
|
|
65
|
+
}
|
|
66
|
+
if (setting.getDensity() == null || setting.getDensity().isBlank()) {
|
|
67
|
+
setting.setDensity(PluginTemplateSettingKeys.DEFAULT_DENSITY);
|
|
68
|
+
}
|
|
69
|
+
if (setting.getSupportLink() == null || setting.getSupportLink().isBlank()) {
|
|
70
|
+
setting.setSupportLink(PluginTemplateSettingKeys.DEFAULT_SUPPORT_LINK);
|
|
71
|
+
}
|
|
72
|
+
return setting;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
package run.halo.plugintemplate.setting;
|
|
2
|
+
|
|
3
|
+
import lombok.Data;
|
|
4
|
+
import lombok.NoArgsConstructor;
|
|
5
|
+
|
|
6
|
+
@Data
|
|
7
|
+
@NoArgsConstructor
|
|
8
|
+
public class PluginTemplateGeneralSetting {
|
|
9
|
+
|
|
10
|
+
private Boolean enableConsoleDashboard = PluginTemplateSettingKeys.DEFAULT_ENABLE_CONSOLE_DASHBOARD;
|
|
11
|
+
private Boolean enableUcDashboard = PluginTemplateSettingKeys.DEFAULT_ENABLE_UC_DASHBOARD;
|
|
12
|
+
private Boolean enableAttachmentProvider = PluginTemplateSettingKeys.DEFAULT_ENABLE_ATTACHMENT_PROVIDER;
|
|
13
|
+
|
|
14
|
+
public boolean isConsoleDashboardEnabled() {
|
|
15
|
+
return !Boolean.FALSE.equals(enableConsoleDashboard);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public boolean isUcDashboardEnabled() {
|
|
19
|
+
return !Boolean.FALSE.equals(enableUcDashboard);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public boolean isAttachmentProviderEnabled() {
|
|
23
|
+
return !Boolean.FALSE.equals(enableAttachmentProvider);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
package run.halo.plugintemplate.setting;
|
|
2
|
+
|
|
3
|
+
public final class PluginTemplateSettingKeys {
|
|
4
|
+
|
|
5
|
+
public static final String PLUGIN_NAME = "halo-plugin-template";
|
|
6
|
+
public static final String DISPLAY_NAME = "Halo Plugin Template";
|
|
7
|
+
public static final String SETTING_NAME = "halo-plugin-template-settings";
|
|
8
|
+
public static final String CONFIG_MAP_NAME = "halo-plugin-template-configmap";
|
|
9
|
+
public static final String CONSOLE_PATH = "/halo-plugin-template";
|
|
10
|
+
public static final String UC_PATH = "/halo-plugin-template";
|
|
11
|
+
public static final String GENERATED_CLIENT_PATH = "ui/src/api/generated";
|
|
12
|
+
public static final String GENERAL_GROUP = "general";
|
|
13
|
+
public static final String UI_GROUP = "ui";
|
|
14
|
+
public static final boolean DEFAULT_ENABLE_CONSOLE_DASHBOARD = true;
|
|
15
|
+
public static final boolean DEFAULT_ENABLE_UC_DASHBOARD = true;
|
|
16
|
+
public static final boolean DEFAULT_ENABLE_ATTACHMENT_PROVIDER = true;
|
|
17
|
+
public static final String DEFAULT_ACCENT_COLOR = "#2457F5";
|
|
18
|
+
public static final String DEFAULT_DENSITY = "balanced";
|
|
19
|
+
public static final String DEFAULT_SUPPORT_LINK =
|
|
20
|
+
"https://docs.halo.run/developer-guide/plugin/introduction";
|
|
21
|
+
|
|
22
|
+
private PluginTemplateSettingKeys() {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
package run.halo.plugintemplate.setting;
|
|
2
|
+
|
|
3
|
+
import lombok.Data;
|
|
4
|
+
import lombok.NoArgsConstructor;
|
|
5
|
+
|
|
6
|
+
@Data
|
|
7
|
+
@NoArgsConstructor
|
|
8
|
+
public class PluginTemplateUiSetting {
|
|
9
|
+
|
|
10
|
+
private String accentColor = PluginTemplateSettingKeys.DEFAULT_ACCENT_COLOR;
|
|
11
|
+
private String density = PluginTemplateSettingKeys.DEFAULT_DENSITY;
|
|
12
|
+
private String supportLink = PluginTemplateSettingKeys.DEFAULT_SUPPORT_LINK;
|
|
13
|
+
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
package run.halo.plugintemplate.utils;
|
|
2
|
+
|
|
3
|
+
import java.util.List;
|
|
4
|
+
import run.halo.plugintemplate.dto.PluginTemplateChecklistItem;
|
|
5
|
+
import run.halo.plugintemplate.dto.PluginTemplateFeatureItem;
|
|
6
|
+
import run.halo.plugintemplate.dto.PluginTemplateOverview;
|
|
7
|
+
import run.halo.plugintemplate.dto.PluginTemplateStatItem;
|
|
8
|
+
import run.halo.plugintemplate.model.PluginTemplateAudience;
|
|
9
|
+
import run.halo.plugintemplate.setting.PluginTemplateGeneralSetting;
|
|
10
|
+
import run.halo.plugintemplate.setting.PluginTemplateSettingKeys;
|
|
11
|
+
import run.halo.plugintemplate.setting.PluginTemplateUiSetting;
|
|
12
|
+
|
|
13
|
+
public final class PluginTemplateSeeds {
|
|
14
|
+
|
|
15
|
+
private PluginTemplateSeeds() {
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public static PluginTemplateOverview buildOverview(
|
|
19
|
+
PluginTemplateAudience audience,
|
|
20
|
+
PluginTemplateGeneralSetting generalSetting,
|
|
21
|
+
PluginTemplateUiSetting uiSetting,
|
|
22
|
+
String generatedAt
|
|
23
|
+
) {
|
|
24
|
+
return PluginTemplateOverview.builder()
|
|
25
|
+
.pluginName(PluginTemplateSettingKeys.PLUGIN_NAME)
|
|
26
|
+
.displayName(PluginTemplateSettingKeys.DISPLAY_NAME)
|
|
27
|
+
.audience(audience.getCode())
|
|
28
|
+
.audienceLabel(audience.getLabel())
|
|
29
|
+
.consolePath(PluginTemplateSettingKeys.CONSOLE_PATH)
|
|
30
|
+
.ucPath(PluginTemplateSettingKeys.UC_PATH)
|
|
31
|
+
.settingName(PluginTemplateSettingKeys.SETTING_NAME)
|
|
32
|
+
.configMapName(PluginTemplateSettingKeys.CONFIG_MAP_NAME)
|
|
33
|
+
.generatedClientPath(PluginTemplateSettingKeys.GENERATED_CLIENT_PATH)
|
|
34
|
+
.generatedAt(generatedAt)
|
|
35
|
+
.enableConsoleDashboard(generalSetting.isConsoleDashboardEnabled())
|
|
36
|
+
.enableUcDashboard(generalSetting.isUcDashboardEnabled())
|
|
37
|
+
.enableAttachmentProvider(generalSetting.isAttachmentProviderEnabled())
|
|
38
|
+
.accentColor(uiSetting.getAccentColor())
|
|
39
|
+
.density(uiSetting.getDensity())
|
|
40
|
+
.supportLink(uiSetting.getSupportLink())
|
|
41
|
+
.stats(defaultStats(generalSetting, uiSetting))
|
|
42
|
+
.features(defaultFeatures(generalSetting, uiSetting))
|
|
43
|
+
.checklist(defaultChecklist(audience, generalSetting))
|
|
44
|
+
.build();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private static List<PluginTemplateStatItem> defaultStats(
|
|
48
|
+
PluginTemplateGeneralSetting generalSetting,
|
|
49
|
+
PluginTemplateUiSetting uiSetting
|
|
50
|
+
) {
|
|
51
|
+
var enabledRoutes = (generalSetting.isConsoleDashboardEnabled() ? 1 : 0)
|
|
52
|
+
+ (generalSetting.isUcDashboardEnabled() ? 1 : 0);
|
|
53
|
+
var enabledExtensionPoints = (generalSetting.isConsoleDashboardEnabled() ? 2 : 0)
|
|
54
|
+
+ (generalSetting.isAttachmentProviderEnabled() ? 1 : 0);
|
|
55
|
+
return List.of(
|
|
56
|
+
PluginTemplateStatItem.builder()
|
|
57
|
+
.key("routes")
|
|
58
|
+
.label("已启用页面")
|
|
59
|
+
.value(String.valueOf(enabledRoutes))
|
|
60
|
+
.helper("Console / UC 入口会根据 settings.yaml 中的开关映射到模板概览。")
|
|
61
|
+
.tone("primary")
|
|
62
|
+
.build(),
|
|
63
|
+
PluginTemplateStatItem.builder()
|
|
64
|
+
.key("extension-points")
|
|
65
|
+
.label("已启用扩展点")
|
|
66
|
+
.value(String.valueOf(enabledExtensionPoints))
|
|
67
|
+
.helper("仪表盘、快速操作和附件选择器状态由插件设置驱动。")
|
|
68
|
+
.tone("success")
|
|
69
|
+
.build(),
|
|
70
|
+
PluginTemplateStatItem.builder()
|
|
71
|
+
.key("ui-density")
|
|
72
|
+
.label("UI 密度")
|
|
73
|
+
.value(uiDensityLabel(uiSetting.getDensity()))
|
|
74
|
+
.helper("PluginUiProvider 会把密度映射到 Element Plus 全局 size。")
|
|
75
|
+
.tone("warning")
|
|
76
|
+
.build()
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private static List<PluginTemplateFeatureItem> defaultFeatures(
|
|
81
|
+
PluginTemplateGeneralSetting generalSetting,
|
|
82
|
+
PluginTemplateUiSetting uiSetting
|
|
83
|
+
) {
|
|
84
|
+
return List.of(
|
|
85
|
+
PluginTemplateFeatureItem.builder()
|
|
86
|
+
.key("console-route")
|
|
87
|
+
.title("Console 路由")
|
|
88
|
+
.area("UI")
|
|
89
|
+
.description("带菜单元数据和权限元数据的后台入口。")
|
|
90
|
+
.enabled(generalSetting.isConsoleDashboardEnabled())
|
|
91
|
+
.build(),
|
|
92
|
+
PluginTemplateFeatureItem.builder()
|
|
93
|
+
.key("uc-route")
|
|
94
|
+
.title("UC 路由")
|
|
95
|
+
.area("UI")
|
|
96
|
+
.description("面向个人中心的共享页面壳子。")
|
|
97
|
+
.enabled(generalSetting.isUcDashboardEnabled())
|
|
98
|
+
.build(),
|
|
99
|
+
PluginTemplateFeatureItem.builder()
|
|
100
|
+
.key("widget")
|
|
101
|
+
.title("仪表盘小部件")
|
|
102
|
+
.area("Extension Point")
|
|
103
|
+
.description("示例小部件直接消费模板概览接口。")
|
|
104
|
+
.enabled(generalSetting.isConsoleDashboardEnabled())
|
|
105
|
+
.build(),
|
|
106
|
+
PluginTemplateFeatureItem.builder()
|
|
107
|
+
.key("quick-action")
|
|
108
|
+
.title("快速操作")
|
|
109
|
+
.area("Extension Point")
|
|
110
|
+
.description("可一键跳转到模板默认 Console 页面。")
|
|
111
|
+
.enabled(generalSetting.isConsoleDashboardEnabled())
|
|
112
|
+
.build(),
|
|
113
|
+
PluginTemplateFeatureItem.builder()
|
|
114
|
+
.key("attachment-tab")
|
|
115
|
+
.title("附件扩展标签页")
|
|
116
|
+
.area("Extension Point")
|
|
117
|
+
.description("示例附件来源,便于按需改造成图库、素材库或外链源。")
|
|
118
|
+
.enabled(generalSetting.isAttachmentProviderEnabled())
|
|
119
|
+
.build(),
|
|
120
|
+
PluginTemplateFeatureItem.builder()
|
|
121
|
+
.key("element-plus")
|
|
122
|
+
.title("Element Plus 包装层")
|
|
123
|
+
.area("UI")
|
|
124
|
+
.description("低层组件集中在 ui/src/components/ui,并由 PluginUiProvider 同步主色和密度。")
|
|
125
|
+
.enabled(true)
|
|
126
|
+
.build(),
|
|
127
|
+
PluginTemplateFeatureItem.builder()
|
|
128
|
+
.key("openapi")
|
|
129
|
+
.title("OpenAPI 生成链路")
|
|
130
|
+
.area("Tooling")
|
|
131
|
+
.description("概览 API 已接到生成客户端,新增接口后只需重新执行 generateApiClient。")
|
|
132
|
+
.enabled(true)
|
|
133
|
+
.build(),
|
|
134
|
+
PluginTemplateFeatureItem.builder()
|
|
135
|
+
.key("theme-settings")
|
|
136
|
+
.title("设置驱动 UI")
|
|
137
|
+
.area("Tooling")
|
|
138
|
+
.description("当前模板会消费设置项中的主色、密度和支持链接。")
|
|
139
|
+
.enabled(true)
|
|
140
|
+
.build()
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private static List<PluginTemplateChecklistItem> defaultChecklist(
|
|
145
|
+
PluginTemplateAudience audience,
|
|
146
|
+
PluginTemplateGeneralSetting generalSetting
|
|
147
|
+
) {
|
|
148
|
+
return List.of(
|
|
149
|
+
PluginTemplateChecklistItem.builder()
|
|
150
|
+
.key("init-script")
|
|
151
|
+
.title("运行初始化脚本")
|
|
152
|
+
.description("先替换插件名、包名、权限前缀和仓库地址,再开始写业务。")
|
|
153
|
+
.audience("all")
|
|
154
|
+
.status("todo")
|
|
155
|
+
.build(),
|
|
156
|
+
PluginTemplateChecklistItem.builder()
|
|
157
|
+
.key("settings")
|
|
158
|
+
.title("调整 settings.yaml")
|
|
159
|
+
.description("只保留当前插件真实需要的配置项和表单分组。")
|
|
160
|
+
.audience("all")
|
|
161
|
+
.status("recommended")
|
|
162
|
+
.build(),
|
|
163
|
+
PluginTemplateChecklistItem.builder()
|
|
164
|
+
.key("api-client")
|
|
165
|
+
.title("生成前端 API 客户端")
|
|
166
|
+
.description("补充接口后执行 ./gradlew generateApiClient,再在 ui/src/api/index.ts 暴露新增能力。")
|
|
167
|
+
.audience("console")
|
|
168
|
+
.status("recommended")
|
|
169
|
+
.build(),
|
|
170
|
+
PluginTemplateChecklistItem.builder()
|
|
171
|
+
.key("uc-scope")
|
|
172
|
+
.title("确认 UC 暴露面")
|
|
173
|
+
.description("如果插件不需要 UC,可移除 ucRoutes 和对应 role 模板。")
|
|
174
|
+
.audience("uc")
|
|
175
|
+
.status(resolveUcStatus(audience, generalSetting))
|
|
176
|
+
.build()
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private static String resolveUcStatus(
|
|
181
|
+
PluginTemplateAudience audience,
|
|
182
|
+
PluginTemplateGeneralSetting generalSetting
|
|
183
|
+
) {
|
|
184
|
+
if (!generalSetting.isUcDashboardEnabled()) {
|
|
185
|
+
return "optional";
|
|
186
|
+
}
|
|
187
|
+
return audience == PluginTemplateAudience.UC ? "now" : "recommended";
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private static String uiDensityLabel(String density) {
|
|
191
|
+
return switch (density) {
|
|
192
|
+
case "compact" -> "紧凑";
|
|
193
|
+
case "relaxed" -> "宽松";
|
|
194
|
+
default -> "平衡";
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
kind: Role
|
|
2
|
+
apiVersion: v1alpha1
|
|
3
|
+
metadata:
|
|
4
|
+
name: rt-console.halo-plugin-template.halo.run-view
|
|
5
|
+
labels:
|
|
6
|
+
halo.run/role-template: "true"
|
|
7
|
+
annotations:
|
|
8
|
+
rbac.authorization.halo.run/ui-permissions: |
|
|
9
|
+
["plugin:halo-plugin-template:view"]
|
|
10
|
+
rbac.authorization.halo.run/display-name: "Halo 插件模板查看权限"
|
|
11
|
+
rbac.authorization.halo.run/module: "Halo 插件模板"
|
|
12
|
+
rules:
|
|
13
|
+
- apiGroups:
|
|
14
|
+
- console.halo-plugin-template.halo.run
|
|
15
|
+
resources:
|
|
16
|
+
- template-overview
|
|
17
|
+
verbs:
|
|
18
|
+
- get
|
|
19
|
+
- list
|
|
20
|
+
---
|
|
21
|
+
kind: Role
|
|
22
|
+
apiVersion: v1alpha1
|
|
23
|
+
metadata:
|
|
24
|
+
name: rt-console.halo-plugin-template.halo.run-manage
|
|
25
|
+
labels:
|
|
26
|
+
halo.run/role-template: "true"
|
|
27
|
+
annotations:
|
|
28
|
+
rbac.authorization.halo.run/ui-permissions: |
|
|
29
|
+
["plugin:halo-plugin-template:manage"]
|
|
30
|
+
rbac.authorization.halo.run/display-name: "Halo 插件模板管理权限"
|
|
31
|
+
rbac.authorization.halo.run/module: "Halo 插件模板"
|
|
32
|
+
rules:
|
|
33
|
+
- apiGroups:
|
|
34
|
+
- console.halo-plugin-template.halo.run
|
|
35
|
+
resources:
|
|
36
|
+
- template-overview
|
|
37
|
+
verbs:
|
|
38
|
+
- get
|
|
39
|
+
- list
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
kind: Role
|
|
2
|
+
apiVersion: v1alpha1
|
|
3
|
+
metadata:
|
|
4
|
+
name: rt-uc.halo-plugin-template.halo.run-personal
|
|
5
|
+
labels:
|
|
6
|
+
halo.run/role-template: "true"
|
|
7
|
+
annotations:
|
|
8
|
+
rbac.authorization.halo.run/ui-permissions: |
|
|
9
|
+
["plugin:halo-plugin-template:uc"]
|
|
10
|
+
rbac.authorization.halo.run/display-name: "Halo 插件模板 UC 权限"
|
|
11
|
+
rbac.authorization.halo.run/module: "Halo 插件模板"
|
|
12
|
+
rules:
|
|
13
|
+
- apiGroups:
|
|
14
|
+
- uc.halo-plugin-template.halo.run
|
|
15
|
+
resources:
|
|
16
|
+
- template-overview
|
|
17
|
+
verbs:
|
|
18
|
+
- get
|
|
19
|
+
- list
|