mirror of https://github.com/certd/certd
perf: 优化流水线列表页面、详情页面性能,精简返回数据
parent
79f2367472
commit
609ac9c9a2
|
@ -164,8 +164,11 @@ export abstract class BaseService<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildListQuery(listReq: ListReq<T>) {
|
private buildListQuery(listReq: ListReq<T>) {
|
||||||
const { query, sort, buildQuery } = listReq;
|
const { query, sort, buildQuery,select } = listReq;
|
||||||
const qb = this.getRepository().createQueryBuilder('main');
|
const qb = this.getRepository().createQueryBuilder('main');
|
||||||
|
if (select) {
|
||||||
|
qb.setFindOptions({select});
|
||||||
|
}
|
||||||
if (query) {
|
if (query) {
|
||||||
const keys = Object.keys(query);
|
const keys = Object.keys(query);
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
|
@ -191,6 +194,7 @@ export abstract class BaseService<T> {
|
||||||
if (buildQuery) {
|
if (buildQuery) {
|
||||||
buildQuery(qb);
|
buildQuery(qb);
|
||||||
}
|
}
|
||||||
|
|
||||||
return qb;
|
return qb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -335,7 +335,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_triggerCount: {
|
triggerCount: {
|
||||||
title: t("certd.fields.scheduledTaskCount"),
|
title: t("certd.fields.scheduledTaskCount"),
|
||||||
type: "number",
|
type: "number",
|
||||||
column: {
|
column: {
|
||||||
|
@ -346,7 +346,7 @@ export default function ({ crudExpose, context: { groupDictRef, selectedRowKeys
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_stepCount: {
|
stepCount: {
|
||||||
title: t("certd.fields.deployTaskCount"),
|
title: t("certd.fields.deployTaskCount"),
|
||||||
type: "number",
|
type: "number",
|
||||||
form: { show: false },
|
form: { show: false },
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<fs-icon v-bind="status" :color="status.iconColor || status.color" />
|
<fs-icon v-bind="status" :color="status.iconColor || status.color" />
|
||||||
</template>
|
</template>
|
||||||
<p>
|
<p>
|
||||||
<fs-date-format :model-value="runnable.status?.startTime"></fs-date-format>
|
<fs-date-format :model-value="runnable.createTime"></fs-date-format>
|
||||||
<a-tag class="ml-5" :color="status.color" :closable="status.value === 'start'" @close="cancelTask">
|
<a-tag class="ml-5" :color="status.color" :closable="status.value === 'start'" @close="cancelTask">
|
||||||
{{ status.label }}
|
{{ status.label }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
|
@ -46,7 +46,7 @@ export default defineComponent({
|
||||||
emits: ["view", "cancel"],
|
emits: ["view", "cancel"],
|
||||||
setup(props: any, ctx: any) {
|
setup(props: any, ctx: any) {
|
||||||
const status = computed(() => {
|
const status = computed(() => {
|
||||||
return statusUtil.get(props.runnable?.status?.result);
|
return statusUtil.get(props.runnable?.status);
|
||||||
});
|
});
|
||||||
|
|
||||||
function view() {
|
function view() {
|
||||||
|
|
|
@ -258,7 +258,7 @@
|
||||||
<a-timeline class="mt-10">
|
<a-timeline class="mt-10">
|
||||||
<template v-for="item of histories" :key="item.id">
|
<template v-for="item of histories" :key="item.id">
|
||||||
<pi-history-timeline-item
|
<pi-history-timeline-item
|
||||||
:runnable="item.pipeline"
|
:runnable="item"
|
||||||
:history-id="item.id"
|
:history-id="item.id"
|
||||||
:is-current="currentHistory?.id === item.id"
|
:is-current="currentHistory?.id === item.id"
|
||||||
:edit-mode="editMode"
|
:edit-mode="editMode"
|
||||||
|
@ -371,7 +371,7 @@ export default defineComponent({
|
||||||
const loadCurrentHistoryDetail = async () => {
|
const loadCurrentHistoryDetail = async () => {
|
||||||
const detail: RunHistory = await props.options?.getHistoryDetail({ historyId: currentHistory.value.id });
|
const detail: RunHistory = await props.options?.getHistoryDetail({ historyId: currentHistory.value.id });
|
||||||
currentHistory.value.logs = detail.logs;
|
currentHistory.value.logs = detail.logs;
|
||||||
merge(currentHistory.value.pipeline, detail.pipeline);
|
currentHistory.value.pipeline = detail.pipeline;
|
||||||
};
|
};
|
||||||
const changeCurrentHistory = async (history?: RunHistory) => {
|
const changeCurrentHistory = async (history?: RunHistory) => {
|
||||||
if (!history) {
|
if (!history) {
|
||||||
|
@ -382,7 +382,8 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
currentHistory.value = history;
|
currentHistory.value = history;
|
||||||
await loadCurrentHistoryDetail();
|
await loadCurrentHistoryDetail();
|
||||||
pipeline.value = history.pipeline;
|
pipeline.value = currentHistory.value.pipeline;
|
||||||
|
currentPipeline.value = cloneDeep(pipeline.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function loadHistoryList(reload = false) {
|
async function loadHistoryList(reload = false) {
|
||||||
|
@ -413,7 +414,8 @@ export default defineComponent({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (historyList[0].pipeline?.version === pipeline.value.version) {
|
//@ts-ignore
|
||||||
|
if (historyList[0]?.version === pipeline.value.version) {
|
||||||
await changeCurrentHistory(historyList[0]);
|
await changeCurrentHistory(historyList[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -486,7 +488,6 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
detail.pipeline
|
detail.pipeline
|
||||||
);
|
);
|
||||||
debugger;
|
|
||||||
pipeline.value = currentPipeline.value;
|
pipeline.value = currentPipeline.value;
|
||||||
await loadHistoryList(true);
|
await loadHistoryList(true);
|
||||||
},
|
},
|
||||||
|
@ -707,7 +708,6 @@ export default defineComponent({
|
||||||
title: "确认",
|
title: "确认",
|
||||||
content: `确定要手动触发运行吗?`,
|
content: `确定要手动触发运行吗?`,
|
||||||
async onOk() {
|
async onOk() {
|
||||||
debugger;
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
await changeCurrentHistory(null);
|
await changeCurrentHistory(null);
|
||||||
await props.options.doTrigger({ pipelineId: pipeline.value.id, stepId: stepId });
|
await props.options.doTrigger({ pipelineId: pipeline.value.id, stepId: stepId });
|
||||||
|
@ -787,7 +787,6 @@ export default defineComponent({
|
||||||
pipeline.value.version = 0;
|
pipeline.value.version = 0;
|
||||||
}
|
}
|
||||||
pipeline.value.version++;
|
pipeline.value.version++;
|
||||||
debugger;
|
|
||||||
currentPipeline.value = pipeline.value;
|
currentPipeline.value = pipeline.value;
|
||||||
|
|
||||||
//移除空阶段
|
//移除空阶段
|
||||||
|
|
|
@ -214,6 +214,7 @@ function transformStatusCount() {
|
||||||
{ name: "error", label: "失败" },
|
{ name: "error", label: "失败" },
|
||||||
{ name: "canceled", label: "已取消" },
|
{ name: "canceled", label: "已取消" },
|
||||||
{ name: null, label: "未执行" },
|
{ name: null, label: "未执行" },
|
||||||
|
{ name: "skip", label: "跳过" },
|
||||||
];
|
];
|
||||||
const result = [];
|
const result = [];
|
||||||
for (const item of sorted) {
|
for (const item of sorted) {
|
||||||
|
|
|
@ -43,7 +43,7 @@ const slots = defineSlots();
|
||||||
.data-item {
|
.data-item {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 180px;
|
height: 188px;
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from '@midwayjs/core';
|
import { ALL, Body, Controller, Get, Inject, Post, Provide, Query } from "@midwayjs/core";
|
||||||
import { CommonException, Constants, CrudController, PermissionException } from '@certd/lib-server';
|
import { CommonException, Constants, CrudController, PermissionException, SysSettingsService } from "@certd/lib-server";
|
||||||
import { PipelineEntity } from '../../../modules/pipeline/entity/pipeline.js';
|
import { PipelineEntity } from "../../../modules/pipeline/entity/pipeline.js";
|
||||||
import { HistoryService } from '../../../modules/pipeline/service/history-service.js';
|
import { HistoryService } from "../../../modules/pipeline/service/history-service.js";
|
||||||
import { HistoryLogService } from '../../../modules/pipeline/service/history-log-service.js';
|
import { HistoryLogService } from "../../../modules/pipeline/service/history-log-service.js";
|
||||||
import { HistoryEntity } from '../../../modules/pipeline/entity/history.js';
|
import { HistoryEntity } from "../../../modules/pipeline/entity/history.js";
|
||||||
import { HistoryLogEntity } from '../../../modules/pipeline/entity/history-log.js';
|
import { HistoryLogEntity } from "../../../modules/pipeline/entity/history-log.js";
|
||||||
import { PipelineService } from '../../../modules/pipeline/service/pipeline-service.js';
|
import { PipelineService } from "../../../modules/pipeline/service/pipeline-service.js";
|
||||||
import * as fs from 'fs';
|
import * as fs from "fs";
|
||||||
import { logger } from '@certd/basic';
|
import { logger } from "@certd/basic";
|
||||||
import { AuthService } from '../../../modules/sys/authority/service/auth-service.js';
|
import { AuthService } from "../../../modules/sys/authority/service/auth-service.js";
|
||||||
import { SysSettingsService } from '@certd/lib-server';
|
import { In } from "typeorm";
|
||||||
import { In } from 'typeorm';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 证书
|
* 证书
|
||||||
|
@ -88,11 +87,30 @@ export class HistoryController extends CrudController<HistoryService> {
|
||||||
const buildQuery = qb => {
|
const buildQuery = qb => {
|
||||||
qb.limit(20);
|
qb.limit(20);
|
||||||
};
|
};
|
||||||
|
const withDetail = body.withDetail;
|
||||||
|
delete body.withDetail;
|
||||||
|
let select:any = null
|
||||||
|
if (!withDetail) {
|
||||||
|
select = {
|
||||||
|
pipeline: true, // 后面这里改成false
|
||||||
|
id: true,
|
||||||
|
userId: true,
|
||||||
|
pipelineId: true,
|
||||||
|
status: true,
|
||||||
|
// startTime: true,
|
||||||
|
triggerType: true,
|
||||||
|
endTime: true,
|
||||||
|
createTime: true,
|
||||||
|
updateTime: true
|
||||||
|
};
|
||||||
|
}
|
||||||
const listRet = await this.getService().list({
|
const listRet = await this.getService().list({
|
||||||
query: body,
|
query: body,
|
||||||
sort: { prop: 'id', asc: false },
|
sort: { prop: 'id', asc: false },
|
||||||
buildQuery,
|
buildQuery,
|
||||||
|
select
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const item of listRet) {
|
for (const item of listRet) {
|
||||||
if (!item.pipeline) {
|
if (!item.pipeline) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -100,7 +118,13 @@ export class HistoryController extends CrudController<HistoryService> {
|
||||||
const json = JSON.parse(item.pipeline);
|
const json = JSON.parse(item.pipeline);
|
||||||
delete json.stages;
|
delete json.stages;
|
||||||
item.pipeline = json;
|
item.pipeline = json;
|
||||||
|
|
||||||
|
//@ts-ignore
|
||||||
|
item.version = json.version;
|
||||||
|
item.status = json.status.result
|
||||||
|
delete item.pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.ok(listRet);
|
return this.ok(listRet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
import {IServiceGetter} from "@certd/pipeline";
|
import { IServiceGetter } from "@certd/pipeline";
|
||||||
import {Inject, Provide, Scope, ScopeEnum} from "@midwayjs/core";
|
import { ApplicationContext, IMidwayContainer, Provide, Scope, ScopeEnum } from "@midwayjs/core";
|
||||||
import {AccessGetter, AccessService} from "@certd/lib-server";
|
import { AccessGetter, AccessService } from "@certd/lib-server";
|
||||||
import {CnameProxyService} from "./cname-proxy-service.js";
|
import { CnameProxyService } from "./cname-proxy-service.js";
|
||||||
import {NotificationGetter} from "./notification-getter.js";
|
import { NotificationGetter } from "./notification-getter.js";
|
||||||
import {NotificationService} from "../notification-service.js";
|
import { NotificationService } from "../notification-service.js";
|
||||||
import {CnameRecordService} from "../../../cname/service/cname-record-service.js";
|
import { CnameRecordService } from "../../../cname/service/cname-record-service.js";
|
||||||
import {SubDomainsGetter} from './sub-domain-getter.js'
|
import { SubDomainsGetter } from "./sub-domain-getter.js";
|
||||||
import {DomainVerifierGetter} from "./domain-verifier-getter.js";
|
import { DomainVerifierGetter } from "./domain-verifier-getter.js";
|
||||||
import {Context} from "@midwayjs/koa";
|
import { DomainService } from "../../../cert/service/domain-service.js";
|
||||||
import {DomainService} from "../../../cert/service/domain-service.js";
|
import { SubDomainService } from "../sub-domain-service.js";
|
||||||
import {SubDomainService} from "../sub-domain-service.js";
|
|
||||||
|
|
||||||
export class TaskServiceGetter implements IServiceGetter{
|
export class TaskServiceGetter implements IServiceGetter{
|
||||||
private userId: number;
|
private userId: number;
|
||||||
private ctx : Context;
|
private appCtx : IMidwayContainer;
|
||||||
constructor(userId:number,ctx:Context) {
|
constructor(userId:number,appCtx:IMidwayContainer) {
|
||||||
this.userId = userId;
|
this.userId = userId;
|
||||||
this.ctx = ctx
|
this.appCtx = appCtx
|
||||||
}
|
}
|
||||||
async get<T>(serviceName: string): Promise<T> {
|
async get<T>(serviceName: string): Promise<T> {
|
||||||
|
|
||||||
|
@ -36,27 +35,27 @@ export class TaskServiceGetter implements IServiceGetter{
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSubDomainsGetter(): Promise<SubDomainsGetter> {
|
async getSubDomainsGetter(): Promise<SubDomainsGetter> {
|
||||||
const subDomainsService:SubDomainService = await this.ctx.requestContext.getAsync("subDomainService")
|
const subDomainsService:SubDomainService = await this.appCtx.getAsync("subDomainService")
|
||||||
return new SubDomainsGetter(this.userId, subDomainsService)
|
return new SubDomainsGetter(this.userId, subDomainsService)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccessService(): Promise<AccessGetter> {
|
async getAccessService(): Promise<AccessGetter> {
|
||||||
const accessService:AccessService = await this.ctx.requestContext.getAsync("accessService")
|
const accessService:AccessService = await this.appCtx.getAsync("accessService")
|
||||||
return new AccessGetter(this.userId, accessService.getById.bind(accessService));
|
return new AccessGetter(this.userId, accessService.getById.bind(accessService));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getCnameProxyService(): Promise<CnameProxyService> {
|
async getCnameProxyService(): Promise<CnameProxyService> {
|
||||||
const cnameRecordService:CnameRecordService = await this.ctx.requestContext.getAsync("cnameRecordService")
|
const cnameRecordService:CnameRecordService = await this.appCtx.getAsync("cnameRecordService")
|
||||||
return new CnameProxyService(this.userId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
|
return new CnameProxyService(this.userId, cnameRecordService.getWithAccessByDomain.bind(cnameRecordService));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNotificationService(): Promise<NotificationGetter> {
|
async getNotificationService(): Promise<NotificationGetter> {
|
||||||
const notificationService:NotificationService = await this.ctx.requestContext.getAsync("notificationService")
|
const notificationService:NotificationService = await this.appCtx.getAsync("notificationService")
|
||||||
return new NotificationGetter(this.userId, notificationService);
|
return new NotificationGetter(this.userId, notificationService);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDomainVerifierGetter(): Promise<DomainVerifierGetter> {
|
async getDomainVerifierGetter(): Promise<DomainVerifierGetter> {
|
||||||
const domainService:DomainService = await this.ctx.requestContext.getAsync("domainService")
|
const domainService:DomainService = await this.appCtx.getAsync("domainService")
|
||||||
return new DomainVerifierGetter(this.userId, domainService);
|
return new DomainVerifierGetter(this.userId, domainService);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,12 +66,12 @@ export type TaskServiceCreateReq = {
|
||||||
@Provide()
|
@Provide()
|
||||||
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
@Scope(ScopeEnum.Request, { allowDowngrade: true })
|
||||||
export class TaskServiceBuilder {
|
export class TaskServiceBuilder {
|
||||||
@Inject()
|
@ApplicationContext()
|
||||||
ctx: Context;
|
appCtx: IMidwayContainer;
|
||||||
|
|
||||||
create(req:TaskServiceCreateReq){
|
create(req:TaskServiceCreateReq){
|
||||||
const userId = req.userId;
|
const userId = req.userId;
|
||||||
return new TaskServiceGetter(userId,this.ctx)
|
return new TaskServiceGetter(userId,this.appCtx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,22 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
const result = await super.page(pageReq);
|
const result = await super.page(pageReq);
|
||||||
await this.fillLastVars(result.records);
|
await this.fillLastVars(result.records);
|
||||||
|
|
||||||
|
for (const item of result.records) {
|
||||||
|
if (!item.content){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const pipeline = JSON.parse(item.content);
|
||||||
|
let stepCount = 0
|
||||||
|
RunnableCollection.each(pipeline.stages, (runnable: any) => {
|
||||||
|
stepCount++
|
||||||
|
})
|
||||||
|
// @ts-ignore
|
||||||
|
item.stepCount = stepCount
|
||||||
|
// @ts-ignore
|
||||||
|
item.triggerCount = pipeline.triggers.length
|
||||||
|
delete item.content
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +653,7 @@ export class PipelineService extends BaseService<PipelineEntity> {
|
||||||
//修改pipeline状态
|
//修改pipeline状态
|
||||||
const pipelineEntity = new PipelineEntity();
|
const pipelineEntity = new PipelineEntity();
|
||||||
pipelineEntity.id = parseInt(history.pipeline.id);
|
pipelineEntity.id = parseInt(history.pipeline.id);
|
||||||
pipelineEntity.status = history.pipeline.status.status + '';
|
pipelineEntity.status = history.pipeline.status.result + '';
|
||||||
pipelineEntity.lastHistoryTime = history.pipeline.status.startTime;
|
pipelineEntity.lastHistoryTime = history.pipeline.status.startTime;
|
||||||
await this.update(pipelineEntity);
|
await this.update(pipelineEntity);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue