Version: 0.9.42.dev.260424
后端: 1. 新增课表图片识别接口,支持上传截图后返回“可编辑草稿”(success / partial / reject),并补齐大图、空图、格式不支持、识别能力未配置等错误分支。 2. 课表识别服务接入多模态 Responses 链路,完善图片请求归一化与安全校验(大小、MIME、内容探测),并对识别结果做结构化清洗、强/弱约束校验、告警去重与默认文案兜底。 3. 新增 Ark Responses 统一客户端抽象,支持文本+图片输入、JSON对象输出、usage统计透传与不完整输出识别;同时补齐模型返回 finish_reason 透传,便于定位截断问题。 4. 启动阶段增加课表识图模型与参数注入(模型名、最大图片字节、最大输出token),并将配置示例收敛为“仅保留当前代码实际读取项”。 前端: 5. 课表中心新增“导入课表”完整闭环:上传图片识别、草稿编辑校对、正式导入落库;并新增对应 API 与类型定义。 6. 导入弹窗支持识别中止、全局告警与行级告警展示、低置信度提示、行内编辑、手动新增、删除、拖拽排序、本地校验与提交前二次确认。 7. 正式导入前将草稿按“课程名+地点+是否允许嵌入”聚合为导入结构,并统一携带幂等键请求头,降低重复提交风险。 8. 周课表画板修复跨节次事件遮挡导致的网格错位问题,改进“完全遮挡/部分遮挡”渲染判定与 grid 行定位。 9. 助手流式区域优化“思考中”指示逻辑与样式,避免已有正文时仍展示回答中占位;同时补充全局组件视觉统一(弹窗/按钮)样式。 仓库: 10. 新增课表图片识别前端对接说明文档,补充主动优化能力 PRD 讨论稿,并在协作规范中新增“实现 Eino 新能力前需先查官方文档”的约束。
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import axios from 'axios'
|
||||
import http from '@/api/http'
|
||||
import type { ApiResponse, PlainResponse } from '@/types/api'
|
||||
import type {
|
||||
@@ -7,6 +8,9 @@ import type {
|
||||
TaskClassCreatePayload,
|
||||
TaskClassDetail,
|
||||
TaskClassListItem,
|
||||
CourseDraftRow,
|
||||
CourseImportPayload,
|
||||
CourseImageParseResponse,
|
||||
} from '@/types/schedule'
|
||||
import { extractErrorMessage } from '@/utils/http'
|
||||
import { createIdempotencyKey } from '@/utils/idempotency'
|
||||
@@ -147,3 +151,33 @@ export async function deleteTaskClassItem(taskItemId: number, idempotencyKey = c
|
||||
throw new Error(extractErrorMessage(error, '\u5220\u9664\u4efb\u52a1\u5757\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5'))
|
||||
}
|
||||
}
|
||||
|
||||
export async function parseCourseImage(file: File, signal?: AbortSignal) {
|
||||
try {
|
||||
const formData = new FormData()
|
||||
formData.append('image', file)
|
||||
const response = await http.post<ApiResponse<CourseImageParseResponse>>('/course/parse-image', formData, {
|
||||
timeout: 300000,
|
||||
signal,
|
||||
})
|
||||
return response.data.data
|
||||
} catch (error) {
|
||||
if (axios.isCancel(error)) {
|
||||
throw new Error('\u8bc6\u522b\u5df2\u53d6\u6d88')
|
||||
}
|
||||
throw new Error(extractErrorMessage(error, '\u8bfe\u8868\u56fe\u7247\u8bc6\u522b\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5'))
|
||||
}
|
||||
}
|
||||
|
||||
export async function importCourses(payload: CourseImportPayload, idempotencyKey = createIdempotencyKey('course-import')) {
|
||||
try {
|
||||
const response = await http.post<PlainResponse>('/course/import', payload, {
|
||||
headers: {
|
||||
'X-Idempotency-Key': idempotencyKey,
|
||||
},
|
||||
})
|
||||
return response.data
|
||||
} catch (error) {
|
||||
throw new Error(extractErrorMessage(error, '\u8bfe\u7a0b\u5bfc\u5165\u5931\u8d25\uff0c\u8bf7\u7a0d\u540e\u91cd\u8bd5'))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user