mirror of https://github.com/certd/certd
chore: plugin管理
parent
6f8fe62087
commit
ccfe72a0d9
|
@ -1,18 +1,16 @@
|
||||||
import { ConcurrencyStrategy, NotificationWhen, Pipeline, ResultType, Runnable, RunStrategy, Stage, Step, Task } from "../dt/index.js";
|
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 { RunHistory, RunnableCollection } from "./run-history.js";
|
||||||
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
import { AbstractTaskPlugin, PluginDefine, pluginRegistry, TaskInstanceContext, UserInfo } from "../plugin/index.js";
|
||||||
import { ContextFactory, IContext } from "./context.js";
|
import { ContextFactory, IContext } from "./context.js";
|
||||||
import { IStorage } from "./storage.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 { Logger } from "log4js";
|
||||||
import { createAxiosService } from "../utils/index.js";
|
|
||||||
import { IAccessService } from "../access/index.js";
|
import { IAccessService } from "../access/index.js";
|
||||||
import { RegistryItem } from "../registry/index.js";
|
import { RegistryItem } from "../registry/index.js";
|
||||||
import { Decorator } from "../decorator/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 { FileStore } from "./file-store.js";
|
||||||
import { hashUtils, utils } from "../utils/index.js";
|
import { cloneDeep, forEach, merge } from "lodash-es";
|
||||||
|
|
||||||
export type ExecutorOptions = {
|
export type ExecutorOptions = {
|
||||||
pipeline: Pipeline;
|
pipeline: Pipeline;
|
||||||
|
@ -21,6 +19,7 @@ export type ExecutorOptions = {
|
||||||
accessService: IAccessService;
|
accessService: IAccessService;
|
||||||
emailService: IEmailService;
|
emailService: IEmailService;
|
||||||
cnameProxyService: ICnameProxyService;
|
cnameProxyService: ICnameProxyService;
|
||||||
|
pluginConfigService: IPluginConfigService;
|
||||||
fileRootDir?: string;
|
fileRootDir?: string;
|
||||||
user: UserInfo;
|
user: UserInfo;
|
||||||
};
|
};
|
||||||
|
@ -42,7 +41,7 @@ export class Executor {
|
||||||
onChanged: (history: RunHistory) => Promise<void>;
|
onChanged: (history: RunHistory) => Promise<void>;
|
||||||
constructor(options: ExecutorOptions) {
|
constructor(options: ExecutorOptions) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.pipeline = _.cloneDeep(options.pipeline);
|
this.pipeline = cloneDeep(options.pipeline);
|
||||||
this.onChanged = async (history: RunHistory) => {
|
this.onChanged = async (history: RunHistory) => {
|
||||||
await options.onChanged(history);
|
await options.onChanged(history);
|
||||||
};
|
};
|
||||||
|
@ -219,7 +218,7 @@ export class Executor {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const define: PluginDefine = plugin.define;
|
const define: PluginDefine = plugin.define;
|
||||||
//从outputContext读取输入参数
|
//从outputContext读取输入参数
|
||||||
const input = _.cloneDeep(step.input);
|
const input = cloneDeep(step.input);
|
||||||
Decorator.inject(define.input, instance, input, (item, key) => {
|
Decorator.inject(define.input, instance, input, (item, key) => {
|
||||||
if (item.component?.name === "output-selector") {
|
if (item.component?.name === "output-selector") {
|
||||||
const contextKey = input[key];
|
const contextKey = input[key];
|
||||||
|
@ -269,6 +268,7 @@ export class Executor {
|
||||||
accessService: this.options.accessService,
|
accessService: this.options.accessService,
|
||||||
emailService: this.options.emailService,
|
emailService: this.options.emailService,
|
||||||
cnameProxyService: this.options.cnameProxyService,
|
cnameProxyService: this.options.cnameProxyService,
|
||||||
|
pluginConfigService: this.options.pluginConfigService,
|
||||||
pipelineContext: this.pipelineContext,
|
pipelineContext: this.pipelineContext,
|
||||||
userContext: this.contextFactory.getContext("user", this.options.user.id),
|
userContext: this.contextFactory.getContext("user", this.options.user.id),
|
||||||
fileStore: new FileStore({
|
fileStore: new FileStore({
|
||||||
|
@ -290,7 +290,7 @@ export class Executor {
|
||||||
this.lastStatusMap.clear();
|
this.lastStatusMap.clear();
|
||||||
}
|
}
|
||||||
//输出上下文变量到output context
|
//输出上下文变量到output context
|
||||||
_.forEach(define.output, (item: any, key: any) => {
|
forEach(define.output, (item: any, key: any) => {
|
||||||
step.status!.output[key] = instance[key];
|
step.status!.output[key] = instance[key];
|
||||||
// const stepOutputKey = `step.${step.id}.${key}`;
|
// const stepOutputKey = `step.${step.id}.${key}`;
|
||||||
// this.runtime.context[stepOutputKey] = instance[key];
|
// this.runtime.context[stepOutputKey] = instance[key];
|
||||||
|
@ -300,7 +300,7 @@ export class Executor {
|
||||||
if (Object.keys(instance._result.pipelineVars).length > 0) {
|
if (Object.keys(instance._result.pipelineVars).length > 0) {
|
||||||
// 判断 pipelineVars 有值时更新
|
// 判断 pipelineVars 有值时更新
|
||||||
const vars = this.pipelineContext.getObj("vars");
|
const vars = this.pipelineContext.getObj("vars");
|
||||||
_.merge(vars, instance._result.pipelineVars);
|
merge(vars, instance._result.pipelineVars);
|
||||||
await this.pipelineContext.setObj("vars", vars);
|
await this.pipelineContext.setObj("vars", vars);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@ import { IContext, PluginRequestHandleReq, RunnableCollection } from "../core/in
|
||||||
import { ILogger, logger, utils } from "../utils/index.js";
|
import { ILogger, logger, utils } from "../utils/index.js";
|
||||||
import { HttpClient } from "../utils/index.js";
|
import { HttpClient } from "../utils/index.js";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import _ from "lodash-es";
|
|
||||||
import { IPluginConfigService } from "../service/config";
|
import { IPluginConfigService } from "../service/config";
|
||||||
|
import { upperFirst } from "lodash-es";
|
||||||
export type UserInfo = {
|
export type UserInfo = {
|
||||||
role: "admin" | "user";
|
role: "admin" | "user";
|
||||||
id: any;
|
id: any;
|
||||||
|
@ -74,7 +74,7 @@ export type TaskInstanceContext = {
|
||||||
//cname记录服务
|
//cname记录服务
|
||||||
cnameProxyService: ICnameProxyService;
|
cnameProxyService: ICnameProxyService;
|
||||||
//插件配置服务
|
//插件配置服务
|
||||||
configService: IPluginConfigService;
|
pluginConfigService: IPluginConfigService;
|
||||||
//流水线上下文
|
//流水线上下文
|
||||||
pipelineContext: IContext;
|
pipelineContext: IContext;
|
||||||
//用户上下文
|
//用户上下文
|
||||||
|
@ -172,7 +172,7 @@ export abstract class AbstractTaskPlugin implements ITaskPlugin {
|
||||||
|
|
||||||
let methodName = req.action;
|
let methodName = req.action;
|
||||||
if (!req.action.startsWith("on")) {
|
if (!req.action.startsWith("on")) {
|
||||||
methodName = `on${_.upperFirst(req.action)}`;
|
methodName = `on${upperFirst(req.action)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import _ from "lodash-es";
|
|
||||||
import { pluginRegistry } from "./registry.js";
|
import { pluginRegistry } from "./registry.js";
|
||||||
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
|
import { PluginDefine, TaskInputDefine, TaskOutputDefine } from "./api.js";
|
||||||
import { Decorator } from "../decorator/index.js";
|
import { Decorator } from "../decorator/index.js";
|
||||||
import { AUTOWIRE_KEY } from "../decorator/index.js";
|
import { AUTOWIRE_KEY } from "../decorator/index.js";
|
||||||
import "reflect-metadata";
|
import "reflect-metadata";
|
||||||
|
import { merge, sortBy } from "lodash-es";
|
||||||
// 提供一个唯一 key
|
// 提供一个唯一 key
|
||||||
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
|
export const PLUGIN_CLASS_KEY = "pipeline:plugin";
|
||||||
|
|
||||||
|
@ -42,13 +42,13 @@ export function IsTaskPlugin(define: PluginDefine): ClassDecorator {
|
||||||
}
|
}
|
||||||
inputArray.push([key, _input]);
|
inputArray.push([key, _input]);
|
||||||
}
|
}
|
||||||
inputArray = _.sortBy(inputArray, (item: any) => item[1].order);
|
inputArray = sortBy(inputArray, (item: any) => item[1].order);
|
||||||
const inputMap: any = {};
|
const inputMap: any = {};
|
||||||
inputArray.forEach((item: any) => {
|
inputArray.forEach((item: any) => {
|
||||||
inputMap[item[0]] = item[1];
|
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);
|
Reflect.defineMetadata(PLUGIN_CLASS_KEY, define, target);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { FormItemProps } from "../d.ts/index.js";
|
|
||||||
|
|
||||||
export type PluginConfig = {
|
export type PluginConfig = {
|
||||||
show: false;
|
name: string;
|
||||||
sysInput: {
|
disabled: boolean;
|
||||||
[key: string]: {};
|
sysSetting: {
|
||||||
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
export * from "./email.js";
|
export * from "./email.js";
|
||||||
export * from "./cname.js";
|
export * from "./cname.js";
|
||||||
|
export * from "./config.js";
|
||||||
|
|
|
@ -2,59 +2,42 @@ import { ALL, Body, Post, Query } from '@midwayjs/core';
|
||||||
import { BaseController } from './base-controller.js';
|
import { BaseController } from './base-controller.js';
|
||||||
|
|
||||||
export abstract class CrudController<T> extends BaseController {
|
export abstract class CrudController<T> extends BaseController {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
abstract getService<T>();
|
abstract getService<T>();
|
||||||
|
|
||||||
@Post('/page')
|
@Post('/page')
|
||||||
async page(
|
async page(@Body(ALL) body: any) {
|
||||||
@Body(ALL)
|
|
||||||
body
|
|
||||||
) {
|
|
||||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, null);
|
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, null);
|
||||||
return this.ok(pageRet);
|
return this.ok(pageRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/list')
|
@Post('/list')
|
||||||
async list(
|
async list(@Body(ALL) body: any) {
|
||||||
@Body(ALL)
|
|
||||||
body
|
|
||||||
) {
|
|
||||||
const listRet = await this.getService().list(body, null, null);
|
const listRet = await this.getService().list(body, null, null);
|
||||||
return this.ok(listRet);
|
return this.ok(listRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/add')
|
@Post('/add')
|
||||||
async add(
|
async add(@Body(ALL) bean: any) {
|
||||||
@Body(ALL)
|
|
||||||
bean
|
|
||||||
) {
|
|
||||||
delete bean.id;
|
delete bean.id;
|
||||||
const id = await this.getService().add(bean);
|
const id = await this.getService().add(bean);
|
||||||
return this.ok(id);
|
return this.ok(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/info')
|
@Post('/info')
|
||||||
async info(
|
async info(@Query('id') id: number) {
|
||||||
@Query('id')
|
|
||||||
id
|
|
||||||
) {
|
|
||||||
const bean = await this.getService().info(id);
|
const bean = await this.getService().info(id);
|
||||||
return this.ok(bean);
|
return this.ok(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/update')
|
@Post('/update')
|
||||||
async update(
|
async update(@Body(ALL) bean: any) {
|
||||||
@Body(ALL)
|
|
||||||
bean
|
|
||||||
) {
|
|
||||||
await this.getService().update(bean);
|
await this.getService().update(bean);
|
||||||
return this.ok(null);
|
return this.ok(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/delete')
|
@Post('/delete')
|
||||||
async delete(
|
async delete(@Query('id') id: number) {
|
||||||
@Query('id')
|
|
||||||
id
|
|
||||||
) {
|
|
||||||
await this.getService().delete([id]);
|
await this.getService().delete([id]);
|
||||||
return this.ok(null);
|
return this.ok(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,34 @@ export const sysResources = [
|
||||||
permission: "sys:settings:view"
|
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: "账号绑定",
|
title: "账号绑定",
|
||||||
name: "AccountBind",
|
name: "AccountBind",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as api from "/@/views/certd/access/api";
|
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
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 { props, ctx } = context;
|
||||||
const lastResRef = ref();
|
const lastResRef = ref();
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await context.api.GetList(query);
|
||||||
};
|
};
|
||||||
const editRequest = async (req: EditReq) => {
|
const editRequest = async (req: EditReq) => {
|
||||||
const { form, row } = req;
|
const { form, row } = req;
|
||||||
form.id = row.id;
|
form.id = row.id;
|
||||||
form.type = props.type;
|
form.type = props.type;
|
||||||
const res = await api.UpdateObj(form);
|
const res = await context.api.UpdateObj(form);
|
||||||
lastResRef.value = res;
|
lastResRef.value = res;
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
const delRequest = async (req: DelReq) => {
|
const delRequest = async (req: DelReq) => {
|
||||||
const { row } = req;
|
const { row } = req;
|
||||||
return await api.DelObj(row.id);
|
return await context.api.DelObj(row.id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addRequest = async (req: AddReq) => {
|
const addRequest = async (req: AddReq) => {
|
||||||
const { form } = req;
|
const { form } = req;
|
||||||
form.type = props.type;
|
form.type = props.type;
|
||||||
const res = await api.AddObj(form);
|
const res = await context.api.AddObj(form);
|
||||||
lastResRef.value = res;
|
lastResRef.value = res;
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
@ -41,7 +40,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
||||||
|
|
||||||
const typeRef = ref("aliyun");
|
const typeRef = ref("aliyun");
|
||||||
context.typeRef = typeRef;
|
context.typeRef = typeRef;
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
commonColumnsDefine.type.form.component.disabled = true;
|
commonColumnsDefine.type.form.component.disabled = true;
|
||||||
return {
|
return {
|
||||||
typeRef,
|
typeRef,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import { defineComponent, onMounted, watch } from "vue";
|
import { defineComponent, onMounted, watch } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "CertAccessModal",
|
name: "CertAccessModal",
|
||||||
|
@ -16,11 +17,16 @@ export default defineComponent({
|
||||||
type: String,
|
type: String,
|
||||||
default: "aliyun"
|
default: "aliyun"
|
||||||
},
|
},
|
||||||
|
from: {
|
||||||
|
type: String, //user | sys
|
||||||
|
default: "user"
|
||||||
|
},
|
||||||
modelValue: {}
|
modelValue: {}
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
emits: ["update:modelValue"],
|
||||||
setup(props, ctx) {
|
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 });
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context });
|
||||||
|
|
||||||
// 你可以调用此方法,重新初始化crud配置
|
// 你可以调用此方法,重新初始化crud配置
|
||||||
|
|
|
@ -18,9 +18,8 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent, reactive, ref, watch } from "vue";
|
import { defineComponent, reactive, ref, watch } from "vue";
|
||||||
import * as api from "../api";
|
|
||||||
import CertAccessModal from "./access/index.vue";
|
import CertAccessModal from "./access/index.vue";
|
||||||
import { GetProviderDefineByAccessType } from "../api";
|
import { createAccessApi } from "../api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "AccessSelector",
|
name: "AccessSelector",
|
||||||
|
@ -41,10 +40,16 @@ export default defineComponent({
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: "middle"
|
default: "middle"
|
||||||
|
},
|
||||||
|
from: {
|
||||||
|
type: String, //user | sys
|
||||||
|
default: "user"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ["update:modelValue"],
|
emits: ["update:modelValue"],
|
||||||
setup(props, ctx) {
|
setup(props, ctx) {
|
||||||
|
const api = createAccessApi(props.from === "sys" ? "/sys/access" : "/pi/access");
|
||||||
|
|
||||||
const target = ref({});
|
const target = ref({});
|
||||||
const selectedId = ref();
|
const selectedId = ref();
|
||||||
async function refreshTarget(value) {
|
async function refreshTarget(value) {
|
||||||
|
|
|
@ -1,57 +1,61 @@
|
||||||
import { request } from "/src/api/service";
|
import { request } from "/src/api/service";
|
||||||
const apiPrefix = "/pi/access";
|
|
||||||
export async function GetList(query: any) {
|
|
||||||
return await request({
|
|
||||||
url: apiPrefix + "/page",
|
|
||||||
method: "post",
|
|
||||||
data: query
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function AddObj(obj: any) {
|
export function createAccessApi(apiPrefix = "/pi/access") {
|
||||||
return await request({
|
return {
|
||||||
url: apiPrefix + "/add",
|
async GetList(query: any) {
|
||||||
method: "post",
|
return await request({
|
||||||
data: obj
|
url: apiPrefix + "/page",
|
||||||
});
|
method: "post",
|
||||||
}
|
data: query
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
export async function UpdateObj(obj: any) {
|
async AddObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/update",
|
url: apiPrefix + "/add",
|
||||||
method: "post",
|
method: "post",
|
||||||
data: obj
|
data: obj
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function DelObj(id: number) {
|
async UpdateObj(obj: any) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/delete",
|
url: apiPrefix + "/update",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
data: obj
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetObj(id: number) {
|
async DelObj(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/info",
|
url: apiPrefix + "/delete",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { id }
|
params: { id }
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetProviderDefine(type: string) {
|
async GetObj(id: number) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/define",
|
url: apiPrefix + "/info",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { type }
|
params: { id }
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
|
||||||
export async function GetProviderDefineByAccessType(type: string) {
|
async GetProviderDefine(type: string) {
|
||||||
return await request({
|
return await request({
|
||||||
url: apiPrefix + "/defineByAccessType",
|
url: apiPrefix + "/define",
|
||||||
method: "post",
|
method: "post",
|
||||||
params: { type }
|
params: { type }
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async GetProviderDefineByAccessType(type: string) {
|
||||||
|
return await request({
|
||||||
|
url: apiPrefix + "/defineByAccessType",
|
||||||
|
method: "post",
|
||||||
|
params: { type }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
import { ColumnCompositionProps, dict, compute } from "@fast-crud/fast-crud";
|
import { ColumnCompositionProps, dict } from "@fast-crud/fast-crud";
|
||||||
// @ts-ignore
|
|
||||||
import * as api from "./api";
|
|
||||||
// @ts-ignore
|
|
||||||
import _ from "lodash-es";
|
|
||||||
import { computed, ref, toRef } from "vue";
|
import { computed, ref, toRef } from "vue";
|
||||||
import { useReference } from "/@/use/use-refrence";
|
import { useReference } from "/@/use/use-refrence";
|
||||||
|
import { forEach, get, merge, set } from "lodash-es";
|
||||||
|
|
||||||
export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
export function getCommonColumnDefine(crudExpose: any, typeRef: any, api: any) {
|
||||||
const AccessTypeDictRef = dict({
|
const AccessTypeDictRef = dict({
|
||||||
url: "/pi/access/accessTypeDict"
|
url: "/pi/access/accessTypeDict"
|
||||||
});
|
});
|
||||||
|
@ -27,20 +24,20 @@ export function getCommonColumnDefine(crudExpose: any, typeRef: any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('crudBinding.value[mode + "Form"].columns', columnsRef.value);
|
console.log('crudBinding.value[mode + "Form"].columns', columnsRef.value);
|
||||||
_.forEach(define.input, (value: any, mapKey: any) => {
|
forEach(define.input, (value: any, mapKey: any) => {
|
||||||
const key = "access." + mapKey;
|
const key = "access." + mapKey;
|
||||||
const field = {
|
const field = {
|
||||||
...value,
|
...value,
|
||||||
key
|
key
|
||||||
};
|
};
|
||||||
const column = _.merge({ title: key }, defaultPluginConfig, field);
|
const column = merge({ title: key }, defaultPluginConfig, field);
|
||||||
|
|
||||||
//eval
|
//eval
|
||||||
useReference(column);
|
useReference(column);
|
||||||
|
|
||||||
//设置默认值
|
//设置默认值
|
||||||
if (column.value != null && _.get(form, key) == null) {
|
if (column.value != null && get(form, key) == null) {
|
||||||
_.set(form, key, column.value);
|
set(form, key, column.value);
|
||||||
}
|
}
|
||||||
//字段配置赋值
|
//字段配置赋值
|
||||||
columnsRef.value[key] = column;
|
columnsRef.value[key] = column;
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import * as api from "./api";
|
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
import { getCommonColumnDefine } from "/@/views/certd/access/common";
|
||||||
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud";
|
||||||
|
|
||||||
export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const api = context.api;
|
||||||
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
const pageRequest = async (query: UserPageQuery): Promise<UserPageRes> => {
|
||||||
return await api.GetList(query);
|
return await api.GetList(query);
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti
|
||||||
};
|
};
|
||||||
|
|
||||||
const typeRef = ref();
|
const typeRef = ref();
|
||||||
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef);
|
const commonColumnsDefine = getCommonColumnDefine(crudExpose, typeRef, api);
|
||||||
return {
|
return {
|
||||||
crudOptions: {
|
crudOptions: {
|
||||||
request: {
|
request: {
|
||||||
|
|
|
@ -14,11 +14,13 @@
|
||||||
import { defineComponent, onMounted } from "vue";
|
import { defineComponent, onMounted } from "vue";
|
||||||
import { useFs } from "@fast-crud/fast-crud";
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
import createCrudOptions from "./crud";
|
import createCrudOptions from "./crud";
|
||||||
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "AccessManager",
|
name: "AccessManager",
|
||||||
setup() {
|
setup() {
|
||||||
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: {} });
|
const api = createAccessApi("/pi/access");
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||||
|
|
||||||
// 页面打开后获取列表数据
|
// 页面打开后获取列表数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<fs-page>
|
||||||
|
<template #header>
|
||||||
|
<div class="title">
|
||||||
|
系统级授权管理
|
||||||
|
<span class="sub">管理第三方系统的授权信息(系统级)</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding"> </fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "../../certd/access/crud";
|
||||||
|
import { createAccessApi } from "/@/views/certd/access/api";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "SysAccessManager",
|
||||||
|
setup() {
|
||||||
|
const api = createAccessApi("/sys/access");
|
||||||
|
const { crudBinding, crudRef, crudExpose } = useFs({ createCrudOptions, context: { api } });
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
crudBinding,
|
||||||
|
crudRef
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -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 }
|
||||||
|
});
|
||||||
|
}
|
|
@ -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<UserPageRes> => {
|
||||||
|
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<any[]> = 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
<template>
|
||||||
|
<fs-page class="page-cert">
|
||||||
|
<template #header>
|
||||||
|
<div class="title">插件管理</div>
|
||||||
|
</template>
|
||||||
|
<fs-crud ref="crudRef" v-bind="crudBinding">
|
||||||
|
<!-- <template #pagination-left>-->
|
||||||
|
<!-- <a-tooltip title="批量删除">-->
|
||||||
|
<!-- <fs-button icon="DeleteOutlined" @click="handleBatchDelete"></fs-button>-->
|
||||||
|
<!-- </a-tooltip>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
</fs-crud>
|
||||||
|
</fs-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted } from "vue";
|
||||||
|
import { useFs } from "@fast-crud/fast-crud";
|
||||||
|
import createCrudOptions from "./crud";
|
||||||
|
import { message, Modal } from "ant-design-vue";
|
||||||
|
import { DeleteBatch } from "./api";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "SysPlugin"
|
||||||
|
});
|
||||||
|
const { crudBinding, crudRef, crudExpose, context } = useFs({ createCrudOptions });
|
||||||
|
|
||||||
|
const selectedRowKeys = context.selectedRowKeys;
|
||||||
|
const handleBatchDelete = () => {
|
||||||
|
if (selectedRowKeys.value?.length > 0) {
|
||||||
|
Modal.confirm({
|
||||||
|
title: "确认",
|
||||||
|
content: `确定要批量删除这${selectedRowKeys.value.length}条记录吗`,
|
||||||
|
async onOk() {
|
||||||
|
await DeleteBatch(selectedRowKeys.value);
|
||||||
|
message.info("删除成功");
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
selectedRowKeys.value = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
message.error("请先勾选记录");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面打开后获取列表数据
|
||||||
|
onMounted(() => {
|
||||||
|
crudExpose.doRefresh();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less"></style>
|
|
@ -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)
|
||||||
|
);
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
## sqlite与postgres不同点
|
## sqlite与postgres不同点
|
||||||
1.
|
1.
|
||||||
sl: AUTOINCREAMENT
|
sqlite: AUTOINCREAMENT
|
||||||
pg: GENERATED BY DEFAULT AS IDENTITY
|
postgresql: GENERATED BY DEFAULT AS IDENTITY
|
||||||
|
|
||||||
2.
|
2.
|
||||||
datetime
|
sqlite: datetime
|
||||||
timestamp
|
postgresql: timestamp
|
||||||
|
|
||||||
3.
|
3.
|
||||||
update sqlite_sequence set seq = 1000 where name = 'sys_role' ;
|
sqlite: update sqlite_sequence set seq = 1000 where name = 'sys_role' ;
|
||||||
select setval('sys_role_id_seq', 1000);
|
postgresql: select setval('sys_role_id_seq', 1000);
|
||||||
|
|
||||||
4.
|
4.
|
||||||
"disabled" boolean DEFAULT (0)
|
sqlite: "disabled" boolean DEFAULT (0)
|
||||||
"disabled" boolean DEFAULT (false)
|
postgresql: "disabled" boolean DEFAULT (false)
|
||||||
|
|
||||||
5.
|
5.
|
||||||
last_insert_rowid()
|
sqlite: last_insert_rowid()
|
||||||
LASTVAL()
|
postgresql: LASTVAL()
|
||||||
|
|
||||||
6.
|
6.
|
||||||
sl: integer
|
sqlite: integer
|
||||||
pg: bigint
|
postgresql: bigint
|
||||||
|
|
|
@ -12,6 +12,10 @@ export class AccessController extends CrudController<AccessService> {
|
||||||
@Inject()
|
@Inject()
|
||||||
service: AccessService;
|
service: AccessService;
|
||||||
|
|
||||||
|
userId() {
|
||||||
|
return this.getUserId();
|
||||||
|
}
|
||||||
|
|
||||||
getService(): AccessService {
|
getService(): AccessService {
|
||||||
return this.service;
|
return this.service;
|
||||||
}
|
}
|
||||||
|
@ -19,36 +23,36 @@ export class AccessController extends CrudController<AccessService> {
|
||||||
@Post('/page', { summary: Constants.per.authOnly })
|
@Post('/page', { summary: Constants.per.authOnly })
|
||||||
async page(@Body(ALL) body) {
|
async page(@Body(ALL) body) {
|
||||||
body.query = body.query ?? {};
|
body.query = body.query ?? {};
|
||||||
body.query.userId = this.getUserId();
|
body.query.userId = this.userId();
|
||||||
return await super.page(body);
|
return await super.page(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/list', { summary: Constants.per.authOnly })
|
@Post('/list', { summary: Constants.per.authOnly })
|
||||||
async list(@Body(ALL) body) {
|
async list(@Body(ALL) body) {
|
||||||
body.userId = this.getUserId();
|
body.userId = this.userId();
|
||||||
return super.list(body);
|
return super.list(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/add', { summary: Constants.per.authOnly })
|
@Post('/add', { summary: Constants.per.authOnly })
|
||||||
async add(@Body(ALL) bean) {
|
async add(@Body(ALL) bean) {
|
||||||
bean.userId = this.getUserId();
|
bean.userId = this.userId();
|
||||||
return super.add(bean);
|
return super.add(bean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/update', { summary: Constants.per.authOnly })
|
@Post('/update', { summary: Constants.per.authOnly })
|
||||||
async update(@Body(ALL) bean) {
|
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);
|
return super.update(bean);
|
||||||
}
|
}
|
||||||
@Post('/info', { summary: Constants.per.authOnly })
|
@Post('/info', { summary: Constants.per.authOnly })
|
||||||
async info(@Query('id') id: number) {
|
async info(@Query('id') id: number) {
|
||||||
await this.service.checkUserId(id, this.getUserId());
|
await this.service.checkUserId(id, this.userId());
|
||||||
return super.info(id);
|
return super.info(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('/delete', { summary: Constants.per.authOnly })
|
@Post('/delete', { summary: Constants.per.authOnly })
|
||||||
async delete(@Query('id') id: number) {
|
async delete(@Query('id') id: number) {
|
||||||
await this.service.checkUserId(id, this.getUserId());
|
await this.service.checkUserId(id, this.userId());
|
||||||
return super.delete(id);
|
return super.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -20,6 +20,7 @@ import { UserService } from '../../sys/authority/service/user-service.js';
|
||||||
import { AccessGetter } from './access-getter.js';
|
import { AccessGetter } from './access-getter.js';
|
||||||
import { CnameRecordService } from '../../cname/service/cname-record-service.js';
|
import { CnameRecordService } from '../../cname/service/cname-record-service.js';
|
||||||
import { CnameProxyService } from './cname-proxy-service.js';
|
import { CnameProxyService } from './cname-proxy-service.js';
|
||||||
|
import { PluginConfigService } from './plugin-config-service.js';
|
||||||
|
|
||||||
const runningTasks: Map<string | number, Executor> = new Map();
|
const runningTasks: Map<string | number, Executor> = new Map();
|
||||||
const freeCount = 10;
|
const freeCount = 10;
|
||||||
|
@ -45,6 +46,9 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
@Inject()
|
@Inject()
|
||||||
historyLogService: HistoryLogService;
|
historyLogService: HistoryLogService;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
pluginConfigService: PluginConfigService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
userService: UserService;
|
userService: UserService;
|
||||||
|
|
||||||
|
@ -356,6 +360,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
onChanged,
|
onChanged,
|
||||||
accessService: accessGetter,
|
accessService: accessGetter,
|
||||||
cnameProxyService,
|
cnameProxyService,
|
||||||
|
pluginConfigService: this.pluginConfigService,
|
||||||
storage: new DbStorage(userId, this.storageService),
|
storage: new DbStorage(userId, this.storageService),
|
||||||
emailService: this.emailService,
|
emailService: this.emailService,
|
||||||
fileRootDir: this.certdConfig.fileRootDir,
|
fileRootDir: this.certdConfig.fileRootDir,
|
||||||
|
|
|
@ -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({});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
import { Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||||
import { pluginGroups, pluginRegistry } from '@certd/pipeline';
|
import { pluginGroups, pluginRegistry } from '@certd/pipeline';
|
||||||
|
|
||||||
@Provide()
|
@Provide()
|
||||||
@Scope(ScopeEnum.Singleton)
|
@Scope(ScopeEnum.Singleton)
|
||||||
export class PluginService {
|
export class BuiltInPluginService {
|
||||||
getList() {
|
getList() {
|
||||||
const collection = pluginRegistry.storage;
|
const collection = pluginRegistry.storage;
|
||||||
const list = [];
|
const list = [];
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<PluginService> {
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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<PluginEntity> {
|
||||||
|
@InjectEntityModel(PluginEntity)
|
||||||
|
repository: Repository<PluginEntity>;
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
getRepository() {
|
||||||
|
checkComm();
|
||||||
|
return this.repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setDisabled(id: number, disabled: boolean) {
|
||||||
|
await this.repository.update({ id }, { disabled });
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue