yuanjiajun commited on
Commit ·
139dfb9
1
Parent(s): e2ed47d
feat: 单图
Browse files- src/const/article.ts +103 -0
- src/service/article-service.ts +24 -44
- src/utils/common.ts +0 -18
- src/utils/file-utils.ts +30 -0
- src/utils/hugging-face.ts +20 -3
src/const/article.ts
CHANGED
|
@@ -458,3 +458,106 @@ export const emotionalStoryEnding = [
|
|
| 458 |
'结局探讨了自由的含义,主角为了追求自由付出了巨大的代价',
|
| 459 |
'结局是一个开放式的,让读者自己想象后续发展',
|
| 460 |
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 458 |
'结局探讨了自由的含义,主角为了追求自由付出了巨大的代价',
|
| 459 |
'结局是一个开放式的,让读者自己想象后续发展',
|
| 460 |
];
|
| 461 |
+
|
| 462 |
+
export const emotionalStoryCover = [
|
| 463 |
+
'乡村土路',
|
| 464 |
+
'山间小溪',
|
| 465 |
+
'麦田间的田埂',
|
| 466 |
+
'村头的老槐树',
|
| 467 |
+
'柴火垛旁的空地',
|
| 468 |
+
'农家小院的篱笆墙',
|
| 469 |
+
'黄昏下的打谷场',
|
| 470 |
+
'清晨的露珠挂在草叶上',
|
| 471 |
+
'河边的垂柳',
|
| 472 |
+
'雨后的乡间小道',
|
| 473 |
+
'田边的灌溉渠',
|
| 474 |
+
'村口的石磨',
|
| 475 |
+
'破旧的茅草屋',
|
| 476 |
+
'山脚下的梯田',
|
| 477 |
+
'堆满干草的草棚',
|
| 478 |
+
'菜园里的蔬菜架',
|
| 479 |
+
'田野里的稻草人',
|
| 480 |
+
'夏季的瓜棚',
|
| 481 |
+
'冬季的雪压树枝',
|
| 482 |
+
'秋天的落叶满地',
|
| 483 |
+
'村后的小山坡',
|
| 484 |
+
'河边的洗衣石',
|
| 485 |
+
'田边的野花丛',
|
| 486 |
+
'村口的老井',
|
| 487 |
+
'屋顶的烟囱',
|
| 488 |
+
'被雨水冲刷的土墙',
|
| 489 |
+
'麦收后的麦茬地',
|
| 490 |
+
'稻穗低垂的稻田',
|
| 491 |
+
'菜园里的水井',
|
| 492 |
+
'村中的石板路',
|
| 493 |
+
'院门口的石狮子',
|
| 494 |
+
'老房子的木窗',
|
| 495 |
+
'黄昏的炊烟',
|
| 496 |
+
'夏日的蝉鸣树',
|
| 497 |
+
'秋天的柿子树',
|
| 498 |
+
'冬日的冰挂树枝',
|
| 499 |
+
'春天的桃花林',
|
| 500 |
+
'夏日的荷花塘(边缘部分,不拍荷花)',
|
| 501 |
+
'雨后的水洼',
|
| 502 |
+
'村边的小树林',
|
| 503 |
+
'田边的灌溉水车',
|
| 504 |
+
'废弃的石碾',
|
| 505 |
+
'堆满农具的角落',
|
| 506 |
+
'乡村小学的操场',
|
| 507 |
+
'村里的祠堂',
|
| 508 |
+
'晒谷场上的竹席',
|
| 509 |
+
'被藤蔓缠绕的电线杆',
|
| 510 |
+
'田边的稻草人',
|
| 511 |
+
'夏日的丝瓜架',
|
| 512 |
+
'冬日的干草堆',
|
| 513 |
+
'秋天的葡萄园',
|
| 514 |
+
'夏日的向日葵地',
|
| 515 |
+
'河边的菖蒲',
|
| 516 |
+
'田边的艾草',
|
| 517 |
+
'村中的老戏台',
|
| 518 |
+
'夏日的葡萄藤架',
|
| 519 |
+
'秋日的玉米地',
|
| 520 |
+
'冬天的枯树林',
|
| 521 |
+
'春天的油菜花田',
|
| 522 |
+
'夏日的竹林',
|
| 523 |
+
'河边的芦苇荡',
|
| 524 |
+
'田边的荆棘丛',
|
| 525 |
+
'村中的石拱桥',
|
| 526 |
+
'夏日的稻田蛙鸣处',
|
| 527 |
+
'秋日的山楂树',
|
| 528 |
+
'冬日的雪地脚印(如果脚印不太明显可算)',
|
| 529 |
+
'春天的榆钱树',
|
| 530 |
+
'村中的老柳树下',
|
| 531 |
+
'田边的排水沟',
|
| 532 |
+
'夏日的豆角架',
|
| 533 |
+
'秋日的南瓜地',
|
| 534 |
+
'冬日的树挂雾凇',
|
| 535 |
+
'春天的杏花林',
|
| 536 |
+
'村中的晒谷场角落',
|
| 537 |
+
'田边的简易瓜棚',
|
| 538 |
+
'夏日的薄荷地',
|
| 539 |
+
'秋日的板栗树',
|
| 540 |
+
'冬日的冻土裂缝',
|
| 541 |
+
'春天的杨树林',
|
| 542 |
+
'河边的苔藓',
|
| 543 |
+
'田边的废弃犁具',
|
| 544 |
+
'村中的古井台',
|
| 545 |
+
'夏日的稻田飞虫',
|
| 546 |
+
'秋日的酸枣树',
|
| 547 |
+
'冬日的秃树鸟巢',
|
| 548 |
+
'春天的果园小径',
|
| 549 |
+
'村中的柴火堆',
|
| 550 |
+
'田边的灌溉水阀',
|
| 551 |
+
'夏日的薄荷丛',
|
| 552 |
+
'秋日的核桃树',
|
| 553 |
+
'冬日的篱笆上的冰柱',
|
| 554 |
+
'春天的蒲公英地',
|
| 555 |
+
'村中的老榆树下',
|
| 556 |
+
'田边的水洼倒影',
|
| 557 |
+
'夏日的韭菜地',
|
| 558 |
+
'秋日的柿子树红果',
|
| 559 |
+
'冬日的雪地枯草',
|
| 560 |
+
'春天的柳树新芽',
|
| 561 |
+
'村中的石墩',
|
| 562 |
+
'田边的野花小径',
|
| 563 |
+
];
|
src/service/article-service.ts
CHANGED
|
@@ -1,39 +1,24 @@
|
|
| 1 |
-
import {
|
| 2 |
|
| 3 |
-
import {
|
| 4 |
-
import { emotionalStoryTopic, emotionalStoryStyle, emotionalStoryEnding } from '@/const';
|
| 5 |
const htmlToDocx = require('html-to-docx');
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
{
|
| 13 |
-
role: 'user',
|
| 14 |
-
content: `翻译成英语并简化内容提炼核心,控制在十五个单词内:${text}`,
|
| 15 |
-
},
|
| 16 |
-
],
|
| 17 |
-
model: 'qwen-plus',
|
| 18 |
-
});
|
| 19 |
-
console.log(`summary:${summary}`);
|
| 20 |
-
const buffer = await getFluxImageBuffer(`modern China:${summary}`, hfApiKey);
|
| 21 |
-
const imageBase64 = bufferToBase64ImageSrc(buffer, 'image/png');
|
| 22 |
-
console.log('------------- 图片Base64获取成功 ---------------');
|
| 23 |
-
return imageBase64;
|
| 24 |
-
}
|
| 25 |
-
|
| 26 |
-
export const processArticleServe = async (data: { title: string; content: string; config: { output: string; hfApiKey: string } }) => {
|
| 27 |
const { title, content, config } = data;
|
| 28 |
-
|
| 29 |
// 将富文本内容分割成段落数组
|
| 30 |
const paragraphs = content.split(/\\n|\n/).filter((p) => p.trim() !== '');
|
| 31 |
-
const imageParagraphCount = Math.
|
| 32 |
|
| 33 |
// 遍历段落,根据段落内容调用接口生成图片并插入到HTML中
|
| 34 |
const htmlArray = [`<h1>${title}</h1>`];
|
| 35 |
let promiseArray = [];
|
| 36 |
-
let
|
| 37 |
|
| 38 |
for (let i = 0; i < paragraphs.length; i++) {
|
| 39 |
const isGeneImage = i === 0 || (i % imageParagraphCount === 0 && i <= paragraphs.length - (imageParagraphCount - 1));
|
|
@@ -41,29 +26,24 @@ export const processArticleServe = async (data: { title: string; content: string
|
|
| 41 |
|
| 42 |
promiseArray.push(
|
| 43 |
new Promise(async (resolve) => {
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
htmlArray[i + 1] += `<img src="${base64ImageUri}" alt="Generated Image"><br>`;
|
| 53 |
-
}
|
| 54 |
-
} catch (error: any) {
|
| 55 |
-
console.error('Error calling API to generate image:', error);
|
| 56 |
}
|
| 57 |
|
| 58 |
htmlArray[i + 1] += `<p>${paragraphs[i]}</p>`;
|
| 59 |
-
|
| 60 |
resolve(1);
|
| 61 |
}),
|
| 62 |
);
|
| 63 |
|
| 64 |
if (isGeneImage) {
|
| 65 |
-
|
| 66 |
-
if (
|
| 67 |
const start = Date.now();
|
| 68 |
await Promise.all(promiseArray);
|
| 69 |
await delay(Math.max(65 * 1000 - (Date.now() - start), 0));
|
|
@@ -76,13 +56,13 @@ export const processArticleServe = async (data: { title: string; content: string
|
|
| 76 |
|
| 77 |
const htmlWithImages = htmlArray.join('');
|
| 78 |
|
| 79 |
-
if (
|
| 80 |
return {
|
| 81 |
article: htmlWithImages,
|
| 82 |
};
|
| 83 |
}
|
| 84 |
|
| 85 |
-
if (
|
| 86 |
const outputFilename = `docx-${Date.now()}.docx`;
|
| 87 |
const docxBuffer = await htmlToDocx(htmlWithImages, {
|
| 88 |
orientation: 'portrait',
|
|
@@ -104,7 +84,7 @@ export const processArticleElementServe = async () => {
|
|
| 104 |
const topic = getRandomUniqueElements(emotionalStoryTopic, 1)[0];
|
| 105 |
const styleList = getRandomUniqueElements(emotionalStoryStyle, 5);
|
| 106 |
const style = styleList.join(',');
|
| 107 |
-
const ending = getRandomUniqueElements(emotionalStoryEnding, 1)[0];
|
| 108 |
|
| 109 |
return {
|
| 110 |
topic,
|
|
|
|
| 1 |
+
import { delay, getImageBase64ByText, getRandomUniqueElements, retryAsync } from '@/utils';
|
| 2 |
|
| 3 |
+
import { uploadFile } from '@/utils';
|
| 4 |
+
import { emotionalStoryTopic, emotionalStoryStyle, emotionalStoryEnding, emotionalStoryCover } from '@/const';
|
| 5 |
const htmlToDocx = require('html-to-docx');
|
| 6 |
|
| 7 |
+
export const processArticleServe = async (data: {
|
| 8 |
+
title: string;
|
| 9 |
+
content: string;
|
| 10 |
+
config: { output: string; hfApiKey: string; imageCount: number };
|
| 11 |
+
}) => {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
const { title, content, config } = data;
|
| 13 |
+
const { output = 'docx', hfApiKey, imageCount = 6 } = config;
|
| 14 |
// 将富文本内容分割成段落数组
|
| 15 |
const paragraphs = content.split(/\\n|\n/).filter((p) => p.trim() !== '');
|
| 16 |
+
const imageParagraphCount = Math.ceil(paragraphs.length / imageCount);
|
| 17 |
|
| 18 |
// 遍历段落,根据段落内容调用接口生成图片并插入到HTML中
|
| 19 |
const htmlArray = [`<h1>${title}</h1>`];
|
| 20 |
let promiseArray = [];
|
| 21 |
+
let currentImageCount = 0;
|
| 22 |
|
| 23 |
for (let i = 0; i < paragraphs.length; i++) {
|
| 24 |
const isGeneImage = i === 0 || (i % imageParagraphCount === 0 && i <= paragraphs.length - (imageParagraphCount - 1));
|
|
|
|
| 26 |
|
| 27 |
promiseArray.push(
|
| 28 |
new Promise(async (resolve) => {
|
| 29 |
+
// 如果是文章开头(i === 0)或者符合每两或三个段落插入图片的规则(且不在最后两段内)
|
| 30 |
+
if (isGeneImage) {
|
| 31 |
+
currentImageCount++;
|
| 32 |
+
|
| 33 |
+
const text = i ? paragraphs[i - 3] + paragraphs[i - 2] + paragraphs[i - 1] : title;
|
| 34 |
+
const base64ImageUri = await retryAsync(() => getImageBase64ByText(text, hfApiKey), 1, 5 * 1000);
|
| 35 |
+
// 创建 Base64 数据 URI
|
| 36 |
+
htmlArray[i + 1] += `<img src="${base64ImageUri}" alt="Generated Image"><br>`;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
}
|
| 38 |
|
| 39 |
htmlArray[i + 1] += `<p>${paragraphs[i]}</p>`;
|
|
|
|
| 40 |
resolve(1);
|
| 41 |
}),
|
| 42 |
);
|
| 43 |
|
| 44 |
if (isGeneImage) {
|
| 45 |
+
currentImageCount++;
|
| 46 |
+
if (currentImageCount % 3 === 0) {
|
| 47 |
const start = Date.now();
|
| 48 |
await Promise.all(promiseArray);
|
| 49 |
await delay(Math.max(65 * 1000 - (Date.now() - start), 0));
|
|
|
|
| 56 |
|
| 57 |
const htmlWithImages = htmlArray.join('');
|
| 58 |
|
| 59 |
+
if (output === 'html') {
|
| 60 |
return {
|
| 61 |
article: htmlWithImages,
|
| 62 |
};
|
| 63 |
}
|
| 64 |
|
| 65 |
+
if (output === 'docx') {
|
| 66 |
const outputFilename = `docx-${Date.now()}.docx`;
|
| 67 |
const docxBuffer = await htmlToDocx(htmlWithImages, {
|
| 68 |
orientation: 'portrait',
|
|
|
|
| 84 |
const topic = getRandomUniqueElements(emotionalStoryTopic, 1)[0];
|
| 85 |
const styleList = getRandomUniqueElements(emotionalStoryStyle, 5);
|
| 86 |
const style = styleList.join(',');
|
| 87 |
+
const ending = getRandomUniqueElements(emotionalStoryEnding, 1)[0];
|
| 88 |
|
| 89 |
return {
|
| 90 |
topic,
|
src/utils/common.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
| 1 |
-
import axios from 'axios';
|
| 2 |
import util from 'util';
|
| 3 |
const setTimeoutPromise = util.promisify(setTimeout);
|
| 4 |
|
|
@@ -21,23 +20,6 @@ export async function retryAsync(func: () => Promise<any>, x = 3, timeout = 10 *
|
|
| 21 |
throw new Error(`Async function failed after ${x} attempts.`);
|
| 22 |
}
|
| 23 |
|
| 24 |
-
export async function requestQw(data: any) {
|
| 25 |
-
const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0';
|
| 26 |
-
|
| 27 |
-
try {
|
| 28 |
-
const response = await axios.post('https://Joey7938-joe-qw-api.hf.space/api/chat/completions', data, {
|
| 29 |
-
headers: {
|
| 30 |
-
'Content-Type': 'application/json',
|
| 31 |
-
Authorization: `Bearer ${qwToken}`,
|
| 32 |
-
},
|
| 33 |
-
});
|
| 34 |
-
|
| 35 |
-
return response.data.choices[0].message.content;
|
| 36 |
-
} catch (error: any) {
|
| 37 |
-
throw new Error(error.response.data);
|
| 38 |
-
}
|
| 39 |
-
}
|
| 40 |
-
|
| 41 |
export function getRandomUniqueElements(arr: any[], x: number): any[] {
|
| 42 |
const result: any[] = [];
|
| 43 |
const copyArr = arr.slice();
|
|
|
|
|
|
|
| 1 |
import util from 'util';
|
| 2 |
const setTimeoutPromise = util.promisify(setTimeout);
|
| 3 |
|
|
|
|
| 20 |
throw new Error(`Async function failed after ${x} attempts.`);
|
| 21 |
}
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
export function getRandomUniqueElements(arr: any[], x: number): any[] {
|
| 24 |
const result: any[] = [];
|
| 25 |
const copyArr = arr.slice();
|
src/utils/file-utils.ts
CHANGED
|
@@ -3,6 +3,9 @@ import fs from 'fs';
|
|
| 3 |
import os from 'os';
|
| 4 |
import path from 'path';
|
| 5 |
import sharp from 'sharp';
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
// 创建上传文件夹,如果不存在
|
| 8 |
export const createUploadDir = (): string => {
|
|
@@ -100,3 +103,30 @@ export async function blobToArrayBuffer(blobOrArrayBuffer: Blob | ArrayBuffer){
|
|
| 100 |
}
|
| 101 |
}
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
import os from 'os';
|
| 4 |
import path from 'path';
|
| 5 |
import sharp from 'sharp';
|
| 6 |
+
import { getRandomUniqueElements } from './common';
|
| 7 |
+
import { requestQwImage } from './hugging-face';
|
| 8 |
+
import { emotionalStoryCover } from '@/const';
|
| 9 |
|
| 10 |
// 创建上传文件夹,如果不存在
|
| 11 |
export const createUploadDir = (): string => {
|
|
|
|
| 103 |
}
|
| 104 |
}
|
| 105 |
|
| 106 |
+
|
| 107 |
+
export async function getImageBase64ByText(text: string, hfApiKey: string) {
|
| 108 |
+
console.log(`------------ 开始获取图片,原文案:${text} ---------------`);
|
| 109 |
+
|
| 110 |
+
// const summary = await requestQw({
|
| 111 |
+
// messages: [
|
| 112 |
+
// {
|
| 113 |
+
// role: 'user',
|
| 114 |
+
// content: `翻译成英语并简化内容提炼核心,控制在十五个单词内:${text}`,
|
| 115 |
+
// },
|
| 116 |
+
// ],
|
| 117 |
+
// model: 'qwen-plus',
|
| 118 |
+
// });
|
| 119 |
+
// console.log(`summary:${summary}`);
|
| 120 |
+
// const buffer = await getFluxImageBuffer(`modern China:${summary}`, hfApiKey);
|
| 121 |
+
// const imageBase64 = bufferToBase64ImageSrc(buffer, 'image/png');
|
| 122 |
+
|
| 123 |
+
const coverTheme = getRandomUniqueElements(emotionalStoryCover, 1)[0];
|
| 124 |
+
const base64 = await requestQwImage({
|
| 125 |
+
prompt: `手机拍摄,贴近现实生活,灰土气息,纯风景,不要人物和动物:${coverTheme}`,
|
| 126 |
+
model: 'qwen-plus',
|
| 127 |
+
response_format: 'b64_json',
|
| 128 |
+
});
|
| 129 |
+
const imageBase64 = `data:image/png;base64,${base64}`;
|
| 130 |
+
console.log('------------- 图片Base64获取成功 ---------------');
|
| 131 |
+
return imageBase64;
|
| 132 |
+
}
|
src/utils/hugging-face.ts
CHANGED
|
@@ -14,7 +14,7 @@ export async function getTranslatedText(text: string, apiKey: string) {
|
|
| 14 |
},
|
| 15 |
);
|
| 16 |
const translatedText = translatedData.data[0].translation_text as string;
|
| 17 |
-
|
| 18 |
return translatedText;
|
| 19 |
} catch (error) {
|
| 20 |
throw new Error(`翻译失败,错误信息:${error}`);
|
|
@@ -34,15 +34,32 @@ export async function getSummaryText(text: string, apiKey: string) {
|
|
| 34 |
},
|
| 35 |
},
|
| 36 |
);
|
| 37 |
-
|
| 38 |
const summaryText = summaryData.data[0].summary_text as string;
|
| 39 |
-
|
| 40 |
return summaryText;
|
| 41 |
} catch (error) {
|
| 42 |
throw new Error(`总结失败,错误信息:${error}`);
|
| 43 |
}
|
| 44 |
}
|
| 45 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 46 |
export async function requestQwImage(data: any) {
|
| 47 |
const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0';
|
| 48 |
|
|
|
|
| 14 |
},
|
| 15 |
);
|
| 16 |
const translatedText = translatedData.data[0].translation_text as string;
|
| 17 |
+
|
| 18 |
return translatedText;
|
| 19 |
} catch (error) {
|
| 20 |
throw new Error(`翻译失败,错误信息:${error}`);
|
|
|
|
| 34 |
},
|
| 35 |
},
|
| 36 |
);
|
| 37 |
+
|
| 38 |
const summaryText = summaryData.data[0].summary_text as string;
|
| 39 |
+
|
| 40 |
return summaryText;
|
| 41 |
} catch (error) {
|
| 42 |
throw new Error(`总结失败,错误信息:${error}`);
|
| 43 |
}
|
| 44 |
}
|
| 45 |
|
| 46 |
+
export async function requestQw(data: any) {
|
| 47 |
+
const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0';
|
| 48 |
+
|
| 49 |
+
try {
|
| 50 |
+
const response = await axios.post('https://Joey7938-joe-qw-api.hf.space/api/chat/completions', data, {
|
| 51 |
+
headers: {
|
| 52 |
+
'Content-Type': 'application/json',
|
| 53 |
+
Authorization: `Bearer ${qwToken}`,
|
| 54 |
+
},
|
| 55 |
+
});
|
| 56 |
+
|
| 57 |
+
return response.data.choices[0].message.content;
|
| 58 |
+
} catch (error: any) {
|
| 59 |
+
throw new Error(error.response.data);
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
export async function requestQwImage(data: any) {
|
| 64 |
const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0';
|
| 65 |
|