// Code scaffolded by goctl. Safe to edit. // goctl 1.10.1 package ocr import ( "context" "encoding/json" "fmt" "io" "net/http" "net/url" "strings" "sundynix-micro-go/app/plant/api/internal/svc" "sundynix-micro-go/app/plant/api/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type OcrClassifyLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } // OCR植物识别 func NewOcrClassifyLogic(ctx context.Context, svcCtx *svc.ServiceContext) *OcrClassifyLogic { return &OcrClassifyLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // baiduTokenResp 百度 token 响应 type baiduTokenResp struct { AccessToken string `json:"access_token"` } // OcrClassify 调用百度 AI 植物识别接口 func (l *OcrClassifyLogic) OcrClassify(req *types.OcrReq) (interface{}, error) { // 1. 获取百度 access_token apiKey := l.svcCtx.Config.BaiduOcr.ApiKey secretKey := l.svcCtx.Config.BaiduOcr.SecretKey if apiKey == "" || secretKey == "" { return nil, fmt.Errorf("百度 OCR 未配置 ApiKey/SecretKey") } tokenURL := fmt.Sprintf( "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s", apiKey, secretKey, ) tokenResp, err := http.Post(tokenURL, "application/x-www-form-urlencoded", nil) if err != nil { return nil, fmt.Errorf("获取百度 token 失败: %w", err) } defer tokenResp.Body.Close() tokenBody, _ := io.ReadAll(tokenResp.Body) var tokenObj baiduTokenResp if err = json.Unmarshal(tokenBody, &tokenObj); err != nil || tokenObj.AccessToken == "" { return nil, fmt.Errorf("解析百度 token 失败") } // 2. 调用植物识别接口(传入图片 URL) apiURL := "https://aip.baidubce.com/rest/2.0/image-classify/v1/plant?access_token=" + tokenObj.AccessToken payload := strings.NewReader("url=" + url.QueryEscape(req.ImageUrl) + "&baike_num=1") classifyReq, err := http.NewRequest("POST", apiURL, payload) if err != nil { return nil, fmt.Errorf("创建请求失败: %w", err) } classifyReq.Header.Set("Content-Type", "application/x-www-form-urlencoded") client := &http.Client{} classifyResp, err := client.Do(classifyReq) if err != nil { return nil, fmt.Errorf("调用百度植物识别接口失败: %w", err) } defer classifyResp.Body.Close() body, err := io.ReadAll(classifyResp.Body) if err != nil { return nil, fmt.Errorf("读取识别结果失败: %w", err) } // 3. 直接返回百度原始结果(前端自行解析 result 字段) var result interface{} if err = json.Unmarshal(body, &result); err != nil { return nil, fmt.Errorf("解析识别结果失败: %w", err) } return result, nil }