Files
root 9d6181260a
Desktop Client Build / Resolve Build Metadata (push) Successful in 43s
Frontend CI / Frontend (push) Successful in 3m49s
Backend CI / Backend (push) Failing after 7m10s
Desktop Client Build / Build Desktop Client (push) Successful in 23m4s
Desktop Client Build / Publish Client Artifacts to NAS (push) Successful in 28s
feat(media-supply): add media resource supply marketplace
Introduce an end-to-end media-supply feature: tenant-side resource sync
service/worker backed by a Meijiequan supplier client, ops-side management
APIs, and admin/ops web views for resources, orders, favorites and
submission. Adds a shared digitocr helper, MediaSupply config blocks for
tenant and ops, shared types, and migrations for supplier media resources,
price overrides, customer visibility and order refunds.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-29 23:17:01 +08:00

62 lines
1.3 KiB
Go

// 本地识别 CLI:读取一张或多张已保存的验证码 PNG,输出识别结果。
//
// 用法:
//
// go run ./cmd/recognize path/to/captcha.png [more.png ...]
//
// 想批量评估准确率时,把文件命名为"真值.png"(如 4930.png),脚本会自动对比。
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/geo-platform/tenant-api/internal/shared/digitocr"
)
func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, "usage: recognize <png> [png ...]")
os.Exit(2)
}
var total, correct int
for _, path := range os.Args[1:] {
got, err := digitocr.Recognize(path, digitocr.Options{})
if err != nil {
fmt.Printf("%s\tERROR: %v\n", path, err)
continue
}
truth := strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
if isAllDigits(truth) && len(truth) == len(got) {
total++
mark := "OK"
if got == truth {
correct++
} else {
mark = "MISS"
}
fmt.Printf("%s\t%s\t%s (truth=%s)\n", path, got, mark, truth)
} else {
fmt.Printf("%s\t%s\n", path, got)
}
}
if total > 0 {
fmt.Printf("\naccuracy: %d/%d = %.1f%%\n", correct, total, float64(correct)*100/float64(total))
}
}
func isAllDigits(s string) bool {
if s == "" {
return false
}
for _, r := range s {
if r < '0' || r > '9' {
return false
}
}
return true
}