yuanjiajun commited on
Commit
7262592
·
1 Parent(s): 1660a7d
package.json CHANGED
@@ -19,6 +19,7 @@
19
  "axios": "^1.7.7",
20
  "fs": "0.0.1-security",
21
  "html-docx-js": "^0.3.1",
 
22
  "koa": "^2.15.3",
23
  "koa-body": "^6.0.1",
24
  "koa-bodyparser": "^4.4.1",
 
19
  "axios": "^1.7.7",
20
  "fs": "0.0.1-security",
21
  "html-docx-js": "^0.3.1",
22
+ "html-to-docx": "^1.8.0",
23
  "koa": "^2.15.3",
24
  "koa-body": "^6.0.1",
25
  "koa-bodyparser": "^4.4.1",
src/service/article-service.ts CHANGED
@@ -1,29 +1,30 @@
1
  import fs from 'fs';
2
  import htmlDocx from 'html-docx-js';
3
  import path from 'path';
 
4
 
5
  import { requestQw, requestQwImage } from '@/utils';
6
 
7
  const uploadDir = path.join(__dirname, '../../uploads');
8
 
9
- async function getImageBufferByText(text: string, apiKey: string) {
10
  console.log(`------------ 开始获取图片,原文案:${text} ---------------`);
11
 
12
  const summary = await requestQw({
13
- "messages": [
14
- {
15
- "role": "user",
16
- "content": `简化内容提炼核心,控制在八个字内:${text}`
17
- }
18
  ],
19
- "model": "qwen-plus"
20
- })
21
  console.log(`summary:${summary}`);
22
  const imageBase64 = await requestQwImage({
23
- "prompt":`中国现代:${summary}`,
24
- "model":"qwen-vl-plus",
25
- "response_format": "b64_json"
26
- })
27
 
28
  console.log('------------- 图片Base64获取成功 ---------------');
29
  return imageBase64;
@@ -41,24 +42,22 @@ export const processArticleServe = async (data: { title: string; content: string
41
  // 将富文本内容分割成段落数组
42
  const paragraphs = content.split('\n').filter((p) => p.trim() !== '');
43
 
44
- let htmlWithImages = '';
45
 
46
  // await preheat(config.hfApiKey);
47
 
48
  // 遍历段落,根据段落内容调用接口生成图片并插入到HTML中
49
  for (let i = 0; i < paragraphs.length; i++) {
50
-
51
- // 确定用于生成图片的描述内容,除了第一段,其余为上一段的内容
52
- const description = i === 0 ? paragraphs[i] : paragraphs[i - 1];
53
-
54
  try {
55
  // 如果是文章开头(i === 0)或者符合每两或三个段落插入图片的规则(且不在最后两段内)
56
  if (i === 0 || (i % 3 === 0 && i <= paragraphs.length - 2)) {
57
- const imageBase64 = await getImageBufferByText(description, config.hfApiKey);
58
-
59
- // 创建 Base64 数据 URI
60
  const base64ImageUri = `data:image/png;base64,${imageBase64}`; // 根据图像格式调整此处的 mime 类型
 
61
  htmlWithImages += `<img src="${base64ImageUri}" alt="Generated Image"><br>`;
 
62
  }
63
  } catch (error: any) {
64
  console.error('Error calling API to generate image:', error);
@@ -67,31 +66,22 @@ export const processArticleServe = async (data: { title: string; content: string
67
  htmlWithImages += `<p>${paragraphs[i]}</p>`;
68
  }
69
 
70
- const htmlContent = `
71
- <!DOCTYPE html>
72
- <html>
73
- <head>
74
- <meta charset="utf-8">
75
- <title>${title}</title>
76
- </head>
77
- <body>
78
- ${htmlWithImages}
79
- </body>
80
- </html>
81
- `;
82
 
83
  if (config.output === 'html') {
84
  return {
85
- article: htmlContent,
86
  };
87
  }
88
 
89
  if (config.output === 'docx') {
90
  const outputFilename = `docx-${Date.now()}.docx`;
91
  const outputPath = path.join(uploadDir, outputFilename);
92
- const arrayBuffer = htmlDocx.asBlob(htmlContent) as ArrayBuffer;
 
93
  const docxBuffer = Buffer.from(arrayBuffer);
94
  fs.writeFileSync(outputPath, docxBuffer);
 
95
  return {
96
  article: outputFilename,
97
  };
 
1
  import fs from 'fs';
2
  import htmlDocx from 'html-docx-js';
3
  import path from 'path';
4
+ import { blobToArrayBuffer } from '@/utils';
5
 
6
  import { requestQw, requestQwImage } from '@/utils';
7
 
8
  const uploadDir = path.join(__dirname, '../../uploads');
9
 
10
+ async function getImageBufferByText(text: string) {
11
  console.log(`------------ 开始获取图片,原文案:${text} ---------------`);
12
 
13
  const summary = await requestQw({
14
+ messages: [
15
+ {
16
+ role: 'user',
17
+ content: `简化内容提炼核心,控制在八个字内:${text}`,
18
+ },
19
  ],
20
+ model: 'qwen-plus',
21
+ });
22
  console.log(`summary:${summary}`);
23
  const imageBase64 = await requestQwImage({
24
+ prompt: `中国现代:${summary}`,
25
+ model: 'qwen-vl-plus',
26
+ response_format: 'b64_json',
27
+ });
28
 
29
  console.log('------------- 图片Base64获取成功 ---------------');
30
  return imageBase64;
 
42
  // 将富文本内容分割成段落数组
43
  const paragraphs = content.split('\n').filter((p) => p.trim() !== '');
44
 
45
+ let htmlWithImages = `<h1>${title}</h1>`;
46
 
47
  // await preheat(config.hfApiKey);
48
 
49
  // 遍历段落,根据段落内容调用接口生成图片并插入到HTML中
50
  for (let i = 0; i < paragraphs.length; i++) {
 
 
 
 
51
  try {
52
  // 如果是文章开头(i === 0)或者符合每两或三个段落插入图片的规则(且不在最后两段内)
53
  if (i === 0 || (i % 3 === 0 && i <= paragraphs.length - 2)) {
54
+ const text = i ? paragraphs[i - 3] + paragraphs[i - 2] + paragraphs[i - 1] : title;
55
+
56
+ const imageBase64 = await getImageBufferByText(text);
57
  const base64ImageUri = `data:image/png;base64,${imageBase64}`; // 根据图像格式调整此处的 mime 类型
58
+ // 创建 Base64 数据 URI
59
  htmlWithImages += `<img src="${base64ImageUri}" alt="Generated Image"><br>`;
60
+ console.log(htmlWithImages);
61
  }
62
  } catch (error: any) {
63
  console.error('Error calling API to generate image:', error);
 
66
  htmlWithImages += `<p>${paragraphs[i]}</p>`;
67
  }
68
 
69
+ console.log(htmlWithImages);
 
 
 
 
 
 
 
 
 
 
 
70
 
71
  if (config.output === 'html') {
72
  return {
73
+ article: htmlWithImages,
74
  };
75
  }
76
 
77
  if (config.output === 'docx') {
78
  const outputFilename = `docx-${Date.now()}.docx`;
79
  const outputPath = path.join(uploadDir, outputFilename);
80
+ const blob = htmlDocx.asBlob(htmlWithImages) as Blob;
81
+ const arrayBuffer = (await blobToArrayBuffer(blob)) as ArrayBuffer;
82
  const docxBuffer = Buffer.from(arrayBuffer);
83
  fs.writeFileSync(outputPath, docxBuffer);
84
+
85
  return {
86
  article: outputFilename,
87
  };
src/utils/common.ts CHANGED
@@ -20,36 +20,32 @@ export async function retryAsync(func: () => Promise<any>, x = 3, timeout = 10 *
20
  throw new Error(`Async function failed after ${x} attempts.`);
21
  }
22
 
23
- export async function requestQw(data:any) {
24
- const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0'
25
-
26
- const response = await axios.post(
27
- 'https://Joey7938-joe-qw-api.hf.space/api/chat/completions',
28
- data,
29
- {
30
- headers: {
31
- 'Content-Type': 'application/json',
32
- Authorization: `Bearer ${qwToken}`,
33
- },
34
  },
35
- );
36
 
37
  return response.data.choices[0].message.content;
38
  }
39
 
40
- export async function requestQwImage(data:any) {
41
- const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0'
42
-
43
- const response = await axios.post(
44
- 'https://Joey7938-joe-qw-api.hf.space/api/images/generations',
45
- data,
46
- {
47
- headers: {
48
- 'Content-Type': 'application/json',
49
- Authorization: `Bearer ${qwToken}`,
50
- },
51
  },
52
- );
53
 
54
- return response.data.data[0].b64_json;
55
- }
 
 
 
 
 
20
  throw new Error(`Async function failed after ${x} attempts.`);
21
  }
22
 
23
+ export async function requestQw(data: any) {
24
+ const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0';
25
+
26
+ const response = await axios.post('https://Joey7938-joe-qw-api.hf.space/api/chat/completions', data, {
27
+ headers: {
28
+ 'Content-Type': 'application/json',
29
+ Authorization: `Bearer ${qwToken}`,
 
 
 
 
30
  },
31
+ });
32
 
33
  return response.data.choices[0].message.content;
34
  }
35
 
36
+ export async function requestQwImage(data: any) {
37
+ const qwToken = 'sBy1ogROHqapzX0CcdoyjCl$7wAX1NzRpOPRUMrQGgN8J7jSxmMQWreOgkeheTFbylzpf8Gz1g_n0';
38
+
39
+ const { data: response } = await axios.post('https://Joey7938-joe-qw-api.hf.space/api/images/generations', data, {
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ Authorization: `Bearer ${qwToken}`,
 
 
 
 
43
  },
44
+ });
45
 
46
+ if (response.code !== undefined && response.code !== 0) {
47
+ throw new Error(response.message);
48
+ }
49
+
50
+ return response.data[0].b64_json;
51
+ }
src/utils/file-utils.ts CHANGED
@@ -90,3 +90,8 @@ export async function getImageBuffer(text: string, apiKey: string) {
90
  throw new Error(`生成图片失败,错误信息:${error}`);
91
  }
92
  }
 
 
 
 
 
 
90
  throw new Error(`生成图片失败,错误信息:${error}`);
91
  }
92
  }
93
+
94
+ export async function blobToArrayBuffer(blob:Blob) {
95
+ const arrayBuffer = await blob.arrayBuffer();
96
+ return arrayBuffer;
97
+ }