Files
doc_ai_backed/internal/service/task.go

202 lines
6.3 KiB
Go
Raw Normal View History

2025-12-10 18:33:37 +08:00
package service
import (
2025-12-26 15:48:14 +08:00
"bytes"
2025-12-10 18:33:37 +08:00
"context"
2025-12-31 18:05:48 +08:00
"encoding/json"
2025-12-10 18:33:37 +08:00
"errors"
2025-12-26 15:48:14 +08:00
"fmt"
"io"
"net/http"
2025-12-10 18:33:37 +08:00
"strings"
2026-01-27 21:56:21 +08:00
"gitea.com/texpixel/document_ai/internal/model/task"
"gitea.com/texpixel/document_ai/internal/storage/dao"
"gitea.com/texpixel/document_ai/pkg/log"
"gitea.com/texpixel/document_ai/pkg/oss"
2025-12-10 18:33:37 +08:00
)
type TaskService struct {
2025-12-18 12:39:50 +08:00
recognitionTaskDao *dao.RecognitionTaskDao
evaluateTaskDao *dao.EvaluateTaskDao
recognitionResultDao *dao.RecognitionResultDao
2025-12-10 18:33:37 +08:00
}
func NewTaskService() *TaskService {
2025-12-18 12:39:50 +08:00
return &TaskService{
recognitionTaskDao: dao.NewRecognitionTaskDao(),
evaluateTaskDao: dao.NewEvaluateTaskDao(),
recognitionResultDao: dao.NewRecognitionResultDao(),
}
2025-12-10 18:33:37 +08:00
}
func (svc *TaskService) EvaluateTask(ctx context.Context, req *task.EvaluateTaskRequest) error {
2025-12-18 12:39:50 +08:00
task, err := svc.recognitionTaskDao.GetByTaskNo(dao.DB.WithContext(ctx), req.TaskNo)
2025-12-10 18:33:37 +08:00
if err != nil {
log.Error(ctx, "func", "EvaluateTask", "msg", "get task by task no failed", "error", err)
return err
}
if task == nil {
log.Error(ctx, "func", "EvaluateTask", "msg", "task not found")
return errors.New("task not found")
}
if task.Status != dao.TaskStatusCompleted {
log.Error(ctx, "func", "EvaluateTask", "msg", "task not finished")
return errors.New("task not finished")
}
evaluateTask := &dao.EvaluateTask{
TaskID: task.ID,
Satisfied: req.Satisfied,
Feedback: req.Feedback,
Comment: strings.Join(req.Suggestion, ","),
}
2025-12-18 12:39:50 +08:00
err = svc.evaluateTaskDao.Create(dao.DB.WithContext(ctx), evaluateTask)
2025-12-10 18:33:37 +08:00
if err != nil {
log.Error(ctx, "func", "EvaluateTask", "msg", "create evaluate task failed", "error", err)
return err
}
return nil
}
func (svc *TaskService) GetTaskList(ctx context.Context, req *task.TaskListRequest) (*task.TaskListResponse, error) {
2025-12-18 12:39:50 +08:00
tasks, total, err := svc.recognitionTaskDao.GetTaskList(dao.DB.WithContext(ctx), req.UserID, dao.TaskType(req.TaskType), req.Page, req.PageSize)
2025-12-10 18:33:37 +08:00
if err != nil {
log.Error(ctx, "func", "GetTaskList", "msg", "get task list failed", "error", err)
return nil, err
}
2025-12-18 12:39:50 +08:00
taskIDs := make([]int64, 0, len(tasks))
for _, item := range tasks {
taskIDs = append(taskIDs, item.ID)
}
recognitionResults, err := svc.recognitionResultDao.GetByTaskIDs(dao.DB.WithContext(ctx), taskIDs)
if err != nil {
log.Error(ctx, "func", "GetTaskList", "msg", "get recognition results failed", "error", err)
return nil, err
}
recognitionResultMap := make(map[int64]*dao.RecognitionResult)
for _, item := range recognitionResults {
recognitionResultMap[item.TaskID] = item
}
2025-12-10 18:33:37 +08:00
resp := &task.TaskListResponse{
TaskList: make([]*task.TaskListDTO, 0, len(tasks)),
2025-12-18 12:39:50 +08:00
Total: total,
2025-12-10 18:33:37 +08:00
}
for _, item := range tasks {
2025-12-18 12:39:50 +08:00
var latex string
var markdown string
2025-12-20 22:57:14 +08:00
var mathML string
2025-12-18 12:39:50 +08:00
recognitionResult := recognitionResultMap[item.ID]
if recognitionResult != nil {
2025-12-20 21:42:58 +08:00
latex = recognitionResult.Latex
markdown = recognitionResult.Markdown
2025-12-20 22:57:14 +08:00
mathML = recognitionResult.MathML
2025-12-18 12:39:50 +08:00
}
2025-12-18 15:14:42 +08:00
originURL, err := oss.GetDownloadURL(ctx, item.FileURL)
if err != nil {
log.Error(ctx, "func", "GetTaskList", "msg", "get origin url failed", "error", err)
}
2025-12-10 18:33:37 +08:00
resp.TaskList = append(resp.TaskList, &task.TaskListDTO{
2025-12-18 12:39:50 +08:00
Latex: latex,
Markdown: markdown,
2025-12-20 22:57:14 +08:00
MathML: mathML,
2025-12-10 18:33:37 +08:00
TaskID: item.TaskUUID,
FileName: item.FileName,
2025-12-18 15:14:42 +08:00
Status: int(item.Status),
OriginURL: originURL,
2025-12-10 18:33:37 +08:00
TaskType: item.TaskType.String(),
CreatedAt: item.CreatedAt.Format("2006-01-02 15:04:05"),
})
}
return resp, nil
}
2025-12-26 15:48:14 +08:00
func (svc *TaskService) ExportTask(ctx context.Context, req *task.ExportTaskRequest) ([]byte, string, error) {
2025-12-26 16:28:49 +08:00
recognitionTask, err := svc.recognitionTaskDao.GetByTaskNo(dao.DB.WithContext(ctx), req.TaskNo)
2025-12-26 15:48:14 +08:00
if err != nil {
log.Error(ctx, "func", "ExportTask", "msg", "get task by task id failed", "error", err)
return nil, "", err
}
if recognitionTask == nil {
log.Error(ctx, "func", "ExportTask", "msg", "task not found")
return nil, "", errors.New("task not found")
}
if recognitionTask.Status != dao.TaskStatusCompleted {
log.Error(ctx, "func", "ExportTask", "msg", "task not finished")
return nil, "", errors.New("task not finished")
}
2025-12-26 16:28:49 +08:00
recognitionResult, err := svc.recognitionResultDao.GetByTaskID(dao.DB.WithContext(ctx), recognitionTask.ID)
2025-12-26 15:48:14 +08:00
if err != nil {
log.Error(ctx, "func", "ExportTask", "msg", "get recognition result by task id failed", "error", err)
return nil, "", err
}
if recognitionResult == nil {
log.Error(ctx, "func", "ExportTask", "msg", "recognition result not found")
return nil, "", errors.New("recognition result not found")
}
markdown := recognitionResult.Markdown
if markdown == "" {
log.Error(ctx, "func", "ExportTask", "msg", "markdown not found")
return nil, "", errors.New("markdown not found")
}
2025-12-31 18:05:48 +08:00
// 获取文件名(去掉扩展名)
filename := strings.TrimSuffix(recognitionTask.FileName, "."+strings.ToLower(strings.Split(recognitionTask.FileName, ".")[len(strings.Split(recognitionTask.FileName, "."))-1]))
if filename == "" {
filename = "texpixel"
}
2025-12-26 15:48:14 +08:00
2025-12-31 18:05:48 +08:00
// 构建 JSON 请求体
requestBody := map[string]string{
"markdown": markdown,
"filename": filename,
}
jsonData, err := json.Marshal(requestBody)
if err != nil {
log.Error(ctx, "func", "ExportTask", "msg", "json marshal failed", "error", err)
return nil, "", err
}
httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, "https://cloud.texpixel.com:10443/doc_process/v1/convert/file", bytes.NewReader(jsonData))
2025-12-26 15:48:14 +08:00
if err != nil {
log.Error(ctx, "func", "ExportTask", "msg", "create http request failed", "error", err)
return nil, "", err
}
2025-12-31 18:05:48 +08:00
httpReq.Header.Set("Content-Type", "application/json")
2025-12-26 15:48:14 +08:00
client := &http.Client{}
resp, err := client.Do(httpReq)
if err != nil {
log.Error(ctx, "func", "ExportTask", "msg", "http request failed", "error", err)
return nil, "", err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
log.Error(ctx, "func", "ExportTask", "msg", "http request failed", "status", resp.StatusCode)
return nil, "", fmt.Errorf("export service returned status: %d", resp.StatusCode)
}
fileData, err := io.ReadAll(resp.Body)
if err != nil {
log.Error(ctx, "func", "ExportTask", "msg", "read response body failed", "error", err)
return nil, "", err
}
2025-12-31 18:05:48 +08:00
// 新接口只返回 DOCX 格式
contentType := "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
2025-12-26 15:48:14 +08:00
return fileData, contentType, nil
}