完善二维码池 OCR 配置与识别

This commit is contained in:
yml
2026-06-18 15:22:46 +08:00
parent e8bdf574f4
commit 35f2d93fdf
16 changed files with 1025 additions and 48 deletions
+74 -3
View File
@@ -15,6 +15,12 @@ const (
QrCodeStatusUnused = "unused"
QrCodeStatusUsed = "used"
QrCodeStatusDisabled = "disabled"
qrCodeOCRTokenConfigKey = "integration.paddle_ocr_token"
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"
)
var (
@@ -26,6 +32,7 @@ var (
// CreateQrCodeRequest 创建二维码请求
type CreateQrCodeRequest struct {
ImageURL string `json:"image_url" binding:"required"`
GroupName string `json:"group_name"`
Note string `json:"note"`
ExpiresAt *time.Time `json:"expires_at"`
}
@@ -38,8 +45,10 @@ type BatchCreateQrCodeRequest struct {
// UpdateQrCodeRequest 更新二维码请求
type UpdateQrCodeRequest struct {
ImageURL *string `json:"image_url"`
GroupName *string `json:"group_name"`
Note *string `json:"note"`
Status *string `json:"status"`
WecomRenamed *bool `json:"wecom_renamed"`
ExpiresAt *time.Time `json:"expires_at"`
ClearExpiresAt bool `json:"clear_expires_at"`
}
@@ -59,10 +68,24 @@ type QrCodeStats struct {
TotalCount int64 `json:"total_count"`
}
// QrCodeListItem 二维码列表项
type QrCodeListItem struct {
model.ChatQrCode
BoundConversationTitle string `json:"bound_conversation_title"`
}
// QrCodeOCRConfig 二维码 OCR 调用配置
type QrCodeOCRConfig struct {
Token string `json:"token"`
JobURL string `json:"job_url"`
Model string `json:"model"`
}
// CreateQrCode 创建二维码
func (r *Repository) CreateQrCode(ctx context.Context, adminID uint64, req CreateQrCodeRequest) (*model.ChatQrCode, error) {
qrcode := model.ChatQrCode{
ImageURL: req.ImageURL,
GroupName: req.GroupName,
Status: QrCodeStatusUnused,
CreatedBy: adminID,
Note: req.Note,
@@ -90,6 +113,7 @@ func (r *Repository) BatchCreateQrCode(ctx context.Context, adminID uint64, req
for _, item := range req.Items {
qr := model.ChatQrCode{
ImageURL: item.ImageURL,
GroupName: item.GroupName,
Status: QrCodeStatusUnused,
CreatedBy: adminID,
Note: item.Note,
@@ -109,7 +133,7 @@ func (r *Repository) BatchCreateQrCode(ctx context.Context, adminID uint64, req
}
// ListQrCodes 列表查询二维码
func (r *Repository) ListQrCodes(ctx context.Context, req QrCodeListRequest) ([]model.ChatQrCode, int64, error) {
func (r *Repository) ListQrCodes(ctx context.Context, req QrCodeListRequest) ([]QrCodeListItem, int64, error) {
if req.Page < 1 {
req.Page = 1
}
@@ -131,9 +155,22 @@ func (r *Repository) ListQrCodes(ctx context.Context, req QrCodeListRequest) ([]
}
// 查询列表
var qrcodes []model.ChatQrCode
var qrcodes []QrCodeListItem
offset := (req.Page - 1) * req.Limit
if err := query.Order("id DESC").Offset(offset).Limit(req.Limit).Find(&qrcodes).Error; err != nil {
if err := r.db.WithContext(ctx).
Table("chat_qrcode_pool AS q").
Select("q.*, COALESCE(c.title, '') AS bound_conversation_title").
Joins("LEFT JOIN chat_conversations AS c ON c.id = q.conversation_id").
Scopes(func(db *gorm.DB) *gorm.DB {
if req.Status != "" {
return db.Where("q.status = ?", req.Status)
}
return db
}).
Order("q.id DESC").
Offset(offset).
Limit(req.Limit).
Scan(&qrcodes).Error; err != nil {
return nil, 0, err
}
@@ -171,6 +208,34 @@ func (r *Repository) GetQrCodeStats(ctx context.Context) (*QrCodeStats, error) {
return stats, nil
}
// GetQrCodeOCRConfig 获取前端直连 PaddleOCR 所需配置
func (r *Repository) GetQrCodeOCRConfig(ctx context.Context) (*QrCodeOCRConfig, error) {
config := &QrCodeOCRConfig{
JobURL: defaultQrCodeOCRJobURL,
Model: defaultQrCodeOCRModel,
}
var rows []model.SystemConfig
keys := []string{qrCodeOCRTokenConfigKey, qrCodeOCRJobURLConfigKey, qrCodeOCRModelConfigKey}
if err := r.db.WithContext(ctx).Where("`key` IN ?", keys).Find(&rows).Error; err != nil {
return nil, err
}
for _, row := range rows {
switch row.Key {
case qrCodeOCRTokenConfigKey:
config.Token = row.Value
case qrCodeOCRJobURLConfigKey:
if row.Value != "" {
config.JobURL = row.Value
}
case qrCodeOCRModelConfigKey:
if row.Value != "" {
config.Model = row.Value
}
}
}
return config, nil
}
// UpdateQrCode 更新二维码
func (r *Repository) UpdateQrCode(ctx context.Context, id uint64, req UpdateQrCodeRequest) error {
var qrcode model.ChatQrCode
@@ -186,9 +251,15 @@ func (r *Repository) UpdateQrCode(ctx context.Context, id uint64, req UpdateQrCo
if req.ImageURL != nil {
updates["image_url"] = *req.ImageURL
}
if req.GroupName != nil {
updates["group_name"] = *req.GroupName
}
if req.Note != nil {
updates["note"] = *req.Note
}
if req.WecomRenamed != nil {
updates["wecom_renamed"] = *req.WecomRenamed
}
if req.Status != nil {
// 校验状态值
if *req.Status != QrCodeStatusUnused && *req.Status != QrCodeStatusUsed && *req.Status != QrCodeStatusDisabled {