代码拉取完成,页面将自动刷新
package xutil
import (
"encoding/json"
"errors"
"fmt"
"sync"
"time"
"gitee.com/wosylf/ltool"
"gitee.com/wosylf/ltool/pkg/util"
"gitee.com/wosylf/ltool/pkg/xhttp"
)
type BaiduToken struct {
AccessToken string ` json:"access_token" form:"access_token"`
ExpiresIn int64 ` json:"expires_in" form:"expires_in"` //过期时间
}
type UserCard struct {
Name string `gorm:"type:varchar(8);comment:'真实姓名'" json:"name" form:"name"`
FacadeUrl string `gorm:"type:varchar(128);comment:'身份证正面地址'" json:"facade_url,omitempty" form:"facade_url"`
BackUrl string `gorm:"type:varchar(128);comment:'身份证反面地址'" json:"back_url,omitempty" form:"back_url"`
Cardid string `gorm:"type:char(18);comment:'身份证号';index" json:"cardid" form:"cardid"` //身份证号
Md5cardid string `gorm:"-" json:"-" form:"-"` //身份证号
Address string `gorm:"type:varchar(26);comment:'住址'" json:"address" form:"address"` //住址
Birthday string `gorm:"type:char(8);comment:'出生'" json:"birthday" form:"birthday"` //生日
Sex string `gorm:"type:char(1);comment:'性别'" json:"sex" form:"sex"` //性别
Nation string `gorm:"type:varchar(5);comment:'民族'" json:"nation" form:"nation"` //民族
Issue string `gorm:"type:char(8);comment:'签发日期'" json:"issue" form:"issue"` //签发日期
Invalid string `gorm:"type:char(8);comment:'失效日期'" json:"invalid" form:"invalid"` //失效日期
Section string `gorm:"type:varchar(16);comment:'签发机关'" json:"section" form:"section"` //签发机关
Age uint8 `gorm:"comment:'年龄'" json:"age" form:"age"` //失效日期
Surface string `gorm:"-" json:"-" form:"-"` //是正面还是反面
}
type BaiduCard struct {
ImageStatus string ` json:"image_status" form:"image_status"` //图片状态
ErrorCode int ` json:"error_code" form:"error_code"` //图片状态
RiskType string ` json:"risk_type" form:"risk_type"` //风险类型
EditTool string ` json:"edit_tool" form:"edit_tool"` //用啥软件编辑过图片
WordsResult map[string]WordsResult ` json:"words_result" form:"words_result"` //风险类型
CardQuality CardQuality ` json:"card_quality" form:"card_quality"` //风险类型
}
type CardQuality struct {
IsClear_propobility float64 ` json:"IsClear_propobility" form:"IsClear_propobility"`
IsClear float64 ` json:"IsClear" form:"IsClear"` //是否清晰
IsNoCover_propobility float64 ` json:"IsNoCover_propobility" form:"IsNoCover_propobility"`
IsNoCover float64 ` json:"IsNoCover" form:"IsNoCover"` //是否边框/四角完整
IsComplete_propobility float64 ` json:"IsComplete_propobility" form:"IsComplete_propobility"`
IsComplete float64 ` json:"IsComplete" form:"IsComplete"` //是否头像、关键字段无遮挡/马赛克
}
type WordsResult struct {
Location Location ` json:"location" form:"location"`
Words string ` json:"words" form:"words"`
}
type Location struct {
Top float64 ` json:"top" form:"top"`
Left float64 ` json:"left" form:"left"`
Width float64 ` json:"width" form:"width"`
Height float64 ` json:"height" form:"height"`
}
const (
百度获取token地址 = "https://aip.baidubce.com/ouc/2.0/token?grant_type=client_credentials&client_id=%v&client_secret=%v"
百度身份识别地址 = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token="
百度识别正面 = "front"
百度识别反面 = "back"
V身份证签发日期 = "签发日期"
V身份证失效日期 = "失效日期"
V身份证签发机关 = "签发机关"
V身份证姓名 = "姓名"
V身份证民族 = "民族"
V身份证住址 = "住址"
V身份证身份号 = "公民身份号码"
V身份证生日 = "出生"
V身份证性别 = "性别"
)
var (
身份证风险数组 = map[string]string{
"copy": "识别异常,请拍身份证重新上传",
"temporary": "不能为临时身份证,请拍身份证上传",
"screen": "不能为翻拍照片",
"unknown": "照片异常",
}
身份证状态数组 = map[string]string{
"non_idcard": "上传的图片中不包含身份证",
"blurred": "身份证模糊,请重新上传",
"other_type_card": "其他类型证照,请上传身份证照片",
"over_exposure": "身份证关键字段反光或过曝,请调整亮度重新上传",
"over_dark": "身份证欠曝,请拍亮一些",
"unknown": "照片异常,请重试",
}
)
type FBaidu struct {
Ak string
Sk string
Tk string
Exp int64
M sync.RWMutex
}
func F新建百度识别(ak, sk string) *FBaidu {
return &FBaidu{Ak: ak, Sk: sk}
}
func (a *FBaidu) F获取缓存token() (token string, err error) {
//先看缓存有没有
a.M.RLock()
if a.Tk != "" && a.Exp > time.Now().Unix() {
a.M.RUnlock()
return a.Tk, nil
} else {
a.M.RUnlock()
}
a.M.Lock()
a.Tk, a.Exp, err = a.F获取token()
a.M.Unlock()
//bm["access_token"]
return
}
func (a *FBaidu) F获取Tk与过期时间和锁() (string, int64, *sync.RWMutex) {
return a.Tk, a.Exp, &a.M
}
func (a *FBaidu) F获取token() (token string, exp int64, err error) {
//先看缓存有没有
url := fmt.Sprintf(百度获取token地址, a.Ak, a.Sk)
_, by, err := xhttp.NewClient().Get(url).EndBytes(ctx)
if err != nil {
return
}
var bm BaiduToken
if err = json.Unmarshal(by, &bm); err != nil {
return
}
if bm.AccessToken == "" {
err = errors.New("获取百度token失败")
return
}
a.Tk, a.Exp = bm.AccessToken, bm.ExpiresIn+time.Now().Unix()-60
return a.Tk, a.Exp, nil
}
// 第一个为路径,第二个为正反面,默认正面
func (a *FBaidu) F身份证识别(args ...string) (uc *UserCard, err error) {
token, err := util.F获取缓存token(a)
if err != nil {
return
}
path := args[0]
正反面 := 百度识别正面
if len(args) > 1 {
正反面 = args[1]
}
var bm1 BaiduCard
url := 百度身份识别地址 + token
bm := make(ltool.BodyMap)
bm.
Set("url", path).
Set("id_card_side", 正反面).
Set("detect_risk", "true").
Set("detect_quality", "true")
//Set("detect_card","true")//是否对身份证进行裁剪,暂时先不裁剪
encodeurl := bm.EncodeURLParams()
_, err = xhttp.NewClient().Type(xhttp.TypeFormData).Post(url).SendString(encodeurl).EndStruct(ctx, &bm1)
if err != nil {
return
}
if bm1.ImageStatus != "normal" && bm1.ImageStatus != "reversed_side" {
err = errors.New(身份证状态数组[bm1.ImageStatus])
return
}
if bm1.EditTool != "" {
err = errors.New("身份证被剪辑过,请直接拍照上传")
//这里上传的身份证被编辑过,可以加一道风控
return
}
if bm1.RiskType != "normal" && bm1.RiskType != "" {
err = errors.New(身份证风险数组[bm1.RiskType])
return
}
if _, ok := bm1.WordsResult[V身份证签发日期]; ok {
// 存在
正反面 = 百度识别反面
}
uc = new(UserCard)
if 正反面 == 百度识别反面 || (bm1.ImageStatus == "reversed_side" && 正反面 != 百度识别反面) {
//plug.Println("反面")
newt := StrToInt(time.Now().Format("20060102")) //当前时间
uc.Issue = bm1.WordsResult[V身份证签发日期].Words
uc.Invalid = bm1.WordsResult[V身份证失效日期].Words
uc.Section = bm1.WordsResult[V身份证签发机关].Words
uc.BackUrl = path
if newt < StrToInt(uc.Issue) {
err = errors.New("签发日期异常")
return
}
if newt > StrToInt(uc.Invalid) {
err = errors.New("身份证已过期")
return
}
//uc.Age = uint8(newt - StrToInt(uc.Birthday)/10000)
} else {
//plug.Println("正面")
uc.FacadeUrl = path
uc.Birthday = bm1.WordsResult[V身份证生日].Words
uc.Name = bm1.WordsResult[V身份证姓名].Words
uc.Sex = bm1.WordsResult[V身份证性别].Words
uc.Cardid = bm1.WordsResult[V身份证身份号].Words
uc.Age = uint8(F生日转年龄(bm1.WordsResult[V身份证生日].Words))
uc.Nation = bm1.WordsResult[V身份证民族].Words
uc.Address = bm1.WordsResult[V身份证住址].Words
}
uc.Surface = 正反面
return
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。