main
HuangHai 4 weeks ago
parent 7de92edb57
commit 8f28c9a26b

@ -21,7 +21,7 @@ from docx import Document
from docx.shared import Inches
from io import BytesIO
import html2text
import urllib.parse
# 初始化日志
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
@ -168,41 +168,61 @@ class SaveWordRequest(BaseModel):
@app.post("/api/save-word")
async def save_to_word(request: Request):
try:
data = await request.json()
save_request = SaveWordRequest(**data)
except ValidationError as e:
logger.error(f"请求体验证失败: {e.errors()}")
raise HTTPException(status_code=422, detail=e.errors())
# Parse request data
try:
data = await request.json()
html_content = data.get('html_content', '')
if not html_content:
raise ValueError("Empty HTML content")
except Exception as e:
logger.error(f"Request parsing failed: {str(e)}")
raise HTTPException(status_code=400, detail=f"Invalid request: {str(e)}")
# Convert HTML to text
try:
text_maker = html2text.HTML2Text()
text_maker.ignore_links = True
text_maker.ignore_images = True
text_content = text_maker.handle(html_content)
except Exception as e:
logger.error(f"HTML conversion failed: {str(e)}")
raise HTTPException(status_code=400, detail=f"HTML processing error: {str(e)}")
# Create Word document
try:
doc = Document()
doc.add_heading('小学数学问答', 0)
for para in text_content.split('\n\n'):
if para.strip():
doc.add_paragraph(para.strip())
except Exception as e:
logger.error(f"Document creation failed: {str(e)}")
raise HTTPException(status_code=500, detail=f"Document creation error: {str(e)}")
# Save to stream
try:
stream = BytesIO()
doc.save(stream)
stream.seek(0)
except Exception as e:
logger.error(f"Document saving failed: {str(e)}")
raise HTTPException(status_code=500, detail=f"Document saving error: {str(e)}")
# Return response
filename = "小学数学问答.docx"
encoded_filename = urllib.parse.quote(filename)
return StreamingResponse(
stream,
media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
headers={"Content-Disposition": f"attachment; filename*=UTF-8''{encoded_filename}"}
)
except HTTPException:
raise
except Exception as e:
logger.error(f"请求解析失败: {str(e)}")
raise HTTPException(status_code=400, detail="无效的请求格式")
# 转换HTML为纯文本
h = html2text.HTML2Text()
h.ignore_links = True
plain_text = h.handle(save_request.html)
# 创建Word文档
doc = Document()
doc.add_heading('小学数学问答', 0)
doc.add_paragraph(plain_text)
# 保存到内存中的字节流
file_stream = BytesIO()
doc.save(file_stream)
file_stream.seek(0)
# 获取文件内容并计算长度
file_content = file_stream.getvalue()
return StreamingResponse(
BytesIO(file_content),
media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
headers={
"Content-Disposition": "attachment; filename*=UTF-8''%E5%B0%8F%E5%AD%A6%E6%95%B0%E5%AD%A6%E9%97%AE%E7%AD%94.docx",
"Content-Length": str(len(file_content))
}
)
logger.error(f"Unexpected error: {str(e)}")
raise HTTPException(status_code=500, detail="Internal server error")
@app.post("/api/rag")
async def rag_stream(request: Request):

