mirror of https://github.com/certd/certd
perf: [comm] 支持插件管理
parent
417971d15d
commit
e8b617b80c
|
@ -5,7 +5,7 @@ export type Registrable = {
|
|||
title: string;
|
||||
desc?: string;
|
||||
group?: string;
|
||||
deprecated?: string;
|
||||
deprecated?: string | boolean;
|
||||
};
|
||||
|
||||
export type RegistryItem<T> = {
|
||||
|
|
|
@ -1,11 +1,24 @@
|
|||
import { ValidateException } from './exception/index.js';
|
||||
import * as _ from 'lodash-es';
|
||||
import { PermissionException } from './exception/index.js';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { In, Repository, SelectQueryBuilder } from 'typeorm';
|
||||
import { Inject } from '@midwayjs/core';
|
||||
import { TypeORMDataSourceManager } from '@midwayjs/typeorm';
|
||||
import { EntityManager } from 'typeorm/entity-manager/EntityManager.js';
|
||||
|
||||
export type PageReq<T = any> = {
|
||||
page?: { offset: number; limit: number };
|
||||
} & ListReq<T>;
|
||||
|
||||
export type ListReq<T = any> = {
|
||||
query?: Partial<T>;
|
||||
order?: {
|
||||
prop: string;
|
||||
asc: boolean;
|
||||
};
|
||||
buildQuery?: (bq: SelectQueryBuilder<any>) => void;
|
||||
};
|
||||
|
||||
/**
|
||||
* 服务基类
|
||||
*/
|
||||
|
@ -106,50 +119,22 @@ export abstract class BaseService<T> {
|
|||
* 新增|修改|删除 之后的操作
|
||||
* @param data 对应数据
|
||||
*/
|
||||
async modifyAfter(data) {}
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async modifyAfter(data: any) {}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param query 查询条件 bean
|
||||
* @param page
|
||||
* @param order
|
||||
* @param buildQuery
|
||||
*/
|
||||
async page(query, page = { offset: 0, limit: 20 }, order, buildQuery) {
|
||||
async page(pageReq: PageReq<T>) {
|
||||
const { page } = pageReq;
|
||||
if (page.offset == null) {
|
||||
page.offset = 0;
|
||||
}
|
||||
if (page.limit == null) {
|
||||
page.limit = 20;
|
||||
}
|
||||
const qb = this.getRepository().createQueryBuilder('main');
|
||||
if (order && order.prop) {
|
||||
qb.addOrderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
||||
}
|
||||
qb.addOrderBy('id', 'DESC');
|
||||
const qb = this.buildListQuery(pageReq);
|
||||
qb.offset(page.offset).limit(page.limit);
|
||||
//根据bean query
|
||||
if (query) {
|
||||
let whereSql = '';
|
||||
let index = 0;
|
||||
_.forEach(query, (value, key) => {
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
if (index !== 0) {
|
||||
whereSql += ' and ';
|
||||
}
|
||||
whereSql += ` main.${key} = :${key} `;
|
||||
index++;
|
||||
});
|
||||
if (index > 0) {
|
||||
qb.where(whereSql, query);
|
||||
}
|
||||
}
|
||||
//自定义query
|
||||
if (buildQuery) {
|
||||
buildQuery(qb);
|
||||
}
|
||||
const list = await qb.getMany();
|
||||
const total = await qb.getCount();
|
||||
return {
|
||||
|
@ -160,19 +145,13 @@ export abstract class BaseService<T> {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
* @param query 查询条件 bean
|
||||
* @param order
|
||||
* @param buildQuery
|
||||
*/
|
||||
async list(query, order, buildQuery) {
|
||||
private buildListQuery(listReq: ListReq<T>) {
|
||||
const { query, order, buildQuery } = listReq;
|
||||
const qb = this.getRepository().createQueryBuilder('main');
|
||||
if (order && order.prop) {
|
||||
qb.orderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
||||
} else {
|
||||
qb.orderBy('id', 'DESC');
|
||||
qb.addOrderBy('main.' + order.prop, order.asc ? 'ASC' : 'DESC');
|
||||
}
|
||||
qb.addOrderBy('id', 'DESC');
|
||||
//根据bean query
|
||||
if (query) {
|
||||
let whereSql = '';
|
||||
|
@ -195,6 +174,14 @@ export abstract class BaseService<T> {
|
|||
if (buildQuery) {
|
||||
buildQuery(qb);
|
||||
}
|
||||
return qb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
async list(listReq: ListReq<T>) {
|
||||
const qb = this.buildListQuery(listReq);
|
||||
return await qb.getMany();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,13 +7,21 @@ export abstract class CrudController<T> extends BaseController {
|
|||
|
||||
@Post('/page')
|
||||
async page(@Body(ALL) body: any) {
|
||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, null);
|
||||
const pageRet = await this.getService().page({
|
||||
query: body.query ?? {},
|
||||
page: body.page,
|
||||
sort: body.sort,
|
||||
bq: body.bq,
|
||||
});
|
||||
return this.ok(pageRet);
|
||||
}
|
||||
|
||||
@Post('/list')
|
||||
async list(@Body(ALL) body: any) {
|
||||
const listRet = await this.getService().list(body, null, null);
|
||||
const listRet = await this.getService().list({
|
||||
query: body.query ?? {},
|
||||
order: body.order,
|
||||
});
|
||||
return this.ok(listRet);
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
},
|
||||
rules: [{ type: "checkCnameVerifyPlan" }],
|
||||
required: true,
|
||||
helper: "如果选择CNAME方式,请按照上面的显示,给域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它",
|
||||
helper: "如果选择CNAME方式,请按照上面的显示,给要申请证书的域名添加CNAME记录,添加后,点击验证,验证成功后不要删除记录,申请和续期证书会一直用它",
|
||||
col: {
|
||||
span: 24,
|
||||
},
|
||||
|
@ -122,7 +122,7 @@ export class CertApplyPlugin extends CertApplyBasePlugin {
|
|||
domainsVerifyPlan!: DomainsVerifyPlanInput;
|
||||
|
||||
@TaskInput({
|
||||
title: "证书提供商",
|
||||
title: "证书颁发机构",
|
||||
value: "letsencrypt",
|
||||
component: {
|
||||
name: "a-select",
|
||||
|
|
|
@ -134,7 +134,7 @@ function install(app: App, options: any = {}) {
|
|||
//固定label宽度
|
||||
span: null,
|
||||
style: {
|
||||
width: "120px"
|
||||
width: "145px"
|
||||
}
|
||||
},
|
||||
async afterSubmit({ mode }) {
|
||||
|
@ -182,86 +182,7 @@ function install(app: App, options: any = {}) {
|
|||
// @ts-ignore
|
||||
app.use(FsExtendsUploader, {
|
||||
// @ts-ignore
|
||||
defaultType: "cos",
|
||||
cos: {
|
||||
keepName: true,
|
||||
domain: "https://d2p-demo-1251260344.cos.ap-guangzhou.myqcloud.com",
|
||||
bucket: "d2p-plugins-1251260344",
|
||||
region: "ap-guangzhou",
|
||||
secretId: "", //
|
||||
secretKey: "", // 传了secretKey 和secretId 代表使用本地签名模式(不安全,生产环境不推荐)
|
||||
async getAuthorization(custom: any) {
|
||||
// 不传secretKey代表使用临时签名模式,此时此参数必传(安全,生产环境推荐)
|
||||
const ret = request({
|
||||
url: "http://www.docmirror.cn:7070/api/upload/cos/getAuthorization",
|
||||
method: "get"
|
||||
});
|
||||
// 返回结构要求如下
|
||||
// ret.data:{
|
||||
// TmpSecretId,
|
||||
// TmpSecretKey,
|
||||
// XCosSecurityToken,
|
||||
// ExpiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
|
||||
// }
|
||||
return ret;
|
||||
},
|
||||
successHandle(ret: any) {
|
||||
// 上传完成后可以在此处处理结果,修改url什么的
|
||||
console.log("success handle:", ret);
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
alioss: {
|
||||
keepName: true,
|
||||
domain: "https://d2p-demo.oss-cn-shenzhen.aliyuncs.com",
|
||||
bucket: "d2p-plugins",
|
||||
region: "oss-cn-shenzhen",
|
||||
accessKeyId: "",
|
||||
accessKeySecret: "",
|
||||
async getAuthorization(context: FsUploaderGetAuthContext): Promise<FsUploaderAliossSTS> {
|
||||
// 不传accessKeySecret代表使用临时签名模式,此时此参数必传(安全,生产环境推荐)
|
||||
const ret = await request({
|
||||
url: "http://www.docmirror.cn:7070/api/upload/alioss/getAuthorization",
|
||||
method: "get"
|
||||
});
|
||||
console.log("ret", ret);
|
||||
// 返回结构要求如下
|
||||
// ret.data:{
|
||||
// TmpSecretId,
|
||||
// TmpSecretKey,
|
||||
// XCosSecurityToken,
|
||||
// ExpiredTime, // SDK 在 ExpiredTime 时间前,不会再次调用 getAuthorization
|
||||
// key //【可选】后台生成的文件key,如果不传则用前端自己生成的key
|
||||
// }
|
||||
return ret;
|
||||
},
|
||||
sdkOpts: {
|
||||
// sdk配置
|
||||
secure: true // 默认为非https上传,为了安全,设置为true
|
||||
},
|
||||
successHandle(ret: any) {
|
||||
// 上传完成后可以在此处处理结果,修改url什么的
|
||||
console.log("success handle:", ret);
|
||||
return ret;
|
||||
}
|
||||
},
|
||||
qiniu: {
|
||||
keepName: true,
|
||||
bucket: "d2p-plugins",
|
||||
async getToken(options: any) {
|
||||
const ret = await request({
|
||||
url: "http://www.docmirror.cn:7070/api/upload/qiniu/getToken",
|
||||
method: "get"
|
||||
});
|
||||
return ret; // {token:xxx,expires:xxx}
|
||||
},
|
||||
successHandle(ret: any) {
|
||||
// 上传完成后可以在此处处理结果,修改url什么的
|
||||
console.log("success handle:", ret);
|
||||
return ret;
|
||||
},
|
||||
domain: "http://d2p.file.handsfree.work/"
|
||||
},
|
||||
defaultType: "form",
|
||||
form: {
|
||||
keepName: true,
|
||||
action: "http://www.docmirror.cn:7070/api/upload/form/upload",
|
||||
|
@ -313,6 +234,11 @@ function install(app: App, options: any = {}) {
|
|||
//此处演示修改官方字段类型
|
||||
const textType = getType("text");
|
||||
textType.search.autoSearchTrigger = "change"; //修改官方的字段类型,变化就触发 , "enter"=回车键触发
|
||||
if (!textType.column) {
|
||||
textType.column = {};
|
||||
}
|
||||
textType.column.ellipsis = true;
|
||||
textType.column.showTitle = true;
|
||||
|
||||
// 此处演示自定义字段类型
|
||||
addTypes({
|
||||
|
|
|
@ -76,18 +76,21 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
}
|
||||
},
|
||||
domain: {
|
||||
title: "域名",
|
||||
title: "CNAME域名",
|
||||
type: "text",
|
||||
editForm: {
|
||||
component: {
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
form: {
|
||||
component: {
|
||||
placeholder: "cname.handsfree.work"
|
||||
},
|
||||
helper: "CNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||
helper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名",
|
||||
rules: [{ required: true, message: "此项必填" }]
|
||||
},
|
||||
column: {
|
||||
|
@ -97,6 +100,9 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
dnsProviderType: {
|
||||
title: "DNS提供商",
|
||||
type: "dict-select",
|
||||
search: {
|
||||
show: true
|
||||
},
|
||||
dict: dict({
|
||||
url: "pi/dnsProvider/list",
|
||||
value: "key",
|
||||
|
|
|
@ -57,3 +57,11 @@ export async function DeleteBatch(ids: any[]) {
|
|||
data: { ids }
|
||||
});
|
||||
}
|
||||
|
||||
export async function SetDisabled(bean: { id?: number; name?: string; type?: string; disabled: boolean }) {
|
||||
return await request({
|
||||
url: apiPrefix + "/setDisabled",
|
||||
method: "post",
|
||||
data: bean
|
||||
});
|
||||
}
|
||||
|
|
|
@ -72,6 +72,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
buttons: {
|
||||
edit: {
|
||||
show: false
|
||||
},
|
||||
copy: {
|
||||
show: false
|
||||
},
|
||||
remove: {
|
||||
show: false
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -97,7 +103,25 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 100
|
||||
width: 200
|
||||
}
|
||||
},
|
||||
icon: {
|
||||
title: "图标",
|
||||
type: "text",
|
||||
form: {
|
||||
show: false
|
||||
},
|
||||
column: {
|
||||
width: 100,
|
||||
align: "center",
|
||||
component: {
|
||||
name: "fs-icon",
|
||||
vModel: "icon",
|
||||
style: {
|
||||
fontSize: "22px"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
title: {
|
||||
|
@ -118,7 +142,8 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
title: "分组",
|
||||
type: "text",
|
||||
column: {
|
||||
width: 300
|
||||
width: 100,
|
||||
align: "center"
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
|
@ -135,6 +160,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
},
|
||||
column: {
|
||||
width: 100,
|
||||
align: "center",
|
||||
component: {
|
||||
title: "点击可禁用/启用",
|
||||
on: {
|
||||
|
@ -143,7 +169,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat
|
|||
title: "提示",
|
||||
content: `确定要${!value ? "禁用" : "启用"}吗?`,
|
||||
onOk: async () => {
|
||||
await api.SetDisabled(row.id, !value);
|
||||
await api.SetDisabled({
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
type: row.type,
|
||||
disabled: !value
|
||||
});
|
||||
await crudExpose.doRefresh();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ CREATE TABLE "pi_plugin"
|
|||
"setting" text,
|
||||
"sysSetting" text,
|
||||
"content" text,
|
||||
"type" strinng NOT NULL,
|
||||
"type" varchar(100) NOT NULL,
|
||||
"disabled" boolean NOT NULL,
|
||||
"create_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP),
|
||||
"update_time" datetime NOT NULL DEFAULT (CURRENT_TIMESTAMP)
|
||||
|
|
|
@ -66,7 +66,7 @@ const development = {
|
|||
type: 'better-sqlite3',
|
||||
database: './data/db.sqlite',
|
||||
synchronize: false, // 如果第一次使用,不存在表,有同步的需求可以写 true
|
||||
logging: false,
|
||||
logging: true,
|
||||
|
||||
// 配置实体模型 或者 entities: '/entity',
|
||||
entities: ['**/modules/**/entity/*.js', ...libServerEntities, ...commercialEntities, PipelineEntity, FlywayHistory, UserEntity],
|
||||
|
|
|
@ -28,7 +28,12 @@ export class CnameRecordController extends CrudController<CnameRecordService> {
|
|||
}
|
||||
};
|
||||
|
||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, bq);
|
||||
const pageRet = await this.getService().page({
|
||||
query: body.query,
|
||||
page: body.page,
|
||||
order: body.order,
|
||||
buildQuery: bq,
|
||||
});
|
||||
return this.ok(pageRet);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,6 @@ export class AccessController extends CrudController<AccessService> {
|
|||
@Inject()
|
||||
service: AccessService;
|
||||
|
||||
userId() {
|
||||
return this.getUserId();
|
||||
}
|
||||
|
||||
getService(): AccessService {
|
||||
return this.service;
|
||||
}
|
||||
|
@ -23,36 +19,45 @@ export class AccessController extends CrudController<AccessService> {
|
|||
@Post('/page', { summary: Constants.per.authOnly })
|
||||
async page(@Body(ALL) body) {
|
||||
body.query = body.query ?? {};
|
||||
body.query.userId = this.userId();
|
||||
return await super.page(body);
|
||||
delete body.query.userId;
|
||||
const buildQuery = qb => {
|
||||
qb.where('user_id = :userId', { userId: this.getUserId() });
|
||||
};
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
page: body.page,
|
||||
order: body.order,
|
||||
buildQuery,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Body(ALL) body) {
|
||||
body.userId = this.userId();
|
||||
body.userId = this.getUserId();
|
||||
return super.list(body);
|
||||
}
|
||||
|
||||
@Post('/add', { summary: Constants.per.authOnly })
|
||||
async add(@Body(ALL) bean) {
|
||||
bean.userId = this.userId();
|
||||
bean.userId = this.getUserId();
|
||||
return super.add(bean);
|
||||
}
|
||||
|
||||
@Post('/update', { summary: Constants.per.authOnly })
|
||||
async update(@Body(ALL) bean) {
|
||||
await this.service.checkUserId(bean.id, this.userId());
|
||||
await this.service.checkUserId(bean.id, this.getUserId());
|
||||
return super.update(bean);
|
||||
}
|
||||
@Post('/info', { summary: Constants.per.authOnly })
|
||||
async info(@Query('id') id: number) {
|
||||
await this.service.checkUserId(id, this.userId());
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
return super.info(id);
|
||||
}
|
||||
|
||||
@Post('/delete', { summary: Constants.per.authOnly })
|
||||
async delete(@Query('id') id: number) {
|
||||
await this.service.checkUserId(id, this.userId());
|
||||
await this.service.checkUserId(id, this.getUserId());
|
||||
return super.delete(id);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,8 +48,11 @@ export class HistoryController extends CrudController<HistoryService> {
|
|||
let pipelineIds: any = null;
|
||||
const pipelineTitle = body.query?.pipelineTitle;
|
||||
if (pipelineTitle) {
|
||||
const pipelines = await this.pipelineService.list(pipelineQuery, null, qb => {
|
||||
const pipelines = await this.pipelineService.list({
|
||||
query: pipelineQuery,
|
||||
buildQuery: qb => {
|
||||
qb.where('title like :title', { title: `%${pipelineTitle}%` });
|
||||
},
|
||||
});
|
||||
pipelineIds = pipelines.map(p => p.id);
|
||||
}
|
||||
|
@ -62,7 +65,12 @@ export class HistoryController extends CrudController<HistoryService> {
|
|||
}
|
||||
};
|
||||
|
||||
const res = await this.service.page(body?.query, body?.page, body?.sort, buildQuery);
|
||||
const res = await this.service.page({
|
||||
query: body.query,
|
||||
page: body.page,
|
||||
order: body.order,
|
||||
buildQuery,
|
||||
});
|
||||
return this.ok(res);
|
||||
}
|
||||
|
||||
|
@ -78,7 +86,11 @@ export class HistoryController extends CrudController<HistoryService> {
|
|||
const buildQuery = qb => {
|
||||
qb.limit(10);
|
||||
};
|
||||
const listRet = await this.getService().list(body, { prop: 'id', asc: false }, buildQuery);
|
||||
const listRet = await this.getService().list({
|
||||
query: body,
|
||||
order: { prop: 'id', asc: false },
|
||||
buildQuery,
|
||||
});
|
||||
return this.ok(listRet);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,12 @@ export class PipelineController extends CrudController<PipelineService> {
|
|||
body.sort = { prop: 'order', asc: false };
|
||||
}
|
||||
|
||||
const pageRet = await this.getService().page(body?.query, body?.page, body?.sort, buildQuery);
|
||||
const pageRet = await this.getService().page({
|
||||
query: body.query,
|
||||
page: body.page,
|
||||
order: body.order,
|
||||
buildQuery,
|
||||
});
|
||||
return this.ok(pageRet);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import { ALL, Controller, Inject, Post, Provide, Query } from '@midwayjs/core';
|
||||
import { BaseController } from '@certd/lib-server';
|
||||
import { BuiltInPluginService } from '../../modules/pipeline/service/plugin-service.js';
|
||||
import { Constants } from '@certd/lib-server';
|
||||
import { BaseController, Constants } from '@certd/lib-server';
|
||||
import { PluginService } from '../../modules/plugin/service/plugin-service.js';
|
||||
|
||||
/**
|
||||
* 插件
|
||||
|
@ -10,19 +9,19 @@ import { Constants } from '@certd/lib-server';
|
|||
@Controller('/api/pi/plugin')
|
||||
export class PluginController extends BaseController {
|
||||
@Inject()
|
||||
service: BuiltInPluginService;
|
||||
service: PluginService;
|
||||
|
||||
@Post('/list', { summary: Constants.per.authOnly })
|
||||
async list(@Query(ALL) query: any) {
|
||||
query.userId = this.getUserId();
|
||||
const list = this.service.getList();
|
||||
const list = await this.service.getEnabledBuiltInList();
|
||||
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();
|
||||
const group = await this.service.getEnabledBuildInGroup();
|
||||
return this.ok(group);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,14 @@ export class SysAccessController extends AccessController {
|
|||
return this.service2;
|
||||
}
|
||||
|
||||
userId() {
|
||||
getUserId() {
|
||||
checkComm();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Post('/page', { summary: 'sys:settings:view' })
|
||||
async page(@Body(ALL) body: any) {
|
||||
return await await super.page(body);
|
||||
return await super.page(body);
|
||||
}
|
||||
|
||||
@Post('/list', { summary: 'sys:settings:view' })
|
||||
|
|
|
@ -61,8 +61,8 @@ export class PluginController extends CrudController<PluginService> {
|
|||
}
|
||||
|
||||
@Post('/setDisabled', { summary: 'sys:settings:edit' })
|
||||
async setDisabled(@Body('id') id: number, @Body('disabled') disabled: boolean) {
|
||||
await this.service.setDisabled(id, disabled);
|
||||
async setDisabled(@Body(ALL) body: { id: number; name: string; type: string; disabled: boolean }) {
|
||||
await this.service.setDisabled(body);
|
||||
return this.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { BaseService, PermissionException, ValidateException } from '@certd/lib-server';
|
||||
import { BaseService, PageReq, PermissionException, ValidateException } from '@certd/lib-server';
|
||||
import { AccessEntity } from '../entity/access.js';
|
||||
import { AccessDefine, accessRegistry, newAccess } from '@certd/pipeline';
|
||||
import { EncryptService } from './encrypt-service.js';
|
||||
|
@ -23,8 +23,8 @@ export class AccessService extends BaseService<AccessEntity> {
|
|||
return this.repository;
|
||||
}
|
||||
|
||||
async page(query, page = { offset: 0, limit: 20 }, order, buildQuery) {
|
||||
const res = await super.page(query, page, order, buildQuery);
|
||||
async page(pageReq: PageReq<AccessEntity>) {
|
||||
const res = await super.page(pageReq);
|
||||
res.records = res.records.map(item => {
|
||||
delete item.encryptSetting;
|
||||
return item;
|
||||
|
@ -107,7 +107,7 @@ export class AccessService extends BaseService<AccessEntity> {
|
|||
if (entity == null) {
|
||||
throw new Error(`该授权配置不存在,请确认是否已被删除:id=${id}`);
|
||||
}
|
||||
if (userId !== entity.userId) {
|
||||
if (userId !== entity.userId && entity.userId !== 0) {
|
||||
throw new PermissionException('您对该Access授权无访问权限');
|
||||
}
|
||||
// const access = accessRegistry.get(entity.type);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { BaseService } from '@certd/lib-server';
|
||||
import { BaseService, PageReq } from '@certd/lib-server';
|
||||
import { HistoryEntity } from '../entity/history.js';
|
||||
import { PipelineEntity } from '../entity/pipeline.js';
|
||||
import { HistoryDetail } from '../entity/vo/history-detail.js';
|
||||
|
@ -32,8 +32,8 @@ export class HistoryService extends BaseService<HistoryEntity> {
|
|||
return this.repository;
|
||||
}
|
||||
|
||||
async page(query, page, sort, buildQuery) {
|
||||
const res = await super.page(query, page, sort, buildQuery);
|
||||
async page(pageReq: PageReq<HistoryEntity>) {
|
||||
const res = await super.page(pageReq);
|
||||
for (const item of res.records) {
|
||||
item.fillPipelineTitle();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Config, Inject, Provide, Scope, ScopeEnum, sleep } from '@midwayjs/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { In, Repository } from 'typeorm';
|
||||
import { BaseService } from '@certd/lib-server';
|
||||
import { BaseService, PageReq } from '@certd/lib-server';
|
||||
import { PipelineEntity } from '../entity/pipeline.js';
|
||||
import { PipelineDetail } from '../entity/vo/pipeline-detail.js';
|
||||
import { Executor, isPlus, Pipeline, ResultType, RunHistory, UserInfo } from '@certd/pipeline';
|
||||
|
@ -68,8 +68,8 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
|||
return bean;
|
||||
}
|
||||
|
||||
async page(query: any, page: { offset: number; limit: number }, order: any, buildQuery: any) {
|
||||
const result = await super.page(query, page, order, buildQuery);
|
||||
async page(pageReq: PageReq<PipelineEntity>) {
|
||||
const result = await super.page(pageReq);
|
||||
const pipelineIds: number[] = [];
|
||||
const recordMap = {};
|
||||
for (const record of result.records) {
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import { Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
||||
import { BaseService } from '@certd/lib-server';
|
||||
import { BaseService, PageReq } from '@certd/lib-server';
|
||||
import { PluginEntity } from '../entity/plugin.js';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { checkComm } from '@certd/pipeline';
|
||||
import { BuiltInPluginService } from '../../pipeline/service/plugin-service.js';
|
||||
import { checkComm, isComm } from '@certd/pipeline';
|
||||
import { BuiltInPluginService } from '../../pipeline/service/builtin-plugin-service.js';
|
||||
import { merge } from 'lodash-es';
|
||||
|
||||
@Provide()
|
||||
@Scope(ScopeEnum.Singleton)
|
||||
|
@ -21,7 +22,103 @@ export class PluginService extends BaseService<PluginEntity> {
|
|||
return this.repository;
|
||||
}
|
||||
|
||||
async setDisabled(id: number, disabled: boolean) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async page(pageReq: PageReq<PluginEntity>) {
|
||||
const builtInList = await this.getBuiltInEntityList();
|
||||
return {
|
||||
records: builtInList,
|
||||
total: builtInList.length,
|
||||
offset: 0,
|
||||
limit: 99999,
|
||||
};
|
||||
}
|
||||
|
||||
async getEnabledBuildInGroup() {
|
||||
const groups = this.builtInPluginService.getGroups();
|
||||
if (!isComm()) {
|
||||
return groups;
|
||||
}
|
||||
const list = await this.list({
|
||||
query: {
|
||||
type: 'builtIn',
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
const disabledNames = list.map(it => it.name);
|
||||
for (const key in groups) {
|
||||
const group = groups[key];
|
||||
if (!group.plugins) {
|
||||
continue;
|
||||
}
|
||||
group.plugins = group.plugins.filter(it => !disabledNames.includes(it.name));
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
async getEnabledBuiltInList(): Promise<any> {
|
||||
const builtInList = this.builtInPluginService.getList();
|
||||
if (!isComm()) {
|
||||
return builtInList;
|
||||
}
|
||||
|
||||
const list = await this.list({
|
||||
query: {
|
||||
type: 'builtIn',
|
||||
disabled: true,
|
||||
},
|
||||
});
|
||||
const disabledNames = list.map(it => it.name);
|
||||
|
||||
return builtInList.filter(it => !disabledNames.includes(it.name));
|
||||
}
|
||||
|
||||
async getBuiltInEntityList() {
|
||||
const builtInList = this.builtInPluginService.getList();
|
||||
const list = await this.list({
|
||||
query: {
|
||||
type: 'builtIn',
|
||||
},
|
||||
});
|
||||
|
||||
const records: PluginEntity[] = [];
|
||||
|
||||
for (const item of builtInList) {
|
||||
let record = list.find(it => it.name === item.name);
|
||||
if (!record) {
|
||||
record = new PluginEntity();
|
||||
record.disabled = false;
|
||||
}
|
||||
merge(record, {
|
||||
name: item.name,
|
||||
title: item.title,
|
||||
type: 'builtIn',
|
||||
icon: item.icon,
|
||||
desc: item.desc,
|
||||
group: item.group,
|
||||
});
|
||||
records.push(record);
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
async setDisabled(opts: { id: number; name: string; type: string; disabled: boolean }) {
|
||||
const { id, name, type, disabled } = opts;
|
||||
if (!type) {
|
||||
throw new Error('参数错误: type 不能为空');
|
||||
}
|
||||
if (id > 0) {
|
||||
//update
|
||||
await this.repository.update({ id }, { disabled });
|
||||
return;
|
||||
}
|
||||
|
||||
if (name && type === 'builtIn') {
|
||||
const pluginEntity = new PluginEntity();
|
||||
pluginEntity.name = name;
|
||||
pluginEntity.type = type;
|
||||
pluginEntity.disabled = disabled;
|
||||
await this.repository.save(pluginEntity);
|
||||
return;
|
||||
}
|
||||
throw new Error('参数错误: id 和 name 必须有一个');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import querystring from 'querystring';
|
|||
desc: 'dynadot dns provider',
|
||||
// 这里是对应的 cloudflare的access类型名称
|
||||
accessType: 'dynadot',
|
||||
deprecated: '暂不支持',
|
||||
})
|
||||
export class DynadotDnsProvider extends AbstractDnsProvider {
|
||||
// 通过Autowire传递context
|
||||
|
|
|
@ -26,6 +26,7 @@ function promisfy(func: any) {
|
|||
desc: '京东云 dns provider',
|
||||
// 这里是对应的 cloudflare的access类型名称
|
||||
accessType: 'jdcloud',
|
||||
deprecated: '暂不支持',
|
||||
})
|
||||
export class JDCloudDnsProvider extends AbstractDnsProvider {
|
||||
// 通过Autowire传递context
|
||||
|
|
Loading…
Reference in New Issue