Merge branch 'main' into feature/distribution-system

This commit is contained in:
yml2213
2026-09-11 09:35:53 +08:00
14 changed files with 75 additions and 13 deletions
@@ -1,6 +1,7 @@
package chat
import (
"context"
"errors"
"net/http"
@@ -10,6 +11,9 @@ import (
)
func writeChatError(c *gin.Context, err error) {
if errors.Is(err, context.Canceled) || errors.Is(c.Request.Context().Err(), context.Canceled) {
return
}
response.RecordError(c, err)
switch {
case errors.Is(err, ErrDependencyUnavailable):
+1 -1
View File
@@ -23,7 +23,7 @@ const (
qrCodeOCRJobURLConfigKey = "integration.paddle_ocr_job_url"
qrCodeOCRModelConfigKey = "integration.paddle_ocr_model"
defaultQrCodeOCRJobURL = "https://paddleocr.aistudio-app.com/api/v2/ocr/jobs"
defaultQrCodeOCRModel = "PaddleOCR-VL-1.6"
defaultQrCodeOCRModel = "PP-OCRv6"
)
var (
+14 -1
View File
@@ -443,6 +443,7 @@ func (r *Repository) submitPaddleOCRJob(ctx context.Context, config *QrCodeOCRCo
optionalPayload, _ := json.Marshal(map[string]bool{
"useDocOrientationClassify": false,
"useDocUnwarping": false,
"useTextlineOrientation": false,
"useChartRecognition": false,
})
_ = writer.WriteField("optionalPayload", string(optionalPayload))
@@ -790,13 +791,25 @@ func collectPaddleOCRText(value any, texts *[]string) {
collectPaddleOCRText(item, texts)
}
case map[string]any:
// PP-OCRv6: prunedResult.rec_texts 包含检测并识别的文字列表
if recTexts, ok := v["rec_texts"].([]any); ok {
for _, item := range recTexts {
if text, ok := item.(string); ok && strings.TrimSpace(text) != "" {
*texts = append(*texts, text)
}
}
return
}
// PaddleOCR-VL: markdown.text 包含识别文本
if markdown, ok := v["markdown"].(map[string]any); ok {
if text, ok := markdown["text"].(string); ok && strings.TrimSpace(text) != "" {
*texts = append(*texts, text)
}
}
for key, item := range v {
if key == "images" || key == "outputImages" {
if key == "images" || key == "outputImages" || key == "ocrImage" || key == "inputImage" ||
key == "preprocessedImages" || key == "model_settings" || key == "text_det_params" ||
key == "logId" || key == "errorCode" || key == "errorMsg" || key == "dataInfo" {
continue
}
collectPaddleOCRText(item, texts)
@@ -222,3 +222,20 @@ func pngHeader(width, height uint32) []byte {
binary.Write(&result, binary.BigEndian, checksum)
return result.Bytes()
}
func TestCollectPaddleOCRJSONLTextSupportsPPOCRv6(t *testing.T) {
rawJSONL := `{"result":{"ocrResults":[{"prunedResult":{"rec_texts":["火爆出租-778群","扫码加入群聊"]},"ocrImage":"https://example.com/ocr.jpg","inputImage":"https://example.com/in.jpg"}]}}`
text := collectPaddleOCRJSONLText(rawJSONL)
if !strings.Contains(text, "火爆出租-778群") || !strings.Contains(text, "扫码加入群聊") {
t.Fatalf("collected text = %q, expected recognized group texts", text)
}
if strings.Contains(text, "ocr.jpg") || strings.Contains(text, "in.jpg") {
t.Fatalf("collected text = %q, should not include image URLs", text)
}
candidates := parseQrCodeGroupNameCandidates(text)
if len(candidates) == 0 || candidates[0] != "火爆出租-778群" {
t.Fatalf("candidates = %v, want 火爆出租-778群 as first candidate", candidates)
}
}
+1 -1
View File
@@ -229,6 +229,7 @@ func (r *Repository) listAdminConversations(ctx context.Context, principal Princ
var rows []conversationRow
offset := (page - 1) * pageSize
queryDB := r.adminConversationBase(ctx, principal, keyword).
Joins("LEFT JOIN chat_messages AS lm ON lm.id = c.last_message_id").
Select(`c.id, c.order_id, c.listing_id, c.type, c.support_scene, c.title, c.status, c.last_message_id,
c.last_message_preview, c.last_message_at, c.created_at, c.updated_at,
COALESCE(cp_me.role, 'admin') AS role,
@@ -302,7 +303,6 @@ func (r *Repository) adminConversationBase(ctx context.Context, principal Princi
db := r.db.WithContext(ctx).Table("chat_conversations AS c").
Joins("LEFT JOIN chat_participants AS cp_me ON cp_me.conversation_id = c.id AND cp_me.participant_type = ? AND cp_me.participant_id = ?", principal.Type, principal.ID).
Joins("LEFT JOIN chat_admin_conversation_states AS cas ON cas.conversation_id = c.id AND cas.admin_user_id = ?", principal.ID).
Joins("LEFT JOIN chat_messages AS lm ON lm.id = c.last_message_id").
Joins("LEFT JOIN rental_orders AS explicit_lo ON explicit_lo.id = c.order_id").
Joins("LEFT JOIN rental_listings AS l ON l.id = COALESCE(explicit_lo.listing_id, c.listing_id)")
if keyword != "" {