2024-07-15 00:30:33 +08:00
|
|
|
import { Config, Inject, Provide, Scope, ScopeEnum } from '@midwayjs/core';
|
2023-01-29 13:44:19 +08:00
|
|
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
2024-10-31 15:14:56 +08:00
|
|
|
import { In, MoreThan, Repository } from 'typeorm';
|
2024-10-14 00:19:55 +08:00
|
|
|
import { BaseService, PageReq } from '@certd/lib-server';
|
2024-07-15 00:30:33 +08:00
|
|
|
import { HistoryEntity } from '../entity/history.js';
|
|
|
|
|
import { PipelineEntity } from '../entity/pipeline.js';
|
|
|
|
|
import { HistoryDetail } from '../entity/vo/history-detail.js';
|
|
|
|
|
import { HistoryLogService } from './history-log-service.js';
|
2023-06-27 22:45:27 +08:00
|
|
|
import { FileItem, Pipeline, RunnableCollection } from '@certd/pipeline';
|
2023-06-28 15:16:19 +08:00
|
|
|
import { FileStore } from '@certd/pipeline';
|
2024-10-03 22:03:49 +08:00
|
|
|
import { logger } from '@certd/pipeline';
|
2024-10-31 15:14:56 +08:00
|
|
|
import dayjs from 'dayjs';
|
2023-01-29 13:44:19 +08:00
|
|
|
/**
|
|
|
|
|
* 证书申请
|
|
|
|
|
*/
|
|
|
|
|
@Provide()
|
|
|
|
|
@Scope(ScopeEnum.Singleton)
|
|
|
|
|
export class HistoryService extends BaseService<HistoryEntity> {
|
|
|
|
|
@InjectEntityModel(HistoryEntity)
|
|
|
|
|
repository: Repository<HistoryEntity>;
|
2024-10-04 00:52:19 +08:00
|
|
|
|
|
|
|
|
@InjectEntityModel(PipelineEntity)
|
|
|
|
|
pipelineRepository: Repository<PipelineEntity>;
|
2023-01-29 13:44:19 +08:00
|
|
|
@Inject()
|
|
|
|
|
logService: HistoryLogService;
|
2023-06-28 15:16:19 +08:00
|
|
|
|
|
|
|
|
@Config('certd')
|
|
|
|
|
private certdConfig: any;
|
|
|
|
|
|
2024-10-09 02:34:28 +08:00
|
|
|
//@ts-ignore
|
2023-01-29 13:44:19 +08:00
|
|
|
getRepository() {
|
|
|
|
|
return this.repository;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-14 00:19:55 +08:00
|
|
|
async page(pageReq: PageReq<HistoryEntity>) {
|
|
|
|
|
const res = await super.page(pageReq);
|
2024-08-05 12:49:44 +08:00
|
|
|
for (const item of res.records) {
|
|
|
|
|
item.fillPipelineTitle();
|
|
|
|
|
}
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-29 13:44:19 +08:00
|
|
|
async save(bean: HistoryEntity) {
|
|
|
|
|
if (bean.id > 0) {
|
|
|
|
|
await this.update(bean);
|
|
|
|
|
} else {
|
|
|
|
|
await this.add(bean);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-30 18:50:53 +08:00
|
|
|
async detail(historyId: number) {
|
2023-01-29 13:44:19 +08:00
|
|
|
const entity = await this.info(historyId);
|
|
|
|
|
const log = await this.logService.info(historyId);
|
|
|
|
|
return new HistoryDetail(entity, log);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async start(pipeline: PipelineEntity) {
|
|
|
|
|
const bean = {
|
|
|
|
|
userId: pipeline.userId,
|
|
|
|
|
pipelineId: pipeline.id,
|
|
|
|
|
title: pipeline.title,
|
|
|
|
|
status: 'start',
|
|
|
|
|
};
|
|
|
|
|
const { id } = await this.add(bean);
|
|
|
|
|
//清除大于pipeline.keepHistoryCount的历史记录
|
2024-08-05 12:49:44 +08:00
|
|
|
await this.clear(pipeline.id, pipeline.keepHistoryCount);
|
2023-01-29 13:44:19 +08:00
|
|
|
return id;
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-25 11:56:15 +08:00
|
|
|
private async clear(pipelineId: number, keepCount = 20) {
|
2024-10-10 02:15:05 +08:00
|
|
|
if (pipelineId == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-01-29 13:44:19 +08:00
|
|
|
const count = await this.repository.count({
|
|
|
|
|
where: {
|
|
|
|
|
pipelineId,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
if (count <= keepCount) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
let shouldDeleteCount = count - keepCount;
|
2024-08-25 01:55:34 +08:00
|
|
|
const maxDeleteCountBatch = 100;
|
|
|
|
|
// const fileStore = new FileStore({
|
|
|
|
|
// rootDir: this.certdConfig.fileRootDir,
|
|
|
|
|
// scope: pipelineId + '',
|
|
|
|
|
// parent: '0',
|
|
|
|
|
// });
|
2023-01-29 13:44:19 +08:00
|
|
|
while (shouldDeleteCount > 0) {
|
2024-08-25 01:55:34 +08:00
|
|
|
const deleteCountBatch = maxDeleteCountBatch > shouldDeleteCount ? shouldDeleteCount : maxDeleteCountBatch;
|
2023-01-29 13:44:19 +08:00
|
|
|
const list = await this.repository.find({
|
|
|
|
|
select: {
|
|
|
|
|
id: true,
|
|
|
|
|
},
|
|
|
|
|
where: {
|
|
|
|
|
pipelineId,
|
|
|
|
|
},
|
|
|
|
|
order: {
|
|
|
|
|
id: 'ASC',
|
|
|
|
|
},
|
|
|
|
|
skip: 0,
|
|
|
|
|
take: deleteCountBatch,
|
|
|
|
|
});
|
|
|
|
|
|
2024-08-25 01:55:34 +08:00
|
|
|
// for (const historyEntity of list) {
|
|
|
|
|
// const id = historyEntity.id;
|
|
|
|
|
// try {
|
|
|
|
|
// fileStore.deleteByParent(pipelineId + '', id + '');
|
|
|
|
|
// } catch (e) {
|
|
|
|
|
// logger.error('删除文件失败', e);
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
const ids = list.map(item => item.id);
|
|
|
|
|
await this.deleteByIds(ids, null);
|
2023-01-29 13:44:19 +08:00
|
|
|
shouldDeleteCount -= deleteCountBatch;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-06-27 22:45:27 +08:00
|
|
|
|
|
|
|
|
async getLastHistory(pipelineId: number) {
|
|
|
|
|
return await this.repository.findOne({
|
|
|
|
|
where: {
|
|
|
|
|
pipelineId,
|
|
|
|
|
},
|
|
|
|
|
order: {
|
|
|
|
|
id: 'DESC',
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async getFiles(history: HistoryEntity) {
|
|
|
|
|
const status: Pipeline = JSON.parse(history.pipeline);
|
|
|
|
|
const files: FileItem[] = [];
|
|
|
|
|
RunnableCollection.each([status], runnable => {
|
|
|
|
|
if (runnable.runnableType !== 'step') {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (runnable.status?.files != null) {
|
|
|
|
|
files.push(...runnable.status.files);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return files;
|
|
|
|
|
}
|
2024-08-05 12:49:44 +08:00
|
|
|
|
|
|
|
|
async deleteByIds(ids: number[], userId: number) {
|
2024-10-10 02:15:05 +08:00
|
|
|
if (!ids || ids.length === 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-13 20:30:42 +08:00
|
|
|
const condition: any = {
|
2024-08-05 12:49:44 +08:00
|
|
|
id: In(ids),
|
2024-08-13 20:30:42 +08:00
|
|
|
};
|
|
|
|
|
if (userId != null) {
|
|
|
|
|
condition.userId = userId;
|
|
|
|
|
}
|
|
|
|
|
await this.repository.delete(condition);
|
2024-08-05 12:49:44 +08:00
|
|
|
await this.logService.deleteByHistoryIds(ids);
|
|
|
|
|
}
|
2024-08-05 12:57:13 +08:00
|
|
|
|
|
|
|
|
async deleteByPipelineId(id: number) {
|
2024-10-10 02:15:05 +08:00
|
|
|
if (id == null) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-08-05 12:57:13 +08:00
|
|
|
await this.repository.delete({
|
|
|
|
|
pipelineId: id,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const fileStore = new FileStore({
|
|
|
|
|
rootDir: this.certdConfig.fileRootDir,
|
|
|
|
|
scope: id + '',
|
|
|
|
|
parent: '0',
|
|
|
|
|
});
|
|
|
|
|
fileStore.deleteByParent(id + '', '');
|
|
|
|
|
} catch (e) {
|
|
|
|
|
logger.error('删除文件失败', e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-10-31 15:14:56 +08:00
|
|
|
|
2024-10-31 16:19:35 +08:00
|
|
|
async countPerDay(param: { days: number; userId?: any }) {
|
2024-10-31 15:14:56 +08:00
|
|
|
const todayEnd = dayjs().endOf('day');
|
2024-10-31 16:19:35 +08:00
|
|
|
const where: any = {
|
|
|
|
|
// 0点
|
|
|
|
|
// userId: param.userId,
|
|
|
|
|
createTime: MoreThan(todayEnd.add(-param.days, 'day').toDate()),
|
|
|
|
|
};
|
|
|
|
|
if (param.userId > 0) {
|
|
|
|
|
where.userId = param.userId;
|
|
|
|
|
}
|
2024-10-31 15:14:56 +08:00
|
|
|
const result = await this.getRepository()
|
|
|
|
|
.createQueryBuilder('main')
|
|
|
|
|
.select('date(main.createTime) AS date') // 将UNIX时间戳转换为日期
|
|
|
|
|
.addSelect('COUNT(*) AS count')
|
2024-10-31 16:19:35 +08:00
|
|
|
.where(where)
|
2024-10-31 15:14:56 +08:00
|
|
|
.groupBy('date')
|
|
|
|
|
.getRawMany();
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2023-01-29 13:44:19 +08:00
|
|
|
}
|