273 lines
7.3 KiB
Go
273 lines
7.3 KiB
Go
package model
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"io"
|
||
"io/ioutil"
|
||
"net/http"
|
||
"net/url"
|
||
"strconv"
|
||
"time"
|
||
"unicode/utf8"
|
||
)
|
||
|
||
const (
|
||
grant_type = "client_credentials"
|
||
)
|
||
|
||
var accessToken string
|
||
var expires_in uint64
|
||
|
||
type OcrQuery struct {
|
||
IdCardUrl string `json:"idCardUrl"`
|
||
Side int `json:"side"` // 1 正面 2 反面
|
||
}
|
||
|
||
type OcrRes struct {
|
||
RealName string `json:"realName"`
|
||
IDNum string `json:"iDNum"`
|
||
Path string `json:"path"`
|
||
Age int `json:"age"`
|
||
Birthday string `json:"birthday"`
|
||
Sex string `json:"sex"`
|
||
IssueDate string `json:"issueDate"`
|
||
ExpirationDate string `json:"expirationDate"`
|
||
}
|
||
|
||
const (
|
||
ocr_client_id = "cLg2dUH1pqopsj22tShw8FQU"
|
||
ocr_client_secret = "diriz5PmhLOB8hwE4KnEEiaBMV6WfBR1"
|
||
)
|
||
|
||
type OrcRes struct {
|
||
Path string `json:"path"`
|
||
Name string `json:"name"`
|
||
IdCard string `json:"idCard"`
|
||
Age int `json:"age"`
|
||
Birthday string `json:"birthday"`
|
||
Sex string `json:"sex"`
|
||
IssueDate string `json:"issueDate"`
|
||
ExpirationDate string `json:"expirationDate"`
|
||
}
|
||
|
||
type OcrGetIdCardRes struct {
|
||
WordsResult WordsResult `json:"words_result"`
|
||
IdcardNumberType int `json:"idcard_number_type"`
|
||
WordsResultNum int `json:"words_result_num"`
|
||
ImageStatus string `json:"image_status"`
|
||
LogId uint64 `json:"log_id"`
|
||
}
|
||
type WordsResult struct {
|
||
Name WordsResultDetail `json:"姓名"`
|
||
Address WordsResultDetail `json:"住址"`
|
||
IdCard WordsResultDetail `json:"公民身份号码"`
|
||
Birthday WordsResultDetail `json:"出生"`
|
||
Sex WordsResultDetail `json:"性别"`
|
||
IssueDate WordsResultDetail `json:"签发日期"`
|
||
ExpirationDate WordsResultDetail `json:"失效日期"`
|
||
}
|
||
type WordsResultDetail struct {
|
||
Words string
|
||
}
|
||
|
||
type AccessToken struct {
|
||
Refresh_token string `json:"refresh_token"`
|
||
Expires_in uint64 `json:"expires_in"`
|
||
Scope string `json:"scope"`
|
||
Session_key string `json:"session_key"`
|
||
Access_token string `json:"access_token"`
|
||
Session_secret string `json:"session_secret"`
|
||
Error string `json:"error"`
|
||
Error_description string `json:"error_description"`
|
||
}
|
||
|
||
func OcrGetIdCard(image string, side string) (*OrcRes, error) {
|
||
var (
|
||
accesstoken string
|
||
response string
|
||
err error
|
||
)
|
||
if accesstoken, err = GetOcrAccessToken(); err != nil {
|
||
fmt.Println(err.Error())
|
||
return nil, err
|
||
}
|
||
if response, err = PostForm("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=["+accesstoken+"]", url.Values{"image": {image}, "id_card_side": {side}}); err != nil {
|
||
fmt.Println(err.Error())
|
||
return nil, err
|
||
}
|
||
var res OcrGetIdCardRes
|
||
if err = json.Unmarshal([]byte(response), &res); err != nil {
|
||
return nil, err
|
||
}
|
||
fmt.Printf("%+v\n", res)
|
||
|
||
switch res.ImageStatus {
|
||
case "normal":
|
||
|
||
case "reversed_side":
|
||
return nil, errors.New("身份证正反面颠倒")
|
||
case "non_idcard":
|
||
return nil, errors.New("上传的图片中不包含身份证")
|
||
case "blurred":
|
||
return nil, errors.New("身份证模糊")
|
||
case "other_type_card":
|
||
return nil, errors.New("其他类型证照")
|
||
case "over_exposure":
|
||
return nil, errors.New("身份证关键字段反光或过曝")
|
||
case "over_dark":
|
||
return nil, errors.New("身份证欠曝(亮度过低)")
|
||
case "unknown":
|
||
return nil, errors.New("未知状态")
|
||
default:
|
||
return nil, errors.New("未知状态")
|
||
}
|
||
if side == "front" {
|
||
switch res.IdcardNumberType {
|
||
case -1:
|
||
return nil, errors.New("身份证正面所有字段全为空")
|
||
case 0:
|
||
return nil, errors.New(" 身份证证号不合法,此情况下不返回身份证证号")
|
||
case 1:
|
||
case 2:
|
||
return nil, errors.New("身份证证号和性别、出生信息都不一致")
|
||
case 3:
|
||
return nil, errors.New("身份证证号和出生信息不一致")
|
||
case 4:
|
||
return nil, errors.New("身份证证号和性别信息不一致")
|
||
default:
|
||
return nil, errors.New("未知状态")
|
||
}
|
||
}
|
||
var result OrcRes
|
||
fmt.Println(res.WordsResult.Name.Words)
|
||
if side == "front" {
|
||
result.Name = res.WordsResult.Name.Words
|
||
result.Birthday = res.WordsResult.Birthday.Words
|
||
result.IdCard = res.WordsResult.IdCard.Words
|
||
result.Sex = res.WordsResult.Sex.Words
|
||
result.Path = res.WordsResult.Address.Words
|
||
var age int
|
||
|
||
birYear, _ := strconv.Atoi(result.Birthday[0:4])
|
||
birMonth, _ := strconv.Atoi(result.Birthday[4:6])
|
||
fmt.Println(birYear)
|
||
fmt.Println(time.Now().Year())
|
||
age = time.Now().Year() - birYear
|
||
|
||
if int(time.Now().Month()) < birMonth {
|
||
age--
|
||
}
|
||
|
||
result.Age = age
|
||
} else {
|
||
issueDate := res.WordsResult.IssueDate.Words[:4] + "-" + res.WordsResult.IssueDate.Words[4:6] + "-" + res.WordsResult.IssueDate.Words[6:8]
|
||
result.IssueDate = issueDate
|
||
expirationDate := res.WordsResult.ExpirationDate.Words[:4] + "-" + res.WordsResult.ExpirationDate.Words[4:6] + "-" + res.WordsResult.ExpirationDate.Words[6:8]
|
||
result.ExpirationDate = expirationDate
|
||
}
|
||
|
||
return &result, nil
|
||
}
|
||
|
||
func (m *OcrRes) CheckIdAndName() {
|
||
if utf8.RuneCountInString(m.RealName) == 18 && utf8.RuneCountInString(m.IDNum) != 18 {
|
||
m.IDNum, m.RealName = m.RealName, m.IDNum
|
||
}
|
||
}
|
||
|
||
func GetOcrAccessToken() (string, error) {
|
||
var (
|
||
resObj AccessToken
|
||
err error
|
||
// daoAccessToken entity.AccessToken
|
||
)
|
||
if expires_in == 0 || expires_in < uint64(time.Now().Unix()) {
|
||
fmt.Println(1)
|
||
// if daoAccessToken, err = dao.GetAccessToken("baidu", "accesstoken"); err != nil { //查询是否有记录
|
||
// return "", err
|
||
// }
|
||
// fmt.Println(2)
|
||
if resObj, err = getOcrAccessToken(); err != nil { //从链上获取
|
||
return "", err
|
||
}
|
||
// var tmp = entity.AccessToken{
|
||
// Platform: "baidu",
|
||
// Types: "accesstoken",
|
||
// Txt: resObj.Access_token,
|
||
// Expires_in: uint64(time.Now().Unix()) + resObj.Expires_in,
|
||
// }
|
||
// if daoAccessToken.Uid == 0 {
|
||
// if err = dao.AddAccessToken(tmp); err != nil {
|
||
// return "", err
|
||
// }
|
||
// } else {
|
||
// if _, err = dao.UpdateAccessToken(tmp); err != nil {
|
||
// return "", err
|
||
// }
|
||
// }
|
||
accessToken = resObj.Access_token
|
||
expires_in = resObj.Expires_in
|
||
}
|
||
return accessToken, nil
|
||
|
||
}
|
||
|
||
func getOcrAccessToken() (AccessToken, error) {
|
||
var (
|
||
resObj AccessToken
|
||
err error
|
||
)
|
||
url := "https://aip.baidubce.com/oauth/2.0/token"
|
||
urlReq := "?grant_type=" + grant_type + "&client_id=" + ocr_client_id + "&client_secret=" + ocr_client_secret
|
||
fmt.Println(urlReq)
|
||
res := Get(url + urlReq)
|
||
if err = json.Unmarshal([]byte(res), &resObj); err != nil {
|
||
return resObj, err
|
||
}
|
||
if resObj.Error != "" {
|
||
return resObj, errors.New(resObj.Error_description)
|
||
}
|
||
return resObj, err
|
||
}
|
||
|
||
func PostForm(urlStr string, data url.Values) (string, error) {
|
||
resp, err := http.PostForm(urlStr, data)
|
||
|
||
if err != nil {
|
||
// handle error
|
||
}
|
||
defer resp.Body.Close()
|
||
body, err := ioutil.ReadAll(resp.Body)
|
||
if err != nil {
|
||
// handle error
|
||
}
|
||
return string(body), err
|
||
}
|
||
|
||
func Get(url string) string {
|
||
|
||
// 超时时间:5秒
|
||
client := &http.Client{Timeout: 5 * time.Second}
|
||
resp, err := client.Get(url)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
defer resp.Body.Close()
|
||
var buffer [512]byte
|
||
result := bytes.NewBuffer(nil)
|
||
for {
|
||
n, err := resp.Body.Read(buffer[0:])
|
||
result.Write(buffer[0:n])
|
||
if err != nil && err == io.EOF {
|
||
break
|
||
} else if err != nil {
|
||
panic(err)
|
||
}
|
||
}
|
||
|
||
return result.String()
|
||
}
|