From a6a5241c269a70a388dc862ea3c08ee8a5a7a219 Mon Sep 17 00:00:00 2001 From: programmerWsy <113076850+Cunninger@users.noreply.github.com> Date: Mon, 13 Jan 2025 18:50:30 +0800 Subject: [PATCH] Update worker.js --- worker.js | 379 +++++++++++------------------------------------------- 1 file changed, 77 insertions(+), 302 deletions(-) diff --git a/worker.js b/worker.js index b2b525c..12269de 100644 --- a/worker.js +++ b/worker.js @@ -16,216 +16,86 @@ async function handleRequest(request) { }); } - // API路由处理 - switch (url.pathname) { - // 1. 通过图片URL识别 - case '/api/recognize/url': - if (request.method === 'POST') { - return handleImageUrlRecognition(request); + // 处理 POST 请求 + if (request.method === 'POST' && url.pathname === '/recognize') { + try { + const { token, imageId } = await request.json(); + + if (!token || !imageId) { + return new Response(JSON.stringify({ error: 'Missing token or imageId' }), { + status: 400, + headers: { 'Content-Type': 'application/json' }, + }); } - break; - // 2. 通过Base64识别 - case '/api/recognize/base64': - if (request.method === 'POST') { - return handleBase64Recognition(request); - } - break; - - // 3. 通过图片文件识别 (原有的/recognize端点) - case '/recognize': - if (request.method === 'POST') { - return handleFileRecognition(request); - } - break; - - // 返回前端界面 - case '/': - return new Response(getHTML(), { - headers: { 'Content-Type': 'text/html' }, - }); - } - - return new Response('Not Found', { status: 404 }); -} - -// 处理图片URL识别 -async function handleImageUrlRecognition(request) { - try { - const { token, imageUrl } = await request.json(); - - if (!token || !imageUrl) { - return new Response(JSON.stringify({ - error: 'Missing token or imageUrl' - }), { - status: 400, - headers: { 'Content-Type': 'application/json' }, - }); - } - - // 下载图片 - const imageResponse = await fetch(imageUrl); - const imageBlob = await imageResponse.blob(); - - // 上传到QwenLM - const formData = new FormData(); - formData.append('file', imageBlob); - - const uploadResponse = await fetch('https://chat.qwenlm.ai/api/v1/files/', { - method: 'POST', - headers: { - 'accept': 'application/json', - 'authorization': `Bearer ${token}`, - }, - body: formData, - }); - - const uploadData = await uploadResponse.json(); - if (!uploadData.id) throw new Error('File upload failed'); - - // 调用识别API - return await recognizeImage(token, uploadData.id); - } catch (error) { - return new Response(JSON.stringify({ - error: error.message || 'Internal Server Error' - }), { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }); - } -} - -// 处理Base64识别 -async function handleBase64Recognition(request) { - try { - const { token, base64Image } = await request.json(); - - if (!token || !base64Image) { - return new Response(JSON.stringify({ - error: 'Missing token or base64Image' - }), { - status: 400, - headers: { 'Content-Type': 'application/json' }, - }); - } - - // 转换Base64为Blob - const imageData = base64Image.startsWith('data:') ? - base64Image : - 'data:image/png;base64,' + base64Image; - - const response = await fetch(imageData); - const blob = await response.blob(); - - // 上传到QwenLM - const formData = new FormData(); - formData.append('file', blob); - - const uploadResponse = await fetch('https://chat.qwenlm.ai/api/v1/files/', { - method: 'POST', - headers: { - 'accept': 'application/json', - 'authorization': `Bearer ${token}`, - }, - body: formData, - }); - - const uploadData = await uploadResponse.json(); - if (!uploadData.id) throw new Error('File upload failed'); - - // 调用识别API - return await recognizeImage(token, uploadData.id); - } catch (error) { - return new Response(JSON.stringify({ - error: error.message || 'Internal Server Error' - }), { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }); - } -} - -// 处理文件识别 (原有功能) -async function handleFileRecognition(request) { - try { - const { token, imageId } = await request.json(); - - if (!token || !imageId) { - return new Response(JSON.stringify({ - error: 'Missing token or imageId' - }), { - status: 400, - headers: { 'Content-Type': 'application/json' }, - }); - } - - return await recognizeImage(token, imageId); - } catch (error) { - return new Response(JSON.stringify({ - error: error.message || 'Internal Server Error' - }), { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }); - } -} - -// 通用的识别函数 -async function recognizeImage(token, imageId) { - const response = await fetch('https://chat.qwenlm.ai/api/chat/completions', { - method: 'POST', - headers: { - 'accept': '*/*', - 'authorization': `Bearer ${token}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ - stream: false, - model: 'qwen-vl-max-latest', - messages: [ - { - role: 'user', - content: [ - { - type: 'text', - text: '请识别图片中的内容。对于数学公式和数学符号,请使用标准的LaTeX格式输出。' + - '要求:\n' + - '1. 所有数学公式和单个数学符号都要用LaTeX格式\n' + - '2. 普通文本保持原样\n' + - '3. 对于行内公式使用$单个符号$\n' + - '4. 对于独立公式块使用$$公式$$\n' + - '5. 严格保持原文的段落格式和换行\n' + - '6. 当文本明显换行时,使用\\n进行换行处理' - }, - { type: 'image', image: imageId }, - ], + // 调用 QwenLM API + const response = await fetch('https://chat.qwenlm.ai/api/chat/completions', { + method: 'POST', + headers: { + 'accept': '*/*', + 'authorization': `Bearer ${token}`, + 'Content-Type': 'application/json', }, - ], - session_id: '1', - chat_id: '2', - id: '3', - }), - }); + body: JSON.stringify({ + stream: false, + model: 'qwen-vl-max-latest', + messages: [ + { + role: 'user', + content: [ + { + type: 'text', + text: '请识别图片中的内容。对于数学公式和数学符号,请使用标准的LaTeX格式输出。' + + '要求:\n' + + '1. 所有数学公式和单个数学符号都要用LaTeX格式\n' + + '2. 普通文本保持原样\n' + + '3. 对于行内公式使用$单个符号$\n' + + '4. 对于独立公式块使用$$公式$$\n' + + '5. 严格保持原文的段落格式和换行\n' + + '6. 当文本明显换行时,使用\\n进行换行处理\n' + + '请尽可能精确地转换每个数学符号并保持原始排版格式。' + }, + { type: 'image', image: imageId }, // 使用上传后的图片 ID + ], + }, + ], + session_id: '1', + chat_id: '2', + id: '3', + }), + }); - const data = await response.json(); - - // 处理识别结果 - let result = data.choices[0]?.message?.content || '识别失败'; - result = result - .replace(/\\(/g, '\\(') - .replace(/\\)/g, '\\)') - .replace(/\n{3,}/g, '\n\n') - .replace(/([^\n])\n([^\n])/g, '$1\n$2') - .trim(); + const data = await response.json(); + + // 对识别结果进行后处理,确保LaTeX格式正确并保持换行 + let result = data.choices[0]?.message?.content || '识别失败'; + result = result + // 修复可能的LaTeX格式问题 + .replace(/\\(/g, '\\(') + .replace(/\\)/g, '\\)') + // 确保连续的换行符被保留(2个以上的换行符表示段落分隔) + .replace(/\n{3,}/g, '\n\n') + // 保留单个换行符,不合并 + .replace(/([^\n])\n([^\n])/g, '$1\n$2') + .trim(); - return new Response(JSON.stringify({ - success: true, - result: result - }), { - headers: { - 'Content-Type': 'application/json', - 'Access-Control-Allow-Origin': '*', - }, + return new Response(JSON.stringify({ ...data, choices: [{ message: { content: result } }] }), { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }); + } catch (error) { + return new Response(JSON.stringify({ error: 'Internal Server Error' }), { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }); + } + } + + // 返回前端界面 + return new Response(getHTML(), { + headers: { 'Content-Type': 'text/html' }, }); } @@ -686,30 +556,6 @@ function getHTML() { ' .copy-btn.copied {', ' background: #27ae60;', ' }', - - ' /* Base64输入相关样式 */', - ' #base64Input {', - ' width: 100%;', - ' height: 100px;', - ' padding: 10px;', - ' margin-top: 10px;', - ' border: 1px solid #dcdde1;', - ' border-radius: 8px;', - ' resize: vertical;', - ' }', - ' .toggle-btn {', - ' background: #3498db;', - ' color: white;', - ' border: none;', - ' padding: 8px 15px;', - ' border-radius: 5px;', - ' cursor: pointer;', - ' margin-top: 10px;', - ' transition: background 0.3s ease;', - ' }', - ' .toggle-btn:hover {', - ' background: #2980b9;', - ' }', '', '', '
', @@ -732,11 +578,9 @@ function getHTML() { '