wp
workabee 7 months ago
parent ee9737442f
commit 90e942e61f

@ -3,6 +3,7 @@ module github.com/exhibition-main
go 1.20
replace (
github.com/fonchain/utils/baidu => ../utils/baidu
github.com/fonchain_enterprise/utils/aes => ../utils/aes
github.com/fonchain_enterprise/utils/chain => ../utils/chain
github.com/fonchain_enterprise/utils/feie => ../utils/feie
@ -22,6 +23,7 @@ require (
github.com/dubbogo/gost v1.13.2
github.com/dubbogo/grpc-go v1.42.10
github.com/dubbogo/triple v1.2.2-rc2
github.com/fonchain/utils/baidu v0.0.0-00010101000000-000000000000
github.com/fonchain_enterprise/utils/objstorage v0.0.0-00010101000000-000000000000
github.com/gin-contrib/gzip v0.0.6
github.com/gin-contrib/pprof v1.4.0

@ -0,0 +1,264 @@
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"`
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"`
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:"性别"`
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("未知状态")
}
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 {
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()
}

@ -37,7 +37,7 @@ func NewRouter() *gin.Engine {
registerAuth.POST("check_by_phone", service.CheckByPhone) //检索手机号
registerAuth.POST("save_register_info", service.SaveRegister) //保存
registerAuth.POST("export_register", service.ExportRegister) //导出
registerAuth.POST("scan_id_card", service.GetCardIdWithImg) //扫描身份证图片获取信息
registerAuth.POST("scan_id_card", service.OcrBase64) //扫描身份证图片获取信息
}
//静态文件

@ -242,7 +242,6 @@ func PutBos(filePath string, mediaType string, needRemove bool) (url string, err
err = errors.New(msg.ErrorUploadBos)
return
}
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
url = fmt.Sprintf("%s/%s", config.Data.Bos.CdnHost, objectName)
return
}
@ -265,7 +264,6 @@ func quickBos(file *multipart.FileHeader, mediaType string, mask string, source
logger.Errorf("quickBos err", err)
return
}
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
url = fmt.Sprintf("%s/%s", config.Data.Bos.CdnHost, objectName)
return
}

@ -2,9 +2,9 @@ package service
import (
"context"
"encoding/base64"
"fmt"
"github.com/dubbogo/gost/log/logger"
"github.com/exhibition-main/api/artist"
"github.com/exhibition-main/api/exhibition"
"github.com/exhibition-main/internal/config"
"github.com/exhibition-main/internal/model"
@ -13,6 +13,9 @@ import (
"github.com/exhibition-main/pkg/logic"
"github.com/exhibition-main/pkg/utils"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"io/ioutil"
"net/http"
"time"
)
@ -131,23 +134,64 @@ func ExportRegister(c *gin.Context) {
}
func GetCardIdWithImg(c *gin.Context) {
var listReq artist.GetCardIdWithImgReq
if err := c.ShouldBind(&listReq); err != nil {
logger.Errorf("GetCardIdWithImg ShouldBind err", err)
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
func OcrBase64(c *gin.Context) {
var req model.OcrQuery
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
logger.Errorf("OcrBase64 ShouldBind err", err)
response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil)
return
}
if err := listReq.Validate(); err != nil {
err = utils.SubstrError(err)
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
img := req.IdCardUrl
response1, err := http.Get(img)
if err != nil {
fmt.Println("网络请求错误:", err)
return
}
defer response1.Body.Close()
// 读取图片数据
imageData, err := ioutil.ReadAll(response1.Body)
if err != nil {
fmt.Println("读取图片数据错误:", err)
return
}
resp, err := GrpcArtistImpl.GetCardIdWithImg(context.Background(), &listReq)
// 将图片数据转换为base64编码
base64Data := base64.StdEncoding.EncodeToString(imageData)
fmt.Println(base64Data)
side := ""
if req.Side == 1 {
side = "front"
} else {
side = "back"
}
result, err := model.OcrGetIdCard(base64Data, side)
if err != nil {
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
return
}
response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp)
res := model.OcrRes{}
if side == "front" {
res.IDNum = result.IdCard
res.RealName = result.Name
res.Path = result.Path
res.Age = result.Age
res.Birthday = result.Birthday
res.Sex = result.Sex
fmt.Println("身份证和名字", res.IDNum, res.RealName)
res.CheckIdAndName()
fmt.Println("身份证和名字", res.IDNum, res.RealName)
} else {
res.ExpirationDate = result.ExpirationDate
}
response.ResponseQuickMsg(c, msg.Ok, "操作成功", res)
return
}

Loading…
Cancel
Save