ai.router.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. const Router = require('@koa/router');
  2. const ai = require('../controller/ai.controller');
  3. const router = new Router({ prefix: '/ai' });
  4. const request = require('../utils/request');
  5. const util = require('../utils/util');
  6. const qs = require('qs');
  7. const bodyParser = require('koa-bodyparser');
  8. const { chatStream } = require('../controller/ai.controller');
  9. /**
  10. * 接口代理和大模型接入API接口
  11. */
  12. // 流式chat
  13. router.post('/stream', bodyParser(), chatStream);
  14. // 项目配置
  15. router.post('/lib/chat', ai.codeGenerate);
  16. // 接口转发(get)
  17. router.get('/proxy', async (ctx) => handleProxy(ctx, 'get'));
  18. // 接口转发(post)
  19. router.post('/proxy', async (ctx) => handleProxy(ctx, 'post'));
  20. // 接口转发(put)
  21. router.put('/proxy', async (ctx) => handleProxy(ctx, 'put'));
  22. // 接口转发(patch)
  23. router.patch('/proxy', async (ctx) => handleProxy(ctx, 'patch'));
  24. // 接口转发(delete)
  25. router.delete('/proxy', async (ctx) => handleProxy(ctx, 'delete'));
  26. const handleProxy = async (ctx, method) => {
  27. try {
  28. const {
  29. query,
  30. body,
  31. headers: { host, origin, proxyapi, ...headers },
  32. } = ctx.request;
  33. if (!proxyapi) {
  34. return util.fail(ctx, '接口请求地址不存在', 404);
  35. }
  36. let params = method === 'get' || method === 'delete' ? query : body;
  37. if (headers['content-type'] === 'application/x-www-form-urlencoded') {
  38. params = qs.stringify(params);
  39. } else {
  40. params = method === 'get' || method === 'delete' ? query : JSON.stringify(params || {});
  41. }
  42. let response = null;
  43. if (method === 'get' || method === 'delete') {
  44. response = await request[method](proxyapi, {
  45. params,
  46. headers,
  47. });
  48. } else {
  49. response = await request[method](proxyapi, params, {
  50. headers,
  51. });
  52. }
  53. const { status, statusText, data } = response;
  54. for (let key in response.headers) {
  55. ctx.set(key, response.headers[key]);
  56. }
  57. if (status === 200) {
  58. ctx.body = data;
  59. } else {
  60. if (status === 401 || status === 405) {
  61. return util.fail(ctx, '接口请求方法错误', status);
  62. }
  63. if (status === 404) {
  64. return util.fail(ctx, '接口请求地址不存在', status);
  65. }
  66. util.fail(ctx, data || statusText, 500);
  67. }
  68. } catch (error) {
  69. // 根据错误类型设置状态码和错误信息
  70. if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND') {
  71. // 服务地址不存在或无法连接
  72. ctx.status = 502; // Bad Gateway
  73. ctx.body = {
  74. message: '服务不可用或地址不存在',
  75. error: error.message,
  76. };
  77. } else if (error.response) {
  78. // 如果错误是来自后端接口的响应
  79. const { status, data } = error.response;
  80. ctx.status = status; // 设置状态码
  81. ctx.body = data; // 设置响应体
  82. } else if (error.request) {
  83. // 请求已发出,但没有收到响应
  84. ctx.status = 504; // Gateway Timeout
  85. ctx.body = {
  86. message: '请求超时,未收到响应',
  87. error: error.message,
  88. };
  89. } else {
  90. // 其他未知错误
  91. ctx.status = 500; // Internal Server Error
  92. ctx.body = {
  93. message: '服务器内部错误',
  94. error: error.message,
  95. };
  96. }
  97. }
  98. };
  99. module.exports = router;