From ccfe72a0d99eaa2f85282db145e34f3a3f25e327 Mon Sep 17 00:00:00 2001 From: xiaojunnuo Date: Sun, 13 Oct 2024 01:27:08 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20plugin=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/pipeline/src/core/executor.ts | 18 +- packages/core/pipeline/src/plugin/api.ts | 6 +- .../core/pipeline/src/plugin/decorator.ts | 6 +- packages/core/pipeline/src/service/config.ts | 9 +- packages/core/pipeline/src/service/index.ts | 1 + .../lib-server/src/basic/crud-controller.ts | 31 +-- .../src/router/source/modules/sys.ts | 28 +++ .../access/access-selector/access/crud.tsx | 11 +- .../access/access-selector/access/index.vue | 8 +- .../certd/access/access-selector/index.vue | 9 +- .../src/views/certd/access/api.ts | 102 +++++----- .../src/views/certd/access/common.tsx | 17 +- .../src/views/certd/access/crud.tsx | 6 +- .../src/views/certd/access/index.vue | 4 +- .../src/views/sys/access/index.vue | 36 ++++ .../certd-client/src/views/sys/plugin/api.ts | 59 ++++++ .../src/views/sys/plugin/crud.tsx | 180 ++++++++++++++++++ .../src/views/sys/plugin/index.vue | 51 +++++ .../db/migration/v10010__plugin.sql | 18 ++ packages/ui/certd-server/db/readme.md | 24 +-- .../pipeline/controller/access-controller.ts | 16 +- .../pipeline/controller/plugin-controller.ts | 28 --- .../pipeline/service/pipeline-service.ts | 5 + .../pipeline/service/plugin-config-service.ts | 13 ++ .../pipeline/service/plugin-service.ts | 3 +- .../modules/sys/access/access-controller.ts | 62 ++++++ .../plugin/controller/plugin-controller.ts | 68 +++++++ .../src/modules/sys/plugin/entity/plugin.ts | 50 +++++ .../sys/plugin/service/plugin-service.ts | 23 +++ 29 files changed, 729 insertions(+), 163 deletions(-) create mode 100644 packages/ui/certd-client/src/views/sys/access/index.vue create mode 100644 packages/ui/certd-client/src/views/sys/plugin/api.ts create mode 100644 packages/ui/certd-client/src/views/sys/plugin/crud.tsx create mode 100644 packages/ui/certd-client/src/views/sys/plugin/index.vue create mode 100644 packages/ui/certd-server/db/migration/v10010__plugin.sql delete mode 100644 packages/ui/certd-server/src/modules/pipeline/controller/plugin-controller.ts create mode 100644 packages/ui/certd-server/src/modules/pipeline/service/plugin-config-service.ts create mode 100644 packages/ui/certd-server/src/modules/sys/access/access-controller.ts create mode 100644 packages/ui/certd-server/src/modules/sys/plugin/controller/plugin-controller.ts create mode 100644 packages/ui/certd-server/src/modules/sys/plugin/entity/plugin.ts create mode 100644 packages/ui/certd-server/src/modules/sys/plugin/service/plugin-service.ts diff --git a/packages/core/pipeline/src/core/executor.ts b/packages/core/pipeline/src/core/executor.ts index 1d2f5075..2d7edfc4 100644 --- a/packages/core/pipeline/src/core/executor.ts +++ b/packages/core/pipeline/src/core/executor.ts @@ -1,18 +1,16 @@ import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js"; -import _ from "lodash-es"; import { RunHistory, RunnableCollection } from "./run-history.js"; import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js"; import { ContextFactory, IContext } from "./context.js"; import { IStorage } from "./storage.js"; -import { logger } from "../utils/index.js"; +import { createAxiosService, hashUtils, logger, utils } from "../utils/index.js"; import { Logger } from "log4js"; -import { createAxiosService } from "../utils/index.js"; import { IAccessService } from "../access/index.js"; import { RegistryItem } from "../registry/index.js"; import { Decorator } from "../decorator/index.js"; -import { ICnameProxyService, IEmailService } from "../service/index.js"; +import { ICnameProxyService, IEmailService, IPluginConfigService } from "../service/index.js"; import { FileStore } from "./file-store.js"; -import { hashUtils, utils } from "../utils/index.js"; +import { cloneDeep, forEach, merge } from "lodash-es"; export type ExecutorOptions = { pipeline: Pipeline; @@ -21,6 +19,7 @@ export type ExecutorOptions = { accessService: IAccessService; emailService: IEmailService; cnameProxyService: ICnameProxyService; + pluginConfigService: IPluginConfigService; fileRootDir?: string; user: UserInfo; }; @@ -42,7 +41,7 @@ export class Executor { onChanged: (history: RunHistory) => Promise; constructor(options: ExecutorOptions) { this.options = options; - this.pipeline = _.cloneDeep(options.pipeline); + this.pipeline = cloneDeep(options.pipeline); this.onChanged = async (history: RunHistory) => { await options.onChanged(history); }; @@ -219,7 +218,7 @@ export class Executor { // @ts-ignore const define: PluginDefine = plugin.define; //从outputContext读取输入参数 - const input = _.cloneDeep(step.input); + const input = cloneDeep(step.input); Decorator.inject(define.input, instance, input, (item, key) => { if (item.component?.name === "output-selector") { const contextKey = input[key]; @@ -269,6 +268,7 @@ export class Executor { accessService: this.options.accessService, emailService: this.options.emailService, cnameProxyService: this.options.cnameProxyService, + pluginConfigService: this.options.pluginConfigService, pipelineContext: this.pipelineContext, userContext: this.contextFactory.getContext("user", this.options.user.id), fileStore: new FileStore({ @@ -290,7 +290,7 @@ export class Executor { this.lastStatusMap.clear(); } //输出上下文变量到output context - _.forEach(define.output, (item: any, key: any) => { + forEach(define.output, (item: any, key: any) => { step.status!.output[key] = instance[key]; // const stepOutputKey = `step.${step.id}.${key}`; // this.runtime.context[stepOutputKey] = instance[key]; @@ -300,7 +300,7 @@ export class Executor { if (Object.keys(instance._result.pipelineVars).length > 0) { // 判断 pipelineVars 有值时更新 const vars = this.pipelineContext.getObj("vars"); - _.merge(vars, instance._result.pipelineVars); + merge(vars, instance._result.pipelineVars); await this.pipelineContext.setObj("vars", vars); } } diff --git a/packages/core/pipeline/src/plugin/api.ts b/packages/core/pipeline/src/plugin/api.ts index d41f14a1..8e9b1484 100644 --- a/packages/core/pipeline/src/plugin/api.ts +++ b/packages/core/pipeline/src/plugin/api.ts @@ -8,8 +8,8 @@ import { IContext, PluginRequestHandleReq, RunnableCollection } from "../core/in import { ILogger, logger, utils } from "../utils/index.js"; import { HttpClient } from "../utils/index.js"; import dayjs from "dayjs"; -import _ from "lodash-es"; import { IPluginConfigService } from "../service/config"; +import { upperFirst } from "lodash-es"; export type UserInfo = { role: "admin" | "user"; id: any; @@ -74,7 +74,7 @@ export type TaskInstanceContext = { //cname记录服务 cnameProxyService: ICnameProxyService; //插件配置服务 - configService: IPluginConfigService; + pluginConfigService: IPluginConfigService; //流水线上下文 pipelineContext: IContext; //用户上下文 @@ -172,7 +172,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin { let methodName = req.action; if (!req.action.startsWith("on")) { - methodName = `on${_.upperFirst(req.action)}`; + methodName = `on${upperFirst(req.action)}`; } // @ts-ignore diff --git a/packages/core/pipeline/src/plugin/decorator.ts b/packages/core/pipeline/src/plugin/decorator.ts index be2510a9..442dbc2c 100644 --- a/packages/core/pipeline/src/plugin/decorator.ts +++ b/packages/core/pipeline/src/plugin/decorator.ts @@ -1,9 +1,9 @@ -import _ from "lodash-es"; import { pluginRegistry } from "./registry.js"; import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js"; import { Decorator } from "../decorator/index.js"; import { AUTOWIRE_KEY } from "../decorator/index.js"; import "reflect-metadata"; +import { merge, sortBy } from "lodash-es"; // 提供一个唯一 key export const PLUGIN_CLASS_KEY = "pipeline:plugin"; @@ -42,13 +42,13 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator { } inputArray.push([key, _input]); } - inputArray = _.sortBy(inputArray, (item: any) => item[1].order); + inputArray = sortBy(inputArray, (item: any) => item[1].order); const inputMap: any = {}; inputArray.forEach((item: any) => { inputMap[item[0]] = item[1]; }); - _.merge(define, { input: inputMap, autowire: autowires, output: outputs }); + merge(define, { input: inputMap, autowire: autowires, output: outputs }); Reflect.defineMetadata(PLUGIN_CLASS_KEY, define, target); diff --git a/packages/core/pipeline/src/service/config.ts b/packages/core/pipeline/src/service/config.ts index 10356532..6ac929fe 100644 --- a/packages/core/pipeline/src/service/config.ts +++ b/packages/core/pipeline/src/service/config.ts @@ -1,9 +1,8 @@ -import { FormItemProps } from "../d.ts/index.js"; - export type PluginConfig = { - show: false; - sysInput: { - [key: string]: {}; + name: string; + disabled: boolean; + sysSetting: { + [key: string]: any; }; }; diff --git a/packages/core/pipeline/src/service/index.ts b/packages/core/pipeline/src/service/index.ts index bee36485..ae0b4281 100644 --- a/packages/core/pipeline/src/service/index.ts +++ b/packages/core/pipeline/src/service/index.ts @@ -1,2 +1,3 @@ export * from "./email.js"; export * from "./cname.js"; +export * from "./config.js"; diff --git a/packages/libs/lib-server/src/basic/crud-controller.ts b/packages/libs/lib-server/src/basic/crud-controller.ts index 7a4fc964..9d1c58fa 100644 --- a/packages/libs/lib-server/src/basic/crud-controller.ts +++ b/packages/libs/lib-server/src/basic/crud-controller.ts @@ -2,59 +2,42 @@ import { ALL, Body, Post, Query } from '@midwayjs/core'; import { BaseController } from './base-controller.js'; export abstract class CrudController extends BaseController { + // eslint-disable-next-line @typescript-eslint/no-unused-vars abstract getService(); @Post('/page') - async page( - @Body(ALL) - body - ) { + async page(@Body(ALL) body: any) { const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, null); return this.ok(pageRet); } @Post('/list') - async list( - @Body(ALL) - body - ) { + async list(@Body(ALL) body: any) { const listRet = await this.getService().list(body, null, null); return this.ok(listRet); } @Post('/add') - async add( - @Body(ALL) - bean - ) { + async add(@Body(ALL) bean: any) { delete bean.id; const id = await this.getService().add(bean); return this.ok(id); } @Post('/info') - async info( - @Query('id') - id - ) { + async info(@Query('id') id: number) { const bean = await this.getService().info(id); return this.ok(bean); } @Post('/update') - async update( - @Body(ALL) - bean - ) { + async update(@Body(ALL) bean: any) { await this.getService().update(bean); return this.ok(null); } @Post('/delete') - async delete( - @Query('id') - id - ) { + async delete(@Query('id') id: number) { await this.getService().delete([id]); return this.ok(null); } diff --git a/packages/ui/certd-client/src/router/source/modules/sys.ts b/packages/ui/certd-client/src/router/source/modules/sys.ts index 6555e4b0..517be413 100644 --- a/packages/ui/certd-client/src/router/source/modules/sys.ts +++ b/packages/ui/certd-client/src/router/source/modules/sys.ts @@ -68,6 +68,34 @@ export const sysResources = [ permission: "sys:settings:view" } }, + { + title: "系统级授权", + name: "SysAccess", + path: "/sys/access", + component: "/sys/access/index.vue", + meta: { + show: () => { + const settingStore = useSettingStore(); + return settingStore.isComm; + }, + icon: "ion:disc-outline", + permission: "sys:settings:view" + } + }, + { + title: "插件管理", + name: "SysPlugin", + path: "/sys/plugin", + component: "/sys/plugin/index.vue", + meta: { + show: () => { + const settingStore = useSettingStore(); + return settingStore.isComm; + }, + icon: "ion:extension-puzzle-outline", + permission: "sys:settings:view" + } + }, { title: "账号绑定", name: "AccountBind", diff --git a/packages/ui/certd-client/src/views/certd/access/access-selector/access/crud.tsx b/packages/ui/certd-client/src/views/certd/access/access-selector/access/crud.tsx index 73c16273..eed3459e 100644 --- a/packages/ui/certd-client/src/views/certd/access/access-selector/access/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/access/access-selector/access/crud.tsx @@ -1,5 +1,4 @@ // @ts-ignore -import * as api from "/@/views/certd/access/api"; import { ref } from "vue"; import { getCommonColumnDefine } from "/@/views/certd/access/common"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; @@ -9,25 +8,25 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat const { props, ctx } = context; const lastResRef = ref(); const pageRequest = async (query: UserPageQuery): Promise => { - return await api.GetList(query); + return await context.api.GetList(query); }; const editRequest = async (req: EditReq) => { const { form, row } = req; form.id = row.id; form.type = props.type; - const res = await api.UpdateObj(form); + const res = await context.api.UpdateObj(form); lastResRef.value = res; return res; }; const delRequest = async (req: DelReq) => { const { row } = req; - return await api.DelObj(row.id); + return await context.api.DelObj(row.id); }; const addRequest = async (req: AddReq) => { const { form } = req; form.type = props.type; - const res = await api.AddObj(form); + const res = await context.api.AddObj(form); lastResRef.value = res; return res; }; @@ -41,7 +40,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat const typeRef = ref("aliyun"); context.typeRef = typeRef; - const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef); + const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api); commonColumnsDefine.type.form.component.disabled = true; return { typeRef, diff --git a/packages/ui/certd-client/src/views/certd/access/access-selector/access/index.vue b/packages/ui/certd-client/src/views/certd/access/access-selector/access/index.vue index f7163106..f5737f26 100644 --- a/packages/ui/certd-client/src/views/certd/access/access-selector/access/index.vue +++ b/packages/ui/certd-client/src/views/certd/access/access-selector/access/index.vue @@ -8,6 +8,7 @@ import { defineComponent, onMounted, watch } from "vue"; import { useFs } from "@fast-crud/fast-crud"; import createCrudOptions from "./crud"; +import { createAccessApi } from "/@/views/certd/access/api"; export default defineComponent({ name: "CertAccessModal", @@ -16,11 +17,16 @@ export default defineComponent({ type: String, default: "aliyun" }, + from: { + type: String, //user | sys + default: "user" + }, modelValue: {} }, emits: ["update:modelValue"], setup(props, ctx) { - const context: any = { props, ctx }; + const api = createAccessApi(props.from === "sys" ? "/sys/access" : "/pi/access"); + const context: any = { props, ctx, api }; const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context }); // 你可以调用此方法,重新初始化crud配置 diff --git a/packages/ui/certd-client/src/views/certd/access/access-selector/index.vue b/packages/ui/certd-client/src/views/certd/access/access-selector/index.vue index 2e3bde1b..e1071585 100644 --- a/packages/ui/certd-client/src/views/certd/access/access-selector/index.vue +++ b/packages/ui/certd-client/src/views/certd/access/access-selector/index.vue @@ -18,9 +18,8 @@ diff --git a/packages/ui/certd-client/src/views/sys/plugin/api.ts b/packages/ui/certd-client/src/views/sys/plugin/api.ts new file mode 100644 index 00000000..e5fe5297 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/plugin/api.ts @@ -0,0 +1,59 @@ +import { request } from "/src/api/service"; + +const apiPrefix = "/sys/plugin"; + +export async function GetList(query: any) { + return await request({ + url: apiPrefix + "/page", + method: "post", + data: query + }); +} + +export async function AddObj(obj: any) { + return await request({ + url: apiPrefix + "/add", + method: "post", + data: obj + }); +} + +export async function UpdateObj(obj: any) { + return await request({ + url: apiPrefix + "/update", + method: "post", + data: obj + }); +} + +export async function DelObj(id: any) { + return await request({ + url: apiPrefix + "/delete", + method: "post", + params: { id } + }); +} + +export async function GetObj(id: any) { + return await request({ + url: apiPrefix + "/info", + method: "post", + params: { id } + }); +} + +export async function GetDetail(id: any) { + return await request({ + url: apiPrefix + "/detail", + method: "post", + params: { id } + }); +} + +export async function DeleteBatch(ids: any[]) { + return await request({ + url: apiPrefix + "/deleteByIds", + method: "post", + data: { ids } + }); +} diff --git a/packages/ui/certd-client/src/views/sys/plugin/crud.tsx b/packages/ui/certd-client/src/views/sys/plugin/crud.tsx new file mode 100644 index 00000000..032fca28 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/plugin/crud.tsx @@ -0,0 +1,180 @@ +import * as api from "./api"; +import { useI18n } from "vue-i18n"; +import { computed, Ref, ref } from "vue"; +import { useRouter } from "vue-router"; +import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes, utils } from "@fast-crud/fast-crud"; +import { useUserStore } from "/src/store/modules/user"; +import { useSettingStore } from "/src/store/modules/settings"; +import { Modal } from "ant-design-vue"; + +export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { + const router = useRouter(); + const { t } = useI18n(); + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + const res = await api.UpdateObj(form); + return res; + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; + + const addRequest = async ({ form }: AddReq) => { + form.content = JSON.stringify({ + title: form.title + }); + const res = await api.AddObj(form); + return res; + }; + + const userStore = useUserStore(); + const settingStore = useSettingStore(); + const selectedRowKeys: Ref = ref([]); + context.selectedRowKeys = selectedRowKeys; + + return { + crudOptions: { + settings: { + plugins: { + //这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并 + rowSelection: { + enabled: true, + order: -2, + before: true, + // handle: (pluginProps,useCrudProps)=>CrudOptions, + props: { + multiple: true, + crossPage: true, + selectedRowKeys + } + } + } + }, + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + actionbar: { + buttons: { + add: { + show: false + } + } + }, + rowHandle: { + minWidth: 200, + fixed: "right", + buttons: { + edit: { + show: false + } + } + }, + columns: { + id: { + title: "ID", + key: "id", + type: "number", + column: { + width: 100 + }, + form: { + show: false + } + }, + name: { + title: "插件名称", + type: "text", + search: { + show: true + }, + form: { + show: false + }, + column: { + width: 100 + } + }, + title: { + title: "标题", + type: "text", + column: { + width: 300 + } + }, + desc: { + title: "描述", + type: "text", + column: { + width: 300 + } + }, + group: { + title: "分组", + type: "text", + column: { + width: 300 + } + }, + disabled: { + title: "禁用/启用", + type: "dict-switch", + dict: dict({ + data: [ + { label: "启用", value: false, color: "success" }, + { label: "禁用", value: true, color: "error" } + ] + }), + form: { + value: false + }, + column: { + width: 100, + component: { + title: "点击可禁用/启用", + on: { + async click({ value, row }) { + Modal.confirm({ + title: "提示", + content: `确定要${!value ? "禁用" : "启用"}吗?`, + onOk: async () => { + await api.SetDisabled(row.id, !value); + await crudExpose.doRefresh(); + } + }); + } + } + } + } + }, + createTime: { + title: "创建时间", + type: "datetime", + form: { + show: false + }, + column: { + sorter: true, + width: 160, + align: "center" + } + }, + updateTime: { + title: "更新时间", + type: "datetime", + form: { + show: false + }, + column: { + show: true + } + } + } + } + }; +} diff --git a/packages/ui/certd-client/src/views/sys/plugin/index.vue b/packages/ui/certd-client/src/views/sys/plugin/index.vue new file mode 100644 index 00000000..1df7f1c6 --- /dev/null +++ b/packages/ui/certd-client/src/views/sys/plugin/index.vue @@ -0,0 +1,51 @@ + + + + diff --git a/packages/ui/certd-server/db/migration/v10010__plugin.sql b/packages/ui/certd-server/db/migration/v10010__plugin.sql new file mode 100644 index 00000000..6f8df237 --- /dev/null +++ b/packages/ui/certd-server/db/migration/v10010__plugin.sql @@ -0,0 +1,18 @@ +CREATE TABLE "pi_plugin" +( + "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, + "name" varchar(100) NOT NULL, + "icon" varchar(100), + "title" varchar(200), + "desc" varchar(500), + "group" varchar(100), + "version" varchar(100), + "setting" text, + "sysSetting" text, + "content" text, + "type" strinng NOT NULL, + "disabled" boolean NOT NULL, + "create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP), + "update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP) +); + diff --git a/packages/ui/certd-server/db/readme.md b/packages/ui/certd-server/db/readme.md index 8cd8facd..a0a51926 100644 --- a/packages/ui/certd-server/db/readme.md +++ b/packages/ui/certd-server/db/readme.md @@ -1,24 +1,24 @@ ## sqlite与postgres不同点 1. -sl: AUTOINCREAMENT -pg: GENERATED BY DEFAULT AS IDENTITY +sqlite: AUTOINCREAMENT +postgresql: GENERATED BY DEFAULT AS IDENTITY 2. -datetime -timestamp +sqlite: datetime +postgresql: timestamp 3. -update sqlite_sequence set seq = 1000 where name = 'sys_role' ; -select setval('sys_role_id_seq', 1000); +sqlite: update sqlite_sequence set seq = 1000 where name = 'sys_role' ; +postgresql: select setval('sys_role_id_seq', 1000); 4. -"disabled" boolean DEFAULT (0) -"disabled" boolean DEFAULT (false) +sqlite: "disabled" boolean DEFAULT (0) +postgresql: "disabled" boolean DEFAULT (false) 5. -last_insert_rowid() -LASTVAL() +sqlite: last_insert_rowid() +postgresql: LASTVAL() 6. -sl: integer -pg: bigint +sqlite: integer +postgresql: bigint diff --git a/packages/ui/certd-server/src/modules/pipeline/controller/access-controller.ts b/packages/ui/certd-server/src/modules/pipeline/controller/access-controller.ts index af4ddb3f..e83fa4bc 100644 --- a/packages/ui/certd-server/src/modules/pipeline/controller/access-controller.ts +++ b/packages/ui/certd-server/src/modules/pipeline/controller/access-controller.ts @@ -12,6 +12,10 @@ export class AccessController extends CrudController { @Inject() service: AccessService; + userId() { + return this.getUserId(); + } + getService(): AccessService { return this.service; } @@ -19,36 +23,36 @@ export class AccessController extends CrudController { @Post('/page', { summary: Constants.per.authOnly }) async page(@Body(ALL) body) { body.query = body.query ?? {}; - body.query.userId = this.getUserId(); + body.query.userId = this.userId(); return await super.page(body); } @Post('/list', { summary: Constants.per.authOnly }) async list(@Body(ALL) body) { - body.userId = this.getUserId(); + body.userId = this.userId(); return super.list(body); } @Post('/add', { summary: Constants.per.authOnly }) async add(@Body(ALL) bean) { - bean.userId = this.getUserId(); + bean.userId = this.userId(); return super.add(bean); } @Post('/update', { summary: Constants.per.authOnly }) async update(@Body(ALL) bean) { - await this.service.checkUserId(bean.id, this.getUserId()); + await this.service.checkUserId(bean.id, this.userId()); return super.update(bean); } @Post('/info', { summary: Constants.per.authOnly }) async info(@Query('id') id: number) { - await this.service.checkUserId(id, this.getUserId()); + await this.service.checkUserId(id, this.userId()); return super.info(id); } @Post('/delete', { summary: Constants.per.authOnly }) async delete(@Query('id') id: number) { - await this.service.checkUserId(id, this.getUserId()); + await this.service.checkUserId(id, this.userId()); return super.delete(id); } diff --git a/packages/ui/certd-server/src/modules/pipeline/controller/plugin-controller.ts b/packages/ui/certd-server/src/modules/pipeline/controller/plugin-controller.ts deleted file mode 100644 index 50a2f698..00000000 --- a/packages/ui/certd-server/src/modules/pipeline/controller/plugin-controller.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; -import { BaseController } from '@certd/lib-server'; -import { PluginService } from '../service/plugin-service.js'; -import { Constants } from '@certd/lib-server'; - -/** - * 插件 - */ -@Provide() -@Controller('/api/pi/plugin') -export class PluginController extends BaseController { - @Inject() - service: PluginService; - - @Post('/list', { summary: Constants.per.authOnly }) - async list(@Query(ALL) query: any) { - query.userId = this.getUserId(); - const list = this.service.getList(); - return this.ok(list); - } - - @Post('/groups', { summary: Constants.per.authOnly }) - async groups(@Query(ALL) query: any) { - query.userId = this.getUserId(); - const group = this.service.getGroups(); - return this.ok(group); - } -} diff --git a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts index d0ead818..00694afb 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/pipeline-service.ts @@ -20,6 +20,7 @@ import { UserService } from '../../sys/authority/service/user-service.js'; import { AccessGetter } from './access-getter.js'; import { CnameRecordService } from '../../cname/service/cname-record-service.js'; import { CnameProxyService } from './cname-proxy-service.js'; +import { PluginConfigService } from './plugin-config-service.js'; const runningTasks: Map = new Map(); const freeCount = 10; @@ -45,6 +46,9 @@ export class PipelineService extends BaseService { @Inject() historyLogService: HistoryLogService; + @Inject() + pluginConfigService: PluginConfigService; + @Inject() userService: UserService; @@ -356,6 +360,7 @@ export class PipelineService extends BaseService { onChanged, accessService: accessGetter, cnameProxyService, + pluginConfigService: this.pluginConfigService, storage: new DbStorage(userId, this.storageService), emailService: this.emailService, fileRootDir: this.certdConfig.fileRootDir, diff --git a/packages/ui/certd-server/src/modules/pipeline/service/plugin-config-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/plugin-config-service.ts new file mode 100644 index 00000000..32f46fbb --- /dev/null +++ b/packages/ui/certd-server/src/modules/pipeline/service/plugin-config-service.ts @@ -0,0 +1,13 @@ +import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; +import { IPluginConfigService } from '@certd/pipeline'; + +/** + * 授权 + */ +@Provide() +@Scope(ScopeEnum.Singleton) +export class PluginConfigService implements IPluginConfigService { + getPluginConfig(pluginName: string) { + return Promise.resolve({}); + } +} diff --git a/packages/ui/certd-server/src/modules/pipeline/service/plugin-service.ts b/packages/ui/certd-server/src/modules/pipeline/service/plugin-service.ts index 5804dcb5..d0296df9 100644 --- a/packages/ui/certd-server/src/modules/pipeline/service/plugin-service.ts +++ b/packages/ui/certd-server/src/modules/pipeline/service/plugin-service.ts @@ -1,8 +1,9 @@ import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; import { pluginGroups, pluginRegistry } from '@certd/pipeline'; + @Provide() @Scope(ScopeEnum.Singleton) -export class PluginService { +export class BuiltInPluginService { getList() { const collection = pluginRegistry.storage; const list = []; diff --git a/packages/ui/certd-server/src/modules/sys/access/access-controller.ts b/packages/ui/certd-server/src/modules/sys/access/access-controller.ts new file mode 100644 index 00000000..8b43da71 --- /dev/null +++ b/packages/ui/certd-server/src/modules/sys/access/access-controller.ts @@ -0,0 +1,62 @@ +import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; +import { AccessService } from '../../pipeline/service/access-service.js'; +import { AccessController } from '../../pipeline/controller/access-controller.js'; +import { checkComm } from '@certd/pipeline'; + +/** + * 授权 + */ +@Provide() +@Controller('/api/sys/access') +export class SysAccessController extends AccessController { + @Inject() + service2: AccessService; + + getService(): AccessService { + return this.service2; + } + + userId() { + checkComm(); + return 0; + } + + @Post('/page', { summary: 'sys:settings:view' }) + async page(@Body(ALL) body: any) { + return await await super.page(body); + } + + @Post('/list', { summary: 'sys:settings:view' }) + async list(@Body(ALL) body: any) { + return await super.list(body); + } + + @Post('/add', { summary: 'sys:settings:edit' }) + async add(@Body(ALL) bean: any) { + return await super.add(bean); + } + + @Post('/update', { summary: 'sys:settings:edit' }) + async update(@Body(ALL) bean: any) { + return await super.update(bean); + } + @Post('/info', { summary: 'sys:settings:view' }) + async info(@Query('id') id: number) { + return await super.info(id); + } + + @Post('/delete', { summary: 'sys:settings:edit' }) + async delete(@Query('id') id: number) { + return await super.delete(id); + } + + @Post('/define', { summary: 'sys:settings:view' }) + async define(@Query('type') type: string) { + return await super.define(type); + } + + @Post('/accessTypeDict', { summary: 'sys:settings:view' }) + async getAccessTypeDict() { + return await super.getAccessTypeDict(); + } +} diff --git a/packages/ui/certd-server/src/modules/sys/plugin/controller/plugin-controller.ts b/packages/ui/certd-server/src/modules/sys/plugin/controller/plugin-controller.ts new file mode 100644 index 00000000..cb2dead4 --- /dev/null +++ b/packages/ui/certd-server/src/modules/sys/plugin/controller/plugin-controller.ts @@ -0,0 +1,68 @@ +import { ALL, Body, Controller, Inject, Post, Provide, Query } from '@midwayjs/core'; +import { merge } from 'lodash-es'; +import { CrudController } from '@certd/lib-server'; +import { PluginService } from '../service/plugin-service.js'; +import { checkComm } from '@certd/pipeline'; + +/** + * 插件 + */ +@Provide() +@Controller('/api/sys/plugin') +export class PluginController extends CrudController { + @Inject() + service: PluginService; + + getService() { + checkComm(); + return this.service; + } + + @Post('/page', { summary: 'sys:settings:view' }) + async page(@Body(ALL) body: any) { + body.query = body.query ?? {}; + return await super.page(body); + } + + @Post('/list', { summary: 'sys:settings:view' }) + async list(@Body(ALL) body: any) { + return super.list(body); + } + + @Post('/add', { summary: 'sys:settings:edit' }) + async add(@Body(ALL) bean: any) { + const def: any = { + isDefault: false, + disabled: false, + }; + merge(bean, def); + return super.add(bean); + } + + @Post('/update', { summary: 'sys:settings:edit' }) + async update(@Body(ALL) bean: any) { + return super.update(bean); + } + + @Post('/info', { summary: 'sys:settings:view' }) + async info(@Query('id') id: number) { + return super.info(id); + } + + @Post('/delete', { summary: 'sys:settings:edit' }) + async delete(@Query('id') id: number) { + return super.delete(id); + } + + @Post('/deleteByIds', { summary: 'sys:settings:edit' }) + async deleteByIds(@Body(ALL) body: { ids: number[] }) { + const res = await this.service.delete(body.ids); + return this.ok(res); + } + + @Post('/setDisabled', { summary: 'sys:settings:edit' }) + async setDisabled(@Body('id') id: number, @Body('disabled') disabled: boolean) { + await this.service.setDisabled(id, disabled); + return this.ok(); + } +} diff --git a/packages/ui/certd-server/src/modules/sys/plugin/entity/plugin.ts b/packages/ui/certd-server/src/modules/sys/plugin/entity/plugin.ts new file mode 100644 index 00000000..41ce9879 --- /dev/null +++ b/packages/ui/certd-server/src/modules/sys/plugin/entity/plugin.ts @@ -0,0 +1,50 @@ +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; + +@Entity('pi_plugin') +export class PluginEntity { + @PrimaryGeneratedColumn() + id: number; + + @Column({ name: 'name', comment: 'Key' }) + name: string; + + @Column({ name: 'icon', comment: '图标' }) + icon: string; + + @Column({ name: 'title', comment: '标题' }) + title: string; + + @Column({ name: 'group', comment: '分组' }) + group: string; + + @Column({ name: 'desc', comment: '描述' }) + desc: string; + + @Column({ comment: '配置', length: 40960 }) + setting: string; + + @Column({ comment: '系统配置', length: 40960 }) + sysSetting: string; + + @Column({ comment: '脚本', length: 40960 }) + content: string; + + @Column({ comment: '类型', length: 100, nullable: true }) + type: string; // builtIn | custom + + @Column({ comment: '启用/禁用', default: false }) + disabled: boolean; + + @Column({ + name: 'create_time', + comment: '创建时间', + default: () => 'CURRENT_TIMESTAMP', + }) + createTime: Date; + @Column({ + name: 'update_time', + comment: '修改时间', + default: () => 'CURRENT_TIMESTAMP', + }) + updateTime: Date; +} diff --git a/packages/ui/certd-server/src/modules/sys/plugin/service/plugin-service.ts b/packages/ui/certd-server/src/modules/sys/plugin/service/plugin-service.ts new file mode 100644 index 00000000..2f42a2ac --- /dev/null +++ b/packages/ui/certd-server/src/modules/sys/plugin/service/plugin-service.ts @@ -0,0 +1,23 @@ +import { Provide, Scope, ScopeEnum } from '@midwayjs/core'; +import { BaseService } from '@certd/lib-server'; +import { PluginEntity } from '../entity/plugin.js'; +import { InjectEntityModel } from '@midwayjs/typeorm'; +import { Repository } from 'typeorm'; +import { checkComm } from '@certd/pipeline'; + +@Provide() +@Scope(ScopeEnum.Singleton) +export class PluginService extends BaseService { + @InjectEntityModel(PluginEntity) + repository: Repository; + + //@ts-ignore + getRepository() { + checkComm(); + return this.repository; + } + + async setDisabled(id: number, disabled: boolean) { + await this.repository.update({ id }, { disabled }); + } +}