将literature改名为paper
This commit is contained in:
+1
-1
@@ -743,7 +743,7 @@
|
||||
<div class="navbar-menu-item" onclick="window.location.href='lab.html'">Project</div>
|
||||
<div class="navbar-menu-item active">Device</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='reports.html'">Reports</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='literature.html'">Literature</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='paper.html'">Paper</div>
|
||||
</div>
|
||||
<div class="navbar-right">
|
||||
<a href="https://beta.obscura.work/lab/device-register.html" target="_blank" class="btn btn-primary">
|
||||
|
||||
@@ -747,7 +747,7 @@
|
||||
<div class="navbar-menu-item active">Project</div>
|
||||
<div class="navbar-menu-item" onclick="window.open('device.html', '_blank')">Device</div>
|
||||
<div class="navbar-menu-item" onclick="window.open('reports.html', '_blank')">Reports</div>
|
||||
<div class="navbar-menu-item" onclick="window.open('literature.html', '_blank')">Literature</div>
|
||||
<div class="navbar-menu-item" onclick="window.open('Paper.html', '_blank')">Paper</div>
|
||||
</div>
|
||||
<div class="navbar-right">
|
||||
<a href="https://beta.obscura.work/lab/device-register.html" target="_blank" class="btn btn-primary">
|
||||
@@ -908,9 +908,9 @@
|
||||
<i class="bi bi-journal-text"></i>
|
||||
<span>Memo</span>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="event.preventDefault(); window.open('https://beta.obscura.work/lab/literature.html?projectId=' + currentProjectId, '_blank')">
|
||||
<div class="sidebar-item" onclick="event.preventDefault(); window.open('https://beta.obscura.work/lab/Paper.html?projectId=' + currentProjectId, '_blank')">
|
||||
<i class="bi bi-book"></i>
|
||||
<span>Literature</span>
|
||||
<span>Paper</span>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="downloadProjectReport(currentProjectId)">
|
||||
<i class="bi bi-file-earmark-text"></i>
|
||||
@@ -2827,7 +2827,7 @@
|
||||
`;
|
||||
document.body.appendChild(loadingToast);
|
||||
|
||||
let projectResult, literatureResult;
|
||||
let projectResult, paperResult;
|
||||
|
||||
|
||||
// 3. Generate new project report
|
||||
@@ -2843,24 +2843,24 @@
|
||||
|
||||
projectResult = await analyzeResponse.json();
|
||||
|
||||
// 2. Get literature analysis report
|
||||
const literatureReportResponse = await fetch(`${API_BASE_URL}/references/${projectId}/summary_report`, {
|
||||
// 2. Get paper analysis report
|
||||
const paperReportResponse = await fetch(`${API_BASE_URL}/references/${projectId}/summary_report`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (literatureReportResponse.status === 404 || !literatureReportResponse.ok) {
|
||||
console.log('No saved literature analysis report found, generating new report...');
|
||||
const literatureAnalyzeResponse = await fetch(`${API_BASE_URL}/references/${projectId}/analyze_report`, {
|
||||
if (paperReportResponse.status === 404 || !paperReportResponse.ok) {
|
||||
console.log('No saved paper analysis report found, generating new report...');
|
||||
const paperAnalyzeResponse = await fetch(`${API_BASE_URL}/references/${projectId}/analyze_report`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (!literatureAnalyzeResponse.ok) {
|
||||
console.log('Failed to generate literature analysis report, will only include project report');
|
||||
literatureResult = null;
|
||||
if (!paperAnalyzeResponse.ok) {
|
||||
console.log('Failed to generate paper analysis report, will only include project report');
|
||||
paperResult = null;
|
||||
} else {
|
||||
// Re-fetch generated report
|
||||
const newReportResponse = await fetch(`${API_BASE_URL}/references/${projectId}/summary_report`, {
|
||||
@@ -2870,17 +2870,17 @@
|
||||
});
|
||||
|
||||
if (newReportResponse.ok) {
|
||||
literatureResult = await newReportResponse.json();
|
||||
paperResult = await newReportResponse.json();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
literatureResult = await literatureReportResponse.json();
|
||||
paperResult = await paperReportResponse.json();
|
||||
}
|
||||
|
||||
// 3. Merge reports
|
||||
const combinedReport = {
|
||||
project_report: projectResult,
|
||||
literature_analysis: literatureResult || "No literature analysis report found"
|
||||
paper_analysis: paperResult || "No analysis report found"
|
||||
};
|
||||
|
||||
// 4. Remove loading prompt
|
||||
|
||||
@@ -1335,132 +1335,6 @@ async def complete_experiment(
|
||||
print(f"Error completing experiment: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=f"Failed to complete experiment: {str(e)}")
|
||||
|
||||
@app.get("/lab/experiments/{experiment_id}/analyze")
|
||||
async def analyze_data(
|
||||
experiment_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""分析实验数据"""
|
||||
db = await get_database()
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
sessions = []
|
||||
total_points = 0
|
||||
total_duration = 0
|
||||
devices_set = set()
|
||||
sensors_count = 0
|
||||
|
||||
async for session in db.experiment_sessions.find({
|
||||
"experiment_id": ObjectId(experiment_id)
|
||||
}):
|
||||
# 计算会话持续时间
|
||||
end_time = session.get("end_time") or datetime.now(timezone.utc)
|
||||
duration = (end_time - session["start_time"]).total_seconds()
|
||||
total_duration += duration
|
||||
|
||||
# 转换时间戳为毫秒
|
||||
start_ms = int(session["start_time"].timestamp() * 1000)
|
||||
end_ms = int(end_time.timestamp() * 1000)
|
||||
|
||||
# 统计设备和传感器数量
|
||||
session_devices = session.get("devices", [])
|
||||
for device in session_devices:
|
||||
devices_set.add(device["serial_number"])
|
||||
sensors_count += len(device.get("sensors", []))
|
||||
|
||||
# 获取会话数据点数
|
||||
session_points = 0
|
||||
for device in session_devices:
|
||||
stream_key = f"experiment:{experiment_id}:{device['serial_number']}"
|
||||
await redis.select(200)
|
||||
|
||||
# 使用 xrange 获取指定时间范围内的数据
|
||||
data_points = await redis.xrange(
|
||||
stream_key,
|
||||
min=str(start_ms),
|
||||
max=str(end_ms)
|
||||
)
|
||||
# 计算数据点数量
|
||||
points = len(data_points)
|
||||
session_points += points
|
||||
|
||||
# 累加到总数据点
|
||||
total_points += session_points
|
||||
|
||||
sessions.append({
|
||||
"session_id": str(session["_id"]),
|
||||
"duration": duration,
|
||||
"data_points": session_points
|
||||
})
|
||||
|
||||
if not sessions:
|
||||
raise HTTPException(status_code=404, detail="没有找到实验会话数据")
|
||||
|
||||
# 准备分析数据
|
||||
experiment_info = {
|
||||
"total_sessions": len(sessions),
|
||||
"total_duration": total_duration,
|
||||
"total_points": total_points,
|
||||
"device_stats": {
|
||||
"total_devices": len(devices_set),
|
||||
"total_sensors": sensors_count
|
||||
},
|
||||
"sessions": sessions
|
||||
}
|
||||
|
||||
# 发送统计数据进行分析
|
||||
analysis_result = await analyze_experiment_data(experiment_info)
|
||||
|
||||
if not analysis_result:
|
||||
raise HTTPException(status_code=500, detail="生成分析报告失败")
|
||||
|
||||
# 保存分析结果到db201
|
||||
await redis.select(201)
|
||||
report_key = f"experiment_report:{experiment_id}"
|
||||
await redis.set(report_key, json.dumps(analysis_result))
|
||||
|
||||
return analysis_result
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error analyzing experiment data: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
@app.get("/lab/experiments/{experiment_id}/report")
|
||||
async def get_saved_report(
|
||||
experiment_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""从 Redis db201 读取已保存的实验报告"""
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
# 选择 db201
|
||||
await redis.select(201)
|
||||
report_key = f"experiment_report:{experiment_id}"
|
||||
|
||||
# 获取已保存的报告
|
||||
existing_report = await redis.get(report_key)
|
||||
|
||||
if not existing_report:
|
||||
raise HTTPException(status_code=404, detail="No saved experiment report found")
|
||||
|
||||
# 返回报告
|
||||
return json.loads(existing_report)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error getting experiment report: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
# 修改进入实验的路由,添加状态检查
|
||||
@app.get("/lab/experiments/{experiment_id}")
|
||||
@@ -1650,14 +1524,322 @@ async def analyze_project_data(project_data):
|
||||
return None
|
||||
|
||||
|
||||
# 创建线程池
|
||||
exppro_analysis_thread_pool = ThreadPoolExecutor(max_workers=3)
|
||||
|
||||
@app.get("/lab/experiments/{experiment_id}/analyze")
|
||||
async def analyze_data(
|
||||
experiment_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""启动实验数据分析"""
|
||||
db = await get_database()
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
# 检查是否已经有正在进行的分析任务
|
||||
await redis.select(201)
|
||||
status_key = f"experiment_analysis_status:{experiment_id}"
|
||||
current_status = await redis.get(status_key)
|
||||
|
||||
if current_status:
|
||||
status_data = json.loads(current_status)
|
||||
if status_data.get("status") == "processing":
|
||||
return {
|
||||
"message": "实验分析任务正在进行中",
|
||||
"status": "processing",
|
||||
"experiment_id": experiment_id,
|
||||
"start_time": status_data.get("start_time")
|
||||
}
|
||||
|
||||
# 记录分析开始状态
|
||||
status_data = {
|
||||
"status": "processing",
|
||||
"start_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
|
||||
# 在新线程中运行分析任务
|
||||
exppro_analysis_thread_pool.submit(
|
||||
run_experiment_analysis_in_thread,
|
||||
experiment_id
|
||||
)
|
||||
|
||||
return {
|
||||
"message": "实验分析任务已启动",
|
||||
"status": "processing",
|
||||
"experiment_id": experiment_id,
|
||||
"start_time": status_data["start_time"]
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error starting experiment analysis: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
def run_experiment_analysis_in_thread(experiment_id: str):
|
||||
"""在独立线程中运行实验分析任务"""
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
try:
|
||||
loop.run_until_complete(
|
||||
process_experiment_analysis(experiment_id)
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error in analysis thread: {str(e)}")
|
||||
finally:
|
||||
loop.close()
|
||||
async def process_experiment_analysis(experiment_id: str):
|
||||
"""后台处理实验分析任务"""
|
||||
db = await get_database()
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
sessions = []
|
||||
total_points = 0
|
||||
total_duration = 0
|
||||
devices_set = set()
|
||||
sensors_count = 0
|
||||
|
||||
async for session in db.experiment_sessions.find({
|
||||
"experiment_id": ObjectId(experiment_id)
|
||||
}):
|
||||
# 计算会话持续时间
|
||||
end_time = session.get("end_time") or datetime.now(timezone.utc)
|
||||
duration = (end_time - session["start_time"]).total_seconds()
|
||||
total_duration += duration
|
||||
|
||||
# 转换时间戳为毫秒
|
||||
start_ms = int(session["start_time"].timestamp() * 1000)
|
||||
end_ms = int(end_time.timestamp() * 1000)
|
||||
|
||||
# 统计设备和传感器数量
|
||||
session_devices = session.get("devices", [])
|
||||
for device in session_devices:
|
||||
devices_set.add(device["serial_number"])
|
||||
sensors_count += len(device.get("sensors", []))
|
||||
|
||||
# 获取会话数据点数
|
||||
session_points = 0
|
||||
for device in session_devices:
|
||||
stream_key = f"experiment:{experiment_id}:{device['serial_number']}"
|
||||
await redis.select(200)
|
||||
|
||||
# 使用 xrange 获取指定时间范围内的数据
|
||||
data_points = await redis.xrange(
|
||||
stream_key,
|
||||
min=str(start_ms),
|
||||
max=str(end_ms)
|
||||
)
|
||||
# 计算数据点数量
|
||||
points = len(data_points)
|
||||
session_points += points
|
||||
|
||||
# 累加到总数据点
|
||||
total_points += session_points
|
||||
|
||||
sessions.append({
|
||||
"session_id": str(session["_id"]),
|
||||
"duration": duration,
|
||||
"data_points": session_points
|
||||
})
|
||||
|
||||
if not sessions:
|
||||
raise HTTPException(status_code=404, detail="没有找到实验会话数据")
|
||||
|
||||
experiment_info = {
|
||||
"total_sessions": len(sessions),
|
||||
"total_duration": total_duration,
|
||||
"total_points": total_points,
|
||||
"device_stats": {
|
||||
"total_devices": len(devices_set),
|
||||
"total_sensors": sensors_count
|
||||
},
|
||||
"sessions": sessions
|
||||
}
|
||||
|
||||
# 执行分析
|
||||
analysis_result = await analyze_experiment_data(experiment_info)
|
||||
|
||||
if analysis_result:
|
||||
# 保存分析结果
|
||||
await redis.select(201)
|
||||
report_key = f"experiment_report:{experiment_id}"
|
||||
await redis.set(report_key, json.dumps(analysis_result))
|
||||
|
||||
# 更新状态为完成
|
||||
status_key = f"experiment_analysis_status:{experiment_id}"
|
||||
status_data = {
|
||||
"status": "completed",
|
||||
"completion_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
else:
|
||||
# 更新失败状态
|
||||
status_data = {
|
||||
"status": "failed",
|
||||
"error": "Failed to generate analysis result",
|
||||
"completion_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error in background experiment analysis: {str(e)}")
|
||||
try:
|
||||
await redis.select(201)
|
||||
status_key = f"experiment_analysis_status:{experiment_id}"
|
||||
status_data = {
|
||||
"status": "failed",
|
||||
"error": str(e),
|
||||
"completion_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
except Exception as redis_error:
|
||||
print(f"Error updating Redis status: {redis_error}")
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
@app.get("/lab/experiments/{experiment_id}/analysis_status")
|
||||
async def get_experiment_analysis_status(
|
||||
experiment_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""获取实验分析任务的状态"""
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
await redis.select(201)
|
||||
status_key = f"experiment_analysis_status:{experiment_id}"
|
||||
status_data = await redis.get(status_key)
|
||||
|
||||
if not status_data:
|
||||
return {
|
||||
"status": "not_started",
|
||||
"experiment_id": experiment_id
|
||||
}
|
||||
|
||||
return json.loads(status_data)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error getting analysis status: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
@app.get("/lab/experiments/{experiment_id}/report")
|
||||
async def get_saved_report(
|
||||
experiment_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""从 Redis db201 读取已保存的实验报告"""
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
# 选择 db201
|
||||
await redis.select(201)
|
||||
report_key = f"experiment_report:{experiment_id}"
|
||||
|
||||
# 获取已保存的报告
|
||||
existing_report = await redis.get(report_key)
|
||||
|
||||
if not existing_report:
|
||||
raise HTTPException(status_code=404, detail="No saved experiment report found")
|
||||
|
||||
# 返回报告
|
||||
return json.loads(existing_report)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error getting experiment report: {e}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
|
||||
# 项目分析的异步实现类似:
|
||||
@app.get("/lab/projects/{project_id}/analyze")
|
||||
async def analyze_project_data_endpoint(
|
||||
project_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""分析项目数据"""
|
||||
"""启动项目数据分析"""
|
||||
db = await get_database()
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
# 检查是否已经有正在进行的分析任务
|
||||
await redis.select(202)
|
||||
status_key = f"project_analysis_status:{project_id}"
|
||||
current_status = await redis.get(status_key)
|
||||
|
||||
if current_status:
|
||||
status_data = json.loads(current_status)
|
||||
if status_data.get("status") == "processing":
|
||||
return {
|
||||
"message": "项目分析任务正在进行中",
|
||||
"status": "processing",
|
||||
"project_id": project_id,
|
||||
"start_time": status_data.get("start_time")
|
||||
}
|
||||
|
||||
# 记录分析开始状态
|
||||
status_data = {
|
||||
"status": "processing",
|
||||
"start_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
|
||||
# 在新线程中运行分析任务
|
||||
exppro_analysis_thread_pool.submit(
|
||||
run_project_analysis_in_thread,
|
||||
project_id
|
||||
)
|
||||
|
||||
return {
|
||||
"message": "项目分析任务已启动",
|
||||
"status": "processing",
|
||||
"project_id": project_id,
|
||||
"start_time": status_data["start_time"]
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error starting project analysis: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
def run_project_analysis_in_thread(project_id: str):
|
||||
"""在独立线程中运行项目分析任务"""
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
try:
|
||||
loop.run_until_complete(
|
||||
process_project_analysis(project_id)
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error in analysis thread: {str(e)}")
|
||||
finally:
|
||||
loop.close()
|
||||
|
||||
async def process_project_analysis(project_id: str):
|
||||
"""后台处理项目分析任务"""
|
||||
db = await get_database()
|
||||
redis = await get_redis()
|
||||
|
||||
@@ -1740,21 +1922,73 @@ async def analyze_project_data_endpoint(
|
||||
"experiment_reports": all_experiment_reports
|
||||
}
|
||||
|
||||
# 发送数据进行项目级分析
|
||||
# 执行分析
|
||||
analysis_result = await analyze_project_data(project_data)
|
||||
|
||||
if not analysis_result:
|
||||
raise HTTPException(status_code=500, detail="Failed to generate project analysis report")
|
||||
|
||||
# 将分析结果保存到Redis db202
|
||||
if analysis_result:
|
||||
# 保存分析结果
|
||||
await redis.select(202)
|
||||
report_key = f"project_report:{project_id}"
|
||||
await redis.set(report_key, json.dumps(analysis_result))
|
||||
|
||||
# 更新状态为完成
|
||||
status_key = f"project_analysis_status:{project_id}"
|
||||
status_data = {
|
||||
"status": "completed",
|
||||
"completion_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
else:
|
||||
# 更新失败状态
|
||||
status_data = {
|
||||
"status": "failed",
|
||||
"error": "Failed to generate analysis result",
|
||||
"completion_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error in background project analysis: {str(e)}")
|
||||
try:
|
||||
await redis.select(202)
|
||||
status_key = f"project_analysis_status:{project_id}"
|
||||
status_data = {
|
||||
"status": "failed",
|
||||
"error": str(e),
|
||||
"completion_time": datetime.now(timezone.utc).isoformat()
|
||||
}
|
||||
await redis.set(status_key, json.dumps(status_data))
|
||||
except Exception as redis_error:
|
||||
print(f"Error updating Redis status: {redis_error}")
|
||||
finally:
|
||||
try:
|
||||
await redis.aclose()
|
||||
except Exception as e:
|
||||
print(f"Error closing Redis connection: {e}")
|
||||
|
||||
@app.get("/lab/projects/{project_id}/analysis_status")
|
||||
async def get_project_analysis_status(
|
||||
project_id: str,
|
||||
current_user: UserModel = Depends(get_current_user)
|
||||
):
|
||||
"""获取项目分析任务的状态"""
|
||||
redis = await get_redis()
|
||||
|
||||
try:
|
||||
await redis.select(202)
|
||||
report_key = f"project_report:{project_id}"
|
||||
await redis.set(report_key, json.dumps(analysis_result))
|
||||
status_key = f"project_analysis_status:{project_id}"
|
||||
status_data = await redis.get(status_key)
|
||||
|
||||
return analysis_result
|
||||
if not status_data:
|
||||
return {
|
||||
"status": "not_started",
|
||||
"project_id": project_id
|
||||
}
|
||||
|
||||
return json.loads(status_data)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error analyzing project data: {e}")
|
||||
print(f"Error getting analysis status: {str(e)}")
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
finally:
|
||||
try:
|
||||
@@ -2060,18 +2294,18 @@ async def get_reference_report(
|
||||
# 修改函数定义为异步函数
|
||||
async def analyze_reference_summary(reference_data):
|
||||
system_prompt = """
|
||||
You are an AI assistant responsible for analyzing literature reports.
|
||||
You will summarize and analyze all literature reports and generate a comprehensive analysis report in JSON format.
|
||||
You are an AI assistant responsible for analyzing paper reports.
|
||||
You will summarize and analyze all paper reports and generate a comprehensive analysis report in JSON format.
|
||||
The JSON structure must strictly follow the provided template.
|
||||
"""
|
||||
|
||||
user_prompt = f"""Analyze the following literature reports:
|
||||
Literature reports: {json.dumps(reference_data, ensure_ascii=False)}
|
||||
user_prompt = f"""Analyze the following paper reports:
|
||||
Paper reports: {json.dumps(reference_data, ensure_ascii=False)}
|
||||
|
||||
Generate a JSON response with the following structure:
|
||||
|
||||
{{
|
||||
"Literature Summary Report": {{
|
||||
"Paper Summary Report": {{
|
||||
"overview": {{
|
||||
"total_papers": "[Number of papers]",
|
||||
"time_range": {{"start_year": "[Start year]", "end_year": "[End year]"}},
|
||||
@@ -2094,11 +2328,11 @@ async def analyze_reference_summary(reference_data):
|
||||
}},
|
||||
"future_directions": {{
|
||||
"potential_applications": "[Potential future applications]",
|
||||
"methodological_suggestions": "[Methodological suggestions based on literature summary]"
|
||||
"methodological_suggestions": "[Methodological suggestions based on paper summary]"
|
||||
}},
|
||||
"impact_assessment": {{
|
||||
"academic_influence": "[Summarize the academic influence of the literature]",
|
||||
"practical_value": "[Summarize the practical value of the literature]"
|
||||
"academic_influence": "[Summarize the academic influence of the paper]",
|
||||
"practical_value": "[Summarize the practical value of the paper]"
|
||||
}}
|
||||
}}
|
||||
}}
|
||||
@@ -3073,13 +3307,13 @@ async def analyze_long_document_async(content: str) -> List[dict]:
|
||||
print(f"\n开始分析第 {i+1}/{len(segments)} 个段落...")
|
||||
|
||||
system_prompt = f"""
|
||||
You are an AI assistant tasked with analyzing part {i+1} of {len(segments)} of an academic literature.
|
||||
You are an AI assistant tasked with analyzing part {i+1} of {len(segments)} of an academic paper.
|
||||
Generate a comprehensive analysis in JSON format covering both basic information and content analysis.
|
||||
Note that this is part {i+1} of a longer document, so focus on the content provided.
|
||||
The JSON structure must strictly follow the provided template.
|
||||
"""
|
||||
|
||||
user_prompt = f"""Analyze the following literature segment and extract all relevant information:
|
||||
user_prompt = f"""Analyze the following paper segment and extract all relevant information:
|
||||
Content: {segment}
|
||||
|
||||
Generate a JSON response with the following structure:
|
||||
@@ -3130,7 +3364,7 @@ async def merge_analysis_results(results: List[dict]) -> dict:
|
||||
print(f"开始合并 {len(results)} 个分析结果...")
|
||||
|
||||
system_prompt = """
|
||||
You are an AI assistant tasked with merging multiple analysis results of different parts of the same academic literature.
|
||||
You are an AI assistant tasked with merging multiple analysis results of different parts of the same academic paper.
|
||||
Generate a comprehensive merged analysis in JSON format.
|
||||
The JSON structure must strictly follow the provided template.
|
||||
Ensure the merged result is coherent and eliminates redundancy.
|
||||
@@ -3174,12 +3408,12 @@ async def merge_analysis_results(results: List[dict]) -> dict:
|
||||
async def analyze_reference_document_async(content: str):
|
||||
"""分析文献的基本信息和内容"""
|
||||
system_prompt = """
|
||||
You are an AI assistant tasked with analyzing academic literature.
|
||||
You are an AI assistant tasked with analyzing academic paper.
|
||||
Generate a comprehensive analysis in JSON format covering both basic information and content analysis.
|
||||
The JSON structure must strictly follow the provided template.
|
||||
"""
|
||||
|
||||
user_prompt = f"""Analyze the following literature and extract all relevant information:
|
||||
user_prompt = f"""Analyze the following paper and extract all relevant information:
|
||||
Content: {content}
|
||||
|
||||
Generate a JSON response with the following structure:
|
||||
@@ -3211,12 +3445,12 @@ async def analyze_reference_document_async(content: str):
|
||||
async def analyze_reference_value_async(content_analysis: dict):
|
||||
"""基于内容分析结果评估文献的价值"""
|
||||
system_prompt = """
|
||||
You are an AI assistant tasked with evaluating the value of academic literature based on its content analysis.
|
||||
You are an AI assistant tasked with evaluating the value of academic paper based on its content analysis.
|
||||
Generate a comprehensive value evaluation in JSON format.
|
||||
The JSON structure must strictly follow the provided template.
|
||||
"""
|
||||
|
||||
user_prompt = f"""Based on the following content analysis, evaluate the literature's value:
|
||||
user_prompt = f"""Based on the following content analysis, evaluate the paper's value:
|
||||
Content Analysis: {json.dumps(content_analysis, ensure_ascii=False)}
|
||||
|
||||
Generate a JSON response with the following structure:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Literature Analysis</title>
|
||||
<title>Paper Analysis</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/font/bootstrap-icons.min.css">
|
||||
<style>
|
||||
@@ -356,7 +356,7 @@
|
||||
<div class="navbar-menu-item" onclick="window.location.href='lab.html'">Project</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='device.html'">Device</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='reports.html'">Reports</div>
|
||||
<div class="navbar-menu-item active" onclick="window.location.href='literature.html'">Literature</div>
|
||||
<div class="navbar-menu-item active" onclick="window.location.href='Paper.html'">Paper</div>
|
||||
</div>
|
||||
<div class="navbar-right">
|
||||
<a href="https://beta.obscura.work/lab/device.html" target="_blank" class="btn btn-primary">
|
||||
@@ -389,9 +389,9 @@
|
||||
|
||||
<!-- 项目文献页面的侧边栏 -->
|
||||
<div class="sidebar-menu hidden" id="projectDetailSidebar">
|
||||
<div class="sidebar-item" onclick="showLiteratureList()">
|
||||
<div class="sidebar-item" onclick="showPaperList()">
|
||||
<i class="bi bi-list-ul"></i>
|
||||
<span>Literature List</span>
|
||||
<span>Paper List</span>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="downloadReferenceReport()">
|
||||
<i class="bi bi-file-earmark-text"></i>
|
||||
@@ -421,8 +421,8 @@
|
||||
<!-- 项目文献详情页面 -->
|
||||
<div id="projectDetailPage" class="content-body hidden">
|
||||
<div class="content-header d-flex justify-content-between align-items-center">
|
||||
<h3 class="content-title" id="referenceAnalysisTitle">Literature Analysis</h3>
|
||||
<button class="btn btn-info" onclick="uploadLiterature()">
|
||||
<h3 class="content-title" id="referenceAnalysisTitle">Paper Analysis</h3>
|
||||
<button class="btn btn-info" onclick="uploadPaper()">
|
||||
<i class="bi bi-upload me-2"></i>
|
||||
Upload
|
||||
</button>
|
||||
@@ -433,9 +433,9 @@
|
||||
</div>
|
||||
|
||||
<!-- 文献分析报告页面 -->
|
||||
<div id="literatureReportPage" class="content-body hidden">
|
||||
<div id="paperReportPage" class="content-body hidden">
|
||||
<div class="content-header d-flex justify-content-between align-items-center">
|
||||
<h3 class="content-title" id="literatureReportTitle">Literature Summary Report</h3>
|
||||
<h3 class="content-title" id="paperReportTitle">Paper Summary Report</h3>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-infoy" onclick="regenerateReport()">
|
||||
<i class="bi bi-arrow-clockwise me-2"></i>
|
||||
@@ -447,7 +447,7 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="literatureReportContent" class="mt-4">
|
||||
<div id="paperReportContent" class="mt-4">
|
||||
<!-- 报告内容将在这里动态加载 -->
|
||||
</div>
|
||||
</div>
|
||||
@@ -564,7 +564,7 @@
|
||||
// 隐藏其他页面和侧边栏
|
||||
document.getElementById('projectDetailPage').classList.add('hidden');
|
||||
document.getElementById('projectDetailSidebar').classList.add('hidden');
|
||||
document.getElementById('literatureReportPage').classList.add('hidden');
|
||||
document.getElementById('paperReportPage').classList.add('hidden');
|
||||
|
||||
currentProjectId = null;
|
||||
// 重新加载项目列表数据
|
||||
@@ -584,14 +584,14 @@
|
||||
document.getElementById('projectDetailSidebar').classList.remove('hidden');
|
||||
|
||||
// 隐藏报告页面
|
||||
document.getElementById('literatureReportPage').classList.add('hidden');
|
||||
document.getElementById('paperReportPage').classList.add('hidden');
|
||||
|
||||
document.getElementById('referenceAnalysisTitle').textContent = `Literature Analysis - ${projectName}`;
|
||||
document.getElementById('referenceAnalysisTitle').textContent = `Paper Analysis - ${projectName}`;
|
||||
|
||||
await loadReferences(projectId);
|
||||
}
|
||||
|
||||
// Add show literature analysis page function
|
||||
// Add show paper analysis page function
|
||||
async function showReferenceAnalysis() {
|
||||
try {
|
||||
// Hide other pages
|
||||
@@ -599,22 +599,22 @@
|
||||
page.classList.remove('active');
|
||||
});
|
||||
|
||||
// Show literature analysis page
|
||||
// Show paper analysis page
|
||||
document.getElementById('referenceAnalysisPage').classList.add('active');
|
||||
|
||||
// Set title
|
||||
document.getElementById('referenceAnalysisTitle').textContent =
|
||||
`Literature Analysis - ${document.getElementById('projectDetailTitle').textContent}`;
|
||||
`Paper Analysis - ${document.getElementById('projectDetailTitle').textContent}`;
|
||||
|
||||
// Load literature list
|
||||
// Load paper list
|
||||
await loadReferences(currentProjectId);
|
||||
} catch (error) {
|
||||
console.error('Failed to show literature analysis page:', error);
|
||||
alert('Failed to show literature analysis page, please try again');
|
||||
console.error('Failed to show Paper analysis page:', error);
|
||||
alert('Failed to show Paper analysis page, please try again');
|
||||
}
|
||||
}
|
||||
|
||||
// Literature card rendering function
|
||||
// paper card rendering function
|
||||
function renderReferenceCard(reference, projectId) {
|
||||
const uploadTime = reference.upload_time;
|
||||
const cardId = `reference-${reference._id}`;
|
||||
@@ -629,7 +629,7 @@
|
||||
<div class="spinner-border spinner-border-sm text-primary me-2" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<span>Analyzing literature content...</span>
|
||||
<span>Analyzing Paper content...</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
@@ -659,12 +659,12 @@
|
||||
`;
|
||||
}
|
||||
|
||||
// Load literature list function
|
||||
// Load paper list function
|
||||
async function loadReferences(projectId) {
|
||||
const referencesList = document.getElementById('referenceAnalysis');
|
||||
|
||||
try {
|
||||
// Get literature list
|
||||
// Get paper list
|
||||
const response = await fetch(`${API_BASE_URL}/projects/${projectId}/references`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
@@ -688,15 +688,15 @@
|
||||
}
|
||||
|
||||
if (references.length === 0) {
|
||||
referencesList.innerHTML = '<div class="alert alert-info">No literature data, please upload literature</div>';
|
||||
referencesList.innerHTML = '<div class="alert alert-info">No paper data, please upload paper</div>';
|
||||
return;
|
||||
}
|
||||
|
||||
// Render literature cards
|
||||
// Render paper cards
|
||||
const referenceCards = references.map(ref => renderReferenceCard(ref, projectId)).join('');
|
||||
referencesList.innerHTML = referenceCards;
|
||||
|
||||
// Get analysis status and results for each literature
|
||||
// Get analysis status and results for each paper
|
||||
references.forEach(async (ref) => {
|
||||
try {
|
||||
const checkAnalysisStatus = async () => {
|
||||
@@ -721,7 +721,7 @@
|
||||
<div class="spinner-border spinner-border-sm text-primary me-2" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<span>Analyzing literature content...</span>
|
||||
<span>Analyzing Paper content...</span>
|
||||
</div>
|
||||
`;
|
||||
statusElement.innerHTML = '<span class="text-primary">Analysis in progress...</span>';
|
||||
@@ -787,10 +787,10 @@
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to load literature list:', error);
|
||||
console.error('Failed to load Paper list:', error);
|
||||
referencesList.innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
Failed to load literature list: ${error.message}
|
||||
Failed to load Paper list: ${error.message}
|
||||
<br>
|
||||
<button class="btn btn-primary mt-2" onclick="loadReferences('${projectId}')">
|
||||
Retry
|
||||
@@ -799,7 +799,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function uploadLiterature() {
|
||||
async function uploadPaper() {
|
||||
if (!currentProjectId) {
|
||||
alert('Please select a project first');
|
||||
return;
|
||||
@@ -912,7 +912,7 @@
|
||||
input.click();
|
||||
}
|
||||
|
||||
// View literature details function
|
||||
// View paper details function
|
||||
async function viewReferenceDetail(referenceId) {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/references/${referenceId}/report`, {
|
||||
@@ -934,7 +934,7 @@
|
||||
<div class="spinner-border text-primary me-3" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<h5 class="mb-0">Analyzing literature content, please wait...</h5>
|
||||
<h5 class="mb-0">Analyzing Paper content, please wait...</h5>
|
||||
</div>
|
||||
`;
|
||||
} else if (analysisResult.status === 'completed') {
|
||||
@@ -943,7 +943,7 @@
|
||||
.replace(/},/g, '')
|
||||
.replace(/{ },/g, '')
|
||||
.replace(/^\s*,/gm, '')
|
||||
.replace(/Literature Analysis Report:/, '<div style="text-align: center"><strong>Literature Analysis Report</strong></div>')
|
||||
.replace(/Paper Analysis Report:/, '<div style="text-align: center"><strong>Paper Analysis</strong></div>')
|
||||
.replace(/^(\s*\d+\.[^:\n]+:)/gm, '<strong>$1</strong>')
|
||||
.split('\n')
|
||||
.map(line => line.trimEnd())
|
||||
@@ -972,7 +972,7 @@
|
||||
<div class="modal-dialog modal-lg" style="max-width: 80%; margin: 1.75rem auto;">
|
||||
<div class="modal-content" style="min-height: 80vh;">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="referenceDetailModalTitle">Literature Analysis Report</h5>
|
||||
<h5 class="modal-title" id="referenceDetailModalTitle">Paper Analysis</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body" style="max-height: calc(80vh - 60px); overflow-y: auto;">
|
||||
@@ -1003,17 +1003,17 @@
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to view details:', error);
|
||||
alert('Failed to get literature analysis report, please try again later');
|
||||
alert('Failed to get analysis report, please try again later');
|
||||
}
|
||||
}
|
||||
|
||||
// View literature details from card
|
||||
// View paper details from card
|
||||
function viewReferenceDetailFromCard(card) {
|
||||
const referenceId = card.id.replace('reference-', '');
|
||||
viewReferenceDetail(referenceId);
|
||||
}
|
||||
|
||||
// Download literature analysis report function
|
||||
// Download paper analysis report function
|
||||
async function downloadReferenceReport() {
|
||||
if (!currentProjectId) {
|
||||
alert('Please select a project first');
|
||||
@@ -1023,20 +1023,20 @@
|
||||
try {
|
||||
// 1. 检查是否有文献
|
||||
const referencesList = document.getElementById('referenceAnalysis');
|
||||
if (referencesList && referencesList.innerHTML.includes('No literature data')) {
|
||||
alert('Please upload literature first!');
|
||||
if (referencesList && referencesList.innerHTML.includes('No Paper data')) {
|
||||
alert('Please upload Paper first!');
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示报告页面
|
||||
document.getElementById('projectsListPage').classList.add('hidden');
|
||||
document.getElementById('projectDetailPage').classList.add('hidden');
|
||||
const reportPage = document.getElementById('literatureReportPage');
|
||||
const reportPage = document.getElementById('paperReportPage');
|
||||
reportPage.classList.remove('hidden');
|
||||
|
||||
// Show loading status
|
||||
const showLoading = (message) => {
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="d-flex align-items-center justify-content-center" style="min-height: 200px;">
|
||||
<div class="text-center">
|
||||
<div class="spinner-border text-primary mb-3" role="status">
|
||||
@@ -1049,7 +1049,7 @@
|
||||
`;
|
||||
};
|
||||
|
||||
showLoading('Getting literature analysis report...');
|
||||
showLoading('Getting paper analysis report...');
|
||||
|
||||
// 2. Check if report already exists
|
||||
const existingReport = await fetch(`${API_BASE_URL}/references/${currentProjectId}/summary_report`, {
|
||||
@@ -1059,7 +1059,7 @@
|
||||
if (existingReport.ok) {
|
||||
const report = await existingReport.json();
|
||||
currentReportData = report;
|
||||
document.getElementById('literatureReportContent').innerHTML = formatReportContent(report);
|
||||
document.getElementById('paperReportContent').innerHTML = formatReportContent(report);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1095,7 +1095,7 @@
|
||||
});
|
||||
const report = await finalReport.json();
|
||||
currentReportData = report;
|
||||
document.getElementById('literatureReportContent').innerHTML = formatReportContent(report);
|
||||
document.getElementById('paperReportContent').innerHTML = formatReportContent(report);
|
||||
}
|
||||
else if (status.status === 'failed') {
|
||||
clearInterval(statusCheck);
|
||||
@@ -1103,7 +1103,7 @@
|
||||
}
|
||||
else if (attempts >= maxAttempts) {
|
||||
clearInterval(statusCheck);
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="alert alert-warning">
|
||||
Report generation is taking longer than expected. Please refresh and try again later.
|
||||
<button class="btn btn-primary mt-2" onclick="downloadReferenceReport()">
|
||||
@@ -1117,7 +1117,7 @@
|
||||
}
|
||||
} catch (error) {
|
||||
clearInterval(statusCheck);
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
Failed to generate report: ${error.message}
|
||||
<button class="btn btn-primary mt-2" onclick="downloadReferenceReport()">
|
||||
@@ -1129,7 +1129,7 @@
|
||||
}, 5000);
|
||||
|
||||
} catch (error) {
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
Operation failed: ${error.message}
|
||||
<button class="btn btn-primary mt-2" onclick="downloadReferenceReport()">
|
||||
@@ -1152,7 +1152,7 @@
|
||||
.replace(/},/g, '')
|
||||
.replace(/{ },/g, '')
|
||||
.replace(/^\s*,/gm, '')
|
||||
.replace(/Literature Summary Report:/, '<div style="text-align: center"><strong style="font-size: 24px;">Literature Summary Report</strong></div>')
|
||||
.replace(/Paper Summary Report:/, '<div style="text-align: center"><strong style="font-size: 24px;">Paper Summary Report</strong></div>')
|
||||
.replace(/^(\s*\d+\.[^:\n]+:)/gm, '<strong>$1</strong>')
|
||||
.split('\n')
|
||||
.map(line => line.trimEnd())
|
||||
@@ -1162,9 +1162,9 @@
|
||||
</div>`;
|
||||
}
|
||||
|
||||
// Delete literature function
|
||||
// Delete paper function
|
||||
async function deleteReference(projectId, referenceId) {
|
||||
if (!confirm('Are you sure you want to delete this literature? This action cannot be undone.')) {
|
||||
if (!confirm('Are you sure you want to delete this Paper? This action cannot be undone.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1184,17 +1184,17 @@
|
||||
|
||||
const referencesList = document.getElementById('referenceAnalysis');
|
||||
if (!referencesList.children.length) {
|
||||
referencesList.innerHTML = '<div class="alert alert-info">No literature data, please upload literature</div>';
|
||||
referencesList.innerHTML = '<div class="alert alert-info">No Paper data, please upload</div>';
|
||||
}
|
||||
|
||||
alert('Literature deleted successfully');
|
||||
alert('Deleted successfully');
|
||||
} else {
|
||||
const error = await response.json();
|
||||
alert(`Failed to delete literature: ${error.detail}`);
|
||||
alert(`Failed to delete Paper: ${error.detail}`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to delete literature:', error);
|
||||
alert('Failed to delete literature, please try again');
|
||||
console.error('Failed to delete Paper:', error);
|
||||
alert('Failed to delete Paper, please try again');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1216,7 +1216,7 @@
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered" style="max-width: 800px;">
|
||||
<div class="modal-content" style="min-height: 60vh;">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="chatModalTitle">Chat with Literature: ${title}</h5>
|
||||
<h5 class="modal-title" id="chatModalTitle">${title}</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body d-flex flex-column" style="height: calc(60vh - 76px);">
|
||||
@@ -1485,9 +1485,9 @@
|
||||
}
|
||||
|
||||
// 添加显示文献列表的函数
|
||||
function showLiteratureList() {
|
||||
function showPaperList() {
|
||||
// 隐藏报告页面
|
||||
document.getElementById('literatureReportPage').classList.add('hidden');
|
||||
document.getElementById('paperReportPage').classList.add('hidden');
|
||||
// 显示文献列表页面
|
||||
document.getElementById('projectDetailPage').classList.remove('hidden');
|
||||
|
||||
@@ -1515,7 +1515,7 @@
|
||||
// 创建临时下载链接
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `literature_analysis_report_${new Date().toISOString().split('T')[0]}.json`;
|
||||
a.download = `paper_analysis_report_${new Date().toISOString().split('T')[0]}.json`;
|
||||
|
||||
// 触发下载
|
||||
document.body.appendChild(a);
|
||||
@@ -1544,7 +1544,7 @@
|
||||
try {
|
||||
// 显示加载状态
|
||||
const showLoading = (message) => {
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="d-flex align-items-center justify-content-center" style="min-height: 200px;">
|
||||
<div class="text-center">
|
||||
<div class="spinner-border text-primary mb-3" role="status">
|
||||
@@ -1589,7 +1589,7 @@
|
||||
});
|
||||
const report = await finalReport.json();
|
||||
currentReportData = report;
|
||||
document.getElementById('literatureReportContent').innerHTML = formatReportContent(report);
|
||||
document.getElementById('paperReportContent').innerHTML = formatReportContent(report);
|
||||
}
|
||||
else if (status.status === 'failed') {
|
||||
clearInterval(statusCheck);
|
||||
@@ -1597,7 +1597,7 @@
|
||||
}
|
||||
else if (attempts >= maxAttempts) {
|
||||
clearInterval(statusCheck);
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="alert alert-warning">
|
||||
Report regeneration is taking longer than expected. Please refresh and try again later.
|
||||
<button class="btn btn-primary mt-2" onclick="regenerateReport()">
|
||||
@@ -1611,7 +1611,7 @@
|
||||
}
|
||||
} catch (error) {
|
||||
clearInterval(statusCheck);
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
Failed to regenerate report: ${error.message}
|
||||
<button class="btn btn-primary mt-2" onclick="regenerateReport()">
|
||||
@@ -1623,7 +1623,7 @@
|
||||
}, 5000);
|
||||
|
||||
} catch (error) {
|
||||
document.getElementById('literatureReportContent').innerHTML = `
|
||||
document.getElementById('paperReportContent').innerHTML = `
|
||||
<div class="alert alert-danger">
|
||||
Operation failed: ${error.message}
|
||||
<button class="btn btn-primary mt-2" onclick="regenerateReport()">
|
||||
+24
-24
@@ -635,7 +635,7 @@
|
||||
<div class="navbar-menu-item" onclick="window.location.href='lab.html'">Project</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='device.html'">Device</div>
|
||||
<div class="navbar-menu-item active">Reports</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='literature.html'">Literature</div>
|
||||
<div class="navbar-menu-item" onclick="window.location.href='Paper.html'">Paper</div>
|
||||
</div>
|
||||
<div class="navbar-right">
|
||||
<a href="https://beta.obscura.work/lab/device.html" target="_blank" class="btn btn-primary">
|
||||
@@ -721,7 +721,7 @@
|
||||
<option value="">All</option>
|
||||
<option value="project">Project</option>
|
||||
<option value="experiment">experiment</option>
|
||||
<option value="literature">Literature</option>
|
||||
<option value="paper">Paper</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
@@ -745,9 +745,9 @@
|
||||
<i class="bi bi-file-text"></i>
|
||||
<span>Project</span>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="switchReportSection('literatureReport')">
|
||||
<div class="sidebar-item" onclick="switchReportSection('paperReport')">
|
||||
<i class="bi bi-book"></i>
|
||||
<span>Literature</span>
|
||||
<span>Paper</span>
|
||||
</div>
|
||||
<div class="sidebar-item" onclick="downloadCurrentReport()">
|
||||
<i class="bi bi-download"></i>
|
||||
@@ -772,8 +772,8 @@
|
||||
<div id="projectReportSection" class="report-section active">
|
||||
<pre id="projectReportDetail" class="report-content bg-light p-3 rounded"></pre>
|
||||
</div>
|
||||
<div id="literatureReportSection" class="report-section">
|
||||
<pre id="literatureReportDetail" class="report-content bg-light p-3 rounded"></pre>
|
||||
<div id="paperReportSection" class="report-section">
|
||||
<pre id="paperReportDetail" class="report-content bg-light p-3 rounded"></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -860,7 +860,7 @@
|
||||
.replace(/{ },/g, '')
|
||||
.replace(/^\s*,/gm, '') // 处理行首的逗号
|
||||
.replace(/Project Analysis Report:/, '<div style="text-align: center"><strong style="font-size: 24px;">Project Analysis Report</strong></div>')
|
||||
.replace(/Literature Summary Report:/, '<div style="text-align: center"><strong style="font-size: 24px;">Literature Summary Report</strong></div>')
|
||||
.replace(/paper Summary Report:/, '<div style="text-align: center"><strong style="font-size: 24px;">Paper Summary Report</strong></div>')
|
||||
// 加粗标题 (以数字开头的行)
|
||||
.replace(/^(\s*\d+\.[^:\n]+:)/gm, '<strong>$1</strong>')
|
||||
// 保持缩进
|
||||
@@ -912,7 +912,7 @@
|
||||
// 修改后的 viewProjectReport 函数
|
||||
async function viewProjectReport(projectId, projectName) {
|
||||
try {
|
||||
let projectData = null, literatureData = null;
|
||||
let projectData = null, paperData = null;
|
||||
|
||||
// 隐藏项目列表页面
|
||||
document.querySelector('.main-content > .row').style.display = 'none';
|
||||
@@ -932,33 +932,33 @@
|
||||
|
||||
// 2. 如果没有项目报告,尝试获取文献分析报告
|
||||
if (!projectData) {
|
||||
const literatureResponse = await fetch(`${API_BASE_URL}/references/${projectId}/summary_report`, {
|
||||
const paperResponse = await fetch(`${API_BASE_URL}/references/${projectId}/summary_report`, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`
|
||||
}
|
||||
});
|
||||
|
||||
if (literatureResponse.ok) {
|
||||
literatureData = await literatureResponse.json();
|
||||
if (paperResponse.ok) {
|
||||
paperData = await paperResponse.json();
|
||||
} else {
|
||||
console.log('No literature report found');
|
||||
console.log('No paper report found');
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 如果两种报告都没有,显示提示信息
|
||||
if (!projectData && !literatureData) {
|
||||
if (!projectData && !paperData) {
|
||||
document.getElementById('reportDetailTitle').textContent = `Project Report - ${projectName}`;
|
||||
document.getElementById('projectReportDetail').innerHTML =
|
||||
'<div class="alert alert-info">No reports available for this project yet.</div>';
|
||||
document.getElementById('literatureReportDetail').innerHTML =
|
||||
'<div class="alert alert-info">No literature analysis report available.</div>';
|
||||
document.getElementById('paperReportDetail').innerHTML =
|
||||
'<div class="alert alert-info">No paper analysis report available.</div>';
|
||||
} else {
|
||||
// 4. 保存当前报告数据
|
||||
currentReportData = {
|
||||
projectId,
|
||||
projectName,
|
||||
projectReport: projectData,
|
||||
literatureReport: literatureData
|
||||
paperReport: paperData
|
||||
};
|
||||
|
||||
// 5. 更新报告显示
|
||||
@@ -966,9 +966,9 @@
|
||||
document.getElementById('projectReportDetail').innerHTML = projectData ?
|
||||
formatReportContent(projectData) :
|
||||
'<div class="alert alert-info">No project report available.</div>';
|
||||
document.getElementById('literatureReportDetail').innerHTML = literatureData ?
|
||||
formatReportContent(literatureData) :
|
||||
'<div class="alert alert-info">No literature analysis report available.</div>';
|
||||
document.getElementById('paperReportDetail').innerHTML = paperData ?
|
||||
formatReportContent(paperData) :
|
||||
'<div class="alert alert-info">No paper analysis report available.</div>';
|
||||
}
|
||||
|
||||
// 6. 显示报告详情页面
|
||||
@@ -990,7 +990,7 @@
|
||||
// Build complete report object
|
||||
const combinedReport = {
|
||||
project_report: currentReportData.projectReport,
|
||||
literature_analysis: currentReportData.literatureReport || "No literature analysis report found"
|
||||
paper_analysis: currentReportData.paperReport || "No paper analysis report found"
|
||||
};
|
||||
|
||||
const reportText = JSON.stringify(combinedReport, null, 2);
|
||||
@@ -1093,7 +1093,7 @@
|
||||
project_name: project.project_name,
|
||||
description: project.description,
|
||||
project_reports: project.project_reports,
|
||||
literature_analysis: project.literature_analysis
|
||||
paper_analysis: project.paper_analysis
|
||||
}));
|
||||
|
||||
const reportText = JSON.stringify(reports, null, 2);
|
||||
@@ -1128,7 +1128,7 @@
|
||||
project_name: project.project_name,
|
||||
description: project.description,
|
||||
project_reports: project.project_reports,
|
||||
literature_analysis: project.literature_analysis
|
||||
paper_analysis: project.paper_analysis
|
||||
}));
|
||||
|
||||
const summaryText = JSON.stringify(summary, null, 2);
|
||||
@@ -1148,7 +1148,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Switch between project report and literature analysis
|
||||
// Switch between project report and paper analysis
|
||||
function switchReportSection(section) {
|
||||
// Remove active class from all sections
|
||||
document.querySelectorAll('.report-section').forEach(section => {
|
||||
@@ -1173,7 +1173,7 @@
|
||||
}
|
||||
|
||||
// 更新标题
|
||||
const title = sectionId === 'projectReport' ? 'Project Report' : 'Literature Analysis';
|
||||
const title = sectionId === 'projectReport' ? 'Project Report' : 'paper Analysis';
|
||||
document.getElementById('reportDetailTitle').textContent = `${title} - ${currentReportData.projectName}`;
|
||||
|
||||
// 更新侧边栏选中状态
|
||||
|
||||
Reference in New Issue
Block a user