diff --git a/.env.development b/.env.development index da1387b..4f2fa07 100644 --- a/.env.development +++ b/.env.development @@ -1 +1,2 @@ -MYSQL_HOST=localhost \ No newline at end of file +MYSQL_HOST=localhost +MYSQL_PORT=33066 \ No newline at end of file diff --git a/.github/workflows/build-latest.yml b/.github/workflows/build-latest.yml index c3063fb..7220327 100644 --- a/.github/workflows/build-latest.yml +++ b/.github/workflows/build-latest.yml @@ -2,8 +2,8 @@ name: Build Latest Image on: push: - branches: - - 'main' + tags: + - 'v*.*.*' jobs: docker: diff --git a/src/main.ts b/src/main.ts index 6de302c..11b982e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -25,7 +25,7 @@ async function bootstrap() { setupSwagger(app); await app.listen(process.env.EOAPI_SERVER_PORT, '0.0.0.0'); const serverUrl = await app.getUrl(); - Logger.log(`api服务已经启动,请访问: ${serverUrl}`); + Logger.log(`Remote Server start successfully,please visit: ${serverUrl}`); // Logger.log(`API文档已生成,请访问: ${serverUrl}/${process.env.SWAGGER_PATH}/`); } diff --git a/src/modules/workspace/project/dto/import.dto.ts b/src/modules/workspace/project/dto/import.dto.ts index a27502c..181bf96 100644 --- a/src/modules/workspace/project/dto/import.dto.ts +++ b/src/modules/workspace/project/dto/import.dto.ts @@ -1,4 +1,5 @@ export class ImportDto { + groupID: number; collections: Child[]; enviroments: Environment[]; } @@ -284,3 +285,16 @@ export interface ApiData { */ responseBodyJsonType?: JsonRootType | string; } + +export type ImportResult = { + errors: { + apiData: any[]; + group: any[]; + enviroments: any[]; + }; + successes: { + apiData: any[]; + group: any[]; + enviroments: any[]; + }; +}; diff --git a/src/modules/workspace/project/project.controller.ts b/src/modules/workspace/project/project.controller.ts index 7d11402..a5d064d 100644 --- a/src/modules/workspace/project/project.controller.ts +++ b/src/modules/workspace/project/project.controller.ts @@ -98,14 +98,7 @@ export class ProjectController { @Body() importDto: ImportDto, ) { // console.log('projectID', projectID, importDto); - const data = await this.service.import( - workspaceID, - Number(projectID), - importDto, - ); - return { - errors: data, - }; + return this.service.import(workspaceID, Number(projectID), importDto); } @ApiOkResponseData(ExportCollectionsResultDto) diff --git a/src/modules/workspace/project/project.service.ts b/src/modules/workspace/project/project.service.ts index 7c14ade..4a24148 100644 --- a/src/modules/workspace/project/project.service.ts +++ b/src/modules/workspace/project/project.service.ts @@ -7,16 +7,10 @@ import { EnvironmentService } from '../environment/environment.service'; import { CreateDto } from './dto/create.dto'; import { UpdateDto } from './dto/update.dto'; import { QueryDto } from './dto/query.dto'; -import { Child, Collections, Environment, ImportDto } from './dto/import.dto'; +import { Child, Environment, ImportDto, ImportResult } from './dto/import.dto'; import { parseAndCheckApiData, parseAndCheckEnv } from './validate'; import { Project } from '@/entities/project.entity'; -type Errors = { - apiData: any[]; - group: any[]; - enviroments: any[]; -}; - @Injectable() export class ProjectService { constructor( @@ -73,17 +67,31 @@ export class ProjectService { return await this.repository.delete(id); } - async import(workspaceID: number, uuid: number, importDto: Collections) { + async import(workspaceID: number, uuid: number, importDto: ImportDto) { + importDto.groupID ??= 0; + const group = this.apiGroupService.findOne({ + where: { uuid: importDto.groupID }, + }); + if (!group) { + return `导入失败,id为${importDto.groupID}的分组不存在`; + } const project = await this.findOne(workspaceID, uuid); if (project) { const { collections, enviroments } = importDto; - const errors = { - apiData: [], - group: [], - enviroments: [], + const data = { + errors: { + apiData: [], + group: [], + enviroments: [], + }, + successes: { + apiData: [], + group: [], + enviroments: [], + }, }; - this.importEnv(enviroments, uuid, errors); - return this.importCollects(collections, uuid, 0, errors); + this.importEnv(enviroments, uuid, data); + return this.importCollects(collections, uuid, importDto.groupID, data); } return '导入失败,项目不存在'; } @@ -126,21 +134,26 @@ export class ProjectService { async importEnv( enviroments: Environment[] = [], projectID: number, - errors: Errors, + importResult: ImportResult, ) { - enviroments.forEach((item) => { + const promiseTask = enviroments.map(async (item) => { const env = { ...item, parameters: item.parameters as unknown as string, }; const result = parseAndCheckEnv(env); if (!result.validate) { - errors.enviroments.push(result); + importResult.errors.enviroments.push(result); } else { result.data.projectID = projectID; - this.environmentService.create(result.data); + const env = await this.environmentService.create(result.data); + importResult.successes.enviroments.push({ + name: env.name, + uuid: env.uuid, + }); } }); + await Promise.allSettled(promiseTask); } getJSONString(target: any) { @@ -161,8 +174,8 @@ export class ProjectService { collections: Child[], projectID: number, parentID = 0, - errors: Errors, - ): Promise { + importResult: ImportResult, + ): Promise { return collections.reduce(async (prev: any, curr: any) => { Reflect.deleteProperty(curr, 'uuid'); if (curr.uri || curr.method || curr.protocol) { @@ -170,31 +183,45 @@ export class ProjectService { if (!result.validate) { (await prev).apiData.push(curr.name || curr.uri); } else { - await this.apiDataService.create({ + const apiData = await this.apiDataService.create({ ...curr, requestBody: this.getJSONString(curr.requestBody || []), responseBody: this.getJSONString(curr.responseBody || []), projectID, groupID: parentID, }); + importResult.successes.apiData.push({ + uri: apiData.uri, + name: apiData.name, + uuid: apiData.uuid, + }); } } else { if (!curr.name) { delete curr.children; (await prev).group.push(curr); } else { - const { uuid } = await this.apiGroupService.create({ + const group = await this.apiGroupService.create({ ...curr, projectID, parentID, }); + importResult.successes.group.push({ + name: group.name, + uuid: group.uuid, + }); if (Array.isArray(curr.children) && curr.children.length) { - await this.importCollects(curr.children, projectID, uuid, errors); + await this.importCollects( + curr.children, + projectID, + group.uuid, + importResult, + ); } } } return prev; - }, errors); + }, importResult); } async getProjectCollections(projectID: number) { diff --git a/src/modules/workspace/workspace.controller.ts b/src/modules/workspace/workspace.controller.ts index c43336c..41caf89 100644 --- a/src/modules/workspace/workspace.controller.ts +++ b/src/modules/workspace/workspace.controller.ts @@ -29,7 +29,10 @@ import { import { WorkspaceEntity } from '@/entities/workspace.entity'; import { IUser, User } from '@/common/decorators/user.decorator'; import { UserEntity } from '@/entities/user.entity'; -import { Collections } from '@/modules/workspace/project/dto/import.dto'; +import { + Collections, + ImportDto, +} from '@/modules/workspace/project/dto/import.dto'; import { ProjectService } from '@/modules/workspace/project/project.service'; import { sampleApiData } from '@/modules/workspace/apiData/samples/sample.api.data'; import { ApiDataService } from '@/modules/workspace/apiData/apiData.service'; @@ -74,14 +77,14 @@ export class WorkspaceController { @ApiCreatedResponseData() @Post('upload') @ApiOperation({ summary: '导入本地数据并创建空间' }) - async importLocalData(@User() user: IUser, @Body() collections: Collections) { + async importLocalData(@User() user: IUser, @Body() importDto: ImportDto) { const workspace = await this.workspaceService.create(user.userId, { title: '默认空间', }); const exportResult = await this.projectService.import( workspace.id, workspace.projects.at(0).uuid, - collections, + importDto, ); if (typeof exportResult === 'string') { return new Error(exportResult);