From e475c9d4738c2e0871f417fbed9eaa97e5195049 Mon Sep 17 00:00:00 2001 From: Cunninger <1803912219@qq.com> Date: Tue, 14 Jan 2025 18:20:37 +0800 Subject: [PATCH] Initial commit --- worker.js | 1545 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1545 insertions(+) create mode 100644 worker.js diff --git a/worker.js b/worker.js new file mode 100644 index 0000000..2f233b6 --- /dev/null +++ b/worker.js @@ -0,0 +1,1545 @@ +addEventListener('fetch', event => { + event.respondWith(handleRequest(event.request)); +}); + +async function handleRequest(request) { + const url = new URL(request.url); + + // 处理 CORS 预检请求 + if (request.method === 'OPTIONS') { + return new Response(null, { + headers: { + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Methods': 'POST, OPTIONS', + 'Access-Control-Allow-Headers': 'Content-Type, Authorization', + }, + }); + } + + // API路由处理 + switch (url.pathname) { + // 1. 通过图片URL识别 + case '/api/recognize/url': + if (request.method === 'POST') { + return handleImageUrlRecognition(request); + } + 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: '请识别图片中的内容,注意以下要求:\n' + + '对于数学公式和普通文本:\n' + + '1. 所有数学公式和数学符号都必须使用标准的LaTeX格式\n' + + '2. 行内公式使用单个$符号包裹,如:$x^2$\n' + + '3. 独立公式块使用两个$$符号包裹,如:$$\\sum_{i=1}^n i^2$$\n' + + '4. 普通文本保持原样,不要使用LaTeX格式\n' + + '5. 保持原文的段落格式和换行\n' + + '6. 明显的换行使用\\n表示\n' + + '7. 确保所有数学符号都被正确包裹在$或$$中\n\n' + + '对于验证码图片:\n' + + '1. 只输出验证码字符,不要加任何额外解释\n' + + '2. 忽略干扰线和噪点\n' + + '3. 注意区分相似字符,如0和O、1和l、2和Z等\n' + + '4. 验证码通常为4-6位字母数字组合\n\n' + + '不要输出任何额外的解释或说明' + }, + { type: 'image', image: imageId }, + ], + }, + ], + session_id: '1', + chat_id: '2', + id: '3', + }), + }); + + const data = await response.json(); + let result = data.choices[0]?.message?.content || '识别失败'; + + // 如果结果长度小于10且只包含字母数字,很可能是验证码 + if (result.length <= 10 && /^[A-Za-z0-9]+$/.test(result)) { + return new Response(JSON.stringify({ + success: true, + result: result.toUpperCase(), // 验证码统一转大写 + type: 'captcha' + }), { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }); + } + + // 其他情况(数学公式和普通文本)的处理 + result = result + .replace(/\\(/g, '\\(') + .replace(/\\)/g, '\\)') + .replace(/\n{3,}/g, '\n\n') + .replace(/([^\n])\n([^\n])/g, '$1\n$2') + .replace(/\$\s+/g, '$') + .replace(/\s+\$/g, '$') + .replace(/\$\$/g, '$$') + .trim(); + + return new Response(JSON.stringify({ + success: true, + result: result, + type: 'text' + }), { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + }, + }); +} + +function getHTML() { + const html = [ + '', + '', + '', + '', + '', + 'Qwen VL 智能识别系统', + + // 添加 MathJax 支持 + '', + '', + '', + '', + + '', + '', + '', + '', + '', + + '
', + '

Qwen VL 智能识别系统

', + '
基于通义千问大模型的多模态智能识别引擎
', + '
', + '📸', + '
', + '拖拽图片到这里,点击上传,或粘贴Base64图片内容
', + '支持复制粘贴图片', + '
', + '', + '', + '', + '
', + '
', + '
', + '
', + '识别结果', + '', + '
', + '
', + '
', + '', + '
', + '

识别历史

', + '
', + '
', + '', + '
', + + '', + + '', + '', + '' + ].join('\n'); + + return html; +} \ No newline at end of file