@ -0,0 +1,114 @@
D:\anaconda3\envs\rag\python.exe D:\dsWork\dsProject\dsRag\Start.py
D:\anaconda3\envs\rag\lib\site-packages\jieba\_compat.py:18: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.
import pkg_resources
2025-06-26 21:19:51,036 - INFO - loading projection weights from D:/Tencent_AILab_ChineseEmbedding/Tencent_AILab_ChineseEmbedding.txt
2025-06-26 21:19:52,660 - INFO - KeyedVectors lifecycle event {'msg': 'loaded (10000, 200) matrix of type float32 from D:/Tencent_AILab_ChineseEmbedding/Tencent_AILab_ChineseEmbedding.txt', 'binary': False, 'encoding': 'utf8', 'datetime': '2025-06-26T21:19:52.638637', 'gensim': '4.3.3', 'python': '3.10.18 | packaged by conda-forge | (main, Jun 4 2025, 14:42:04) [MSC v.1943 64 bit (AMD64)]', 'platform': 'Windows-10-10.0.19044-SP0', 'event': 'load_word2vec_format'}
2025-06-26 21:19:52,660 - INFO - 模型加载成功,词向量维度: 200
INFO: Started server process [23340]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
INFO: 10.10.21.20:9955 - "POST /api/save-word HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "D:\anaconda3\envs\rag\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 403, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "D:\anaconda3\envs\rag\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\fastapi\applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
raise exc
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
await self.app(scope, receive, _send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 714, in __call__
await self.middleware_stack(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 734, in app
await route.handle(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 288, in handle
await self.app(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 73, in app
response = await f(request)
File "D:\anaconda3\envs\rag\lib\site-packages\fastapi\routing.py", line 301, in app
raw_response = await run_endpoint_function(
File "D:\anaconda3\envs\rag\lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
File "D:\dsWork\dsProject\dsRag\Start.py", line 195, in save_to_word
doc._part.new_pic_inline(
File "D:\anaconda3\envs\rag\lib\site-packages\docx\parts\story.py", line 71, in new_pic_inline
rId, image = self.get_or_add_image(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\parts\story.py", line 37, in get_or_add_image
image_part = package.get_or_add_image_part(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\package.py", line 31, in get_or_add_image_part
return self.image_parts.get_or_add_image_part(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\package.py", line 74, in get_or_add_image_part
image = Image.from_file(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\image\image.py", line 41, in from_file
with open(path, "rb") as f:
OSError: [Errno 22] Invalid argument: '\n\n\n <title>小学数学中的模型</title>\n\n\n <h1>小学数学中的模型</h1>\n\n <h2>什么是数学模型?</h2>\n <p>数学模型是用数学语言描述现实世界中与数量有关的问题的方法。它不仅仅是数学表达式,更强调对现实问题的解释和应用。在小学数学中,模型思想是帮助学生理解数学与现实世界联系的重要途径。</p>\n\n <h2>小学数学中的主要模型</h2>\n <ul>\n <li>\n <h3>总量模型(加法模型)</h3>\n <p>描述总量与部分量之间的关系:<strong>总量 = 部分量 + 部分量</strong></p>\n <p>应用场景:计算图书总量、购物总价等。</p>\n </li>\n <li>\n <h3>路程模型(乘法模型)</h3>\n <p>描述距离、速度和时间的关系:<strong>距离 = 速度 × 时间</strong></p>\n <p>也可用于解决"总价=单价×数量"等问题。</p>\n </li>\n <li>\n <h3>植树模型</h3>\n <p>研究有规律排列的"洞"与植树数量之间的关系。</p>\n <p>应用场景:加油站设置、商业点规划等。</p>\n </li>\n <li>\n <h3>工程模型(归一问题)</h3>\n <p>解决工程队合作完成工程的时间问题。</p>\n <p>也可用于注水问题等类似场景。</p>\n </li>\n </ul>\n\n <h2>模型教学的重要性</h2>\n <p>通过模型教学可以:</p>\n <ul>\n <li>帮助学生理解数学概念的实际意义</li>\n <li>培养学生分析问题和解决问题的能力</li>\n <li>激发学生的想象力和创新意识</li>\n <li>建立数学与现实世界的联系</li>\n </ul>\n\n <h2>教学建议</h2>\n <p>在教学中可以通过:</p>\n <ul>\n <li>创设现实情境引发思考</li>\n <li>使用缺失信息的方法促进理解</li>\n <li>鼓励学生讲述与模型相关的故事</li>\n <li>组织小组讨论活动</li>\n </ul>\n\n'
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "D:\anaconda3\envs\rag\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 403, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "D:\anaconda3\envs\rag\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 60, in __call__
return await self.app(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\fastapi\applications.py", line 1054, in __call__
await super().__call__(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\middleware\errors.py", line 187, in __call__
raise exc
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\middleware\errors.py", line 165, in __call__
await self.app(scope, receive, _send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\middleware\exceptions.py", line 62, in __call__
await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 714, in __call__
await self.middleware_stack(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 734, in app
await route.handle(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 288, in handle
await self.app(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 76, in app
await wrap_app_handling_exceptions(app, request)(scope, receive, send)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
raise exc
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app
await app(scope, receive, sender)
File "D:\anaconda3\envs\rag\lib\site-packages\starlette\routing.py", line 73, in app
response = await f(request)
File "D:\anaconda3\envs\rag\lib\site-packages\fastapi\routing.py", line 301, in app
raw_response = await run_endpoint_function(
File "D:\anaconda3\envs\rag\lib\site-packages\fastapi\routing.py", line 212, in run_endpoint_function
return await dependant.call(**values)
File "D:\dsWork\dsProject\dsRag\Start.py", line 195, in save_to_word
doc._part.new_pic_inline(
File "D:\anaconda3\envs\rag\lib\site-packages\docx\parts\story.py", line 71, in new_pic_inline
rId, image = self.get_or_add_image(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\parts\story.py", line 37, in get_or_add_image
image_part = package.get_or_add_image_part(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\package.py", line 31, in get_or_add_image_part
return self.image_parts.get_or_add_image_part(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\package.py", line 74, in get_or_add_image_part
image = Image.from_file(image_descriptor)
File "D:\anaconda3\envs\rag\lib\site-packages\docx\image\image.py", line 41, in from_file
with open(path, "rb") as f:
OSError: [Errno 22] Invalid argument: '\n\n\n <title>小学数学中的模型</title>\n\n\n <h1>小学数学中的模型</h1>\n\n <h2>什么是数学模型?</h2>\n <p>数学模型是用数学语言描述现实世界中与数量有关的问题的方法。它不仅仅是数学表达式,更强调对现实问题的解释和应用。在小学数学中,模型思想是帮助学生理解数学与现实世界联系的重要途径。</p>\n\n <h2>小学数学中的主要模型</h2>\n <ul>\n <li>\n <h3>总量模型(加法模型)</h3>\n <p>描述总量与部分量之间的关系:<strong>总量 = 部分量 + 部分量</strong></p>\n <p>应用场景:计算图书总量、购物总价等。</p>\n </li>\n <li>\n <h3>路程模型(乘法模型)</h3>\n <p>描述距离、速度和时间的关系:<strong>距离 = 速度 × 时间</strong></p>\n <p>也可用于解决"总价=单价×数量"等问题。</p>\n </li>\n <li>\n <h3>植树模型</h3>\n <p>研究有规律排列的"洞"与植树数量之间的关系。</p>\n <p>应用场景:加油站设置、商业点规划等。</p>\n </li>\n <li>\n <h3>工程模型(归一问题)</h3>\n <p>解决工程队合作完成工程的时间问题。</p>\n <p>也可用于注水问题等类似场景。</p>\n </li>\n </ul>\n\n <h2>模型教学的重要性</h2>\n <p>通过模型教学可以:</p>\n <ul>\n <li>帮助学生理解数学概念的实际意义</li>\n <li>培养学生分析问题和解决问题的能力</li>\n <li>激发学生的想象力和创新意识</li>\n <li>建立数学与现实世界的联系</li>\n </ul>\n\n <h2>教学建议</h2>\n <p>在教学中可以通过:</p>\n <ul>\n <li>创设现实情境引发思考</li>\n <li>使用缺失信息的方法促进理解</li>\n <li>鼓励学生讲述与模型相关的故事</li>\n <li>组织小组讨论活动</li>\n </ul>\n\n'
INFO: 10.10.21.20:9963 - "POST /api/save-word HTTP/1.1" 500 Internal Server Error

@ -177,44 +177,33 @@
</div>
<script>
function saveToWord() {
const htmlContent = document.getElementById('dataArea').innerHTML;
if (!htmlContent || htmlContent === '等待问题...') {
alert('请先生成内容再保存!');
return;
}
fetch('/api/save-word', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({html: htmlContent})
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应不正常');
}
return response.blob();
})
.then(blob => {
if (blob.size === 0) {
throw new Error('文件内容为空');
}
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '小学数学问答.docx';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
})
.catch(error => {
console.error('保存Word文档出错:', error);
alert('保存Word文档失败: ' + error.message);
});
}
async function saveToWord() {
const htmlContent = document.getElementById('dataArea').innerHTML;
try {
const response = await fetch('/api/save-word', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ html_content: htmlContent })
});
if (!response.ok) throw new Error('请求失败');
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = '小学数学问答.docx';
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
a.remove();
} catch (error) {
alert('保存失败: ' + error.message);
}
}
</script>
</div>

Loading…
Cancel
Save