even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、nestjs中引用esm插件

nestjs是使用commonjs规范进行开发,但是目前市场上很多插件是使用module的形式进行开发,所以遇到引用问题时,建议开发都绕过去,使用功能差不多的插件,但是如果遇到绕不过去的情况,那可以使用以下的方法进行引用

import { ConfigService } from '@nestjs/config';
import { Injectable } from '@nestjs/common';
import { FailException } from '@app/exceptions/fail.exception';
import { ErrorCode } from '@app/constants/error.constant';

export const importDynamic = new Function(
  'modulePath',
  'return import(modulePath)',
);

@Injectable()
export class ChatService {
  private chatGpt: any;
  public constructor(private readonly configService: ConfigService) {}

  private async initInstance(): Promise<void> {
    if (!this.chatGpt) {
      const { ChatGPTAPI } = await importDynamic('chatgpt');

      this.chatGpt = new ChatGPTAPI({
        apiKey: this.configService.get('chat.apiKey'),
      });
    }
  }

  public async getChatResponse() {
    try {
      if (!this.chatGpt) await this.initInstance();

      const res = await this.chatGpt.sendMessage('用js生成一个计算器');

      return res;
    } catch (err) {
      console.log(err);
      throw new FailException(ErrorCode.SERVER_ERROR);
    }
  }
}

 2、nestjs中实现流的转发以及接口转发

import { Response } from 'express';
import { lastValueFrom } from 'rxjs';
import { HttpService } from '@nestjs/axios';
import { IncomingHttpHeaders } from 'http';
import { Controller, Post, Body, Headers, Res } from '@nestjs/common';

import { DChatParam } from './chat.dto';
import { ChatService } from './chat.service';
import { pipeline } from 'stream';

@Controller('chat')
export class ChatController {
  public constructor(
    private readonly chatService: ChatService,
    private readonly httpService: HttpService,
  ) {}

  // 基本的数据接口转发
  @Post('parse')
  public async chatParser(
    @Headers() headers: IncomingHttpHeaders,
    @Body() body: Record<string, string | boolean | number>,
    // @Res() response: Response,
  ) {
    const response = this.httpService.post(
      'https://api.openai.com/v1/chat/completions',
      {
        model: 'gpt-3.5-turbo',
        messages: [{ role: 'user', content: '你好啊' }],
      },
      {
        headers: {
          'Content-Type': 'application/json',
          Authorization:
            'Bearer sk-************',
        },
      },
    );

    const res = await lastValueFrom(response);

    return res.data;
  }

  @Post('stream')
  public async streamRes(@Body() body: any, @Res() response: Response) {
    const response$ = this.httpService.post(
      'https://api.openai.com/v1/chat/completions',
      {
        model: 'gpt-3.5-turbo',
        messages: [{ role: 'user', content: '你好' }],
        stream: true,
      },
      {
        headers: {
          Authorization:
            'Bearer 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',
          'Content-Type': 'application/json',
        },
      },
    );

    const { data, headers } = await lastValueFrom(response$);

    // 将响应头设置到当前请求的头部
    if (headers) {
      Object.keys(headers).forEach((key) => {
        response.setHeader(key, headers[key]);
      });
    }

    // 管道流处理
    const stream = data;
    await new Promise((resolve, reject) => {
      pipeline(stream, response, (err) => {
        if (err) {
          reject(err);
        } else {
          resolve('');
        }
      });
    });
  }
}

 

 

 

posted on 2023-03-22 17:14  even_blogs  阅读(263)  评论(0编辑  收藏  举报