|
|
package model |
|
|
|
|
|
import ( |
|
|
"crypto/rand" |
|
|
"crypto/rsa" |
|
|
"crypto/x509" |
|
|
"encoding/base64" |
|
|
"encoding/pem" |
|
|
"fmt" |
|
|
"strconv" |
|
|
"strings" |
|
|
"time" |
|
|
|
|
|
"go-common/app/admin/main/member/conf" |
|
|
memmdl "go-common/app/service/main/member/model" |
|
|
"go-common/library/log" |
|
|
xtime "go-common/library/time" |
|
|
|
|
|
"github.com/pkg/errors" |
|
|
) |
|
|
|
|
|
// realname conf var |
|
|
var ( |
|
|
RealnameSalt = "biliidentification@#$%^&*()(*&^%$#" |
|
|
RealnameImgPrefix = "/idenfiles/" |
|
|
RealnameImgSuffix = ".txt" |
|
|
|
|
|
LogActionRealnameUnbind = "realname_unbind" |
|
|
LogActionRealnameBack = "realname_back" |
|
|
LogActionRealnameSubmit = "realname_submit" |
|
|
|
|
|
RealnameManagerLogID = 251 |
|
|
) |
|
|
|
|
|
type realnameChannel string |
|
|
|
|
|
// RealnameChannle |
|
|
const ( |
|
|
ChannelMain realnameChannel = "main" |
|
|
ChannelAlipay realnameChannel = "alipay" |
|
|
) |
|
|
|
|
|
func (ch realnameChannel) DBChannel() uint8 { |
|
|
switch ch { |
|
|
case ChannelMain: |
|
|
return 0 |
|
|
case ChannelAlipay: |
|
|
return 1 |
|
|
} |
|
|
return 0 |
|
|
} |
|
|
|
|
|
type realnameAction string |
|
|
|
|
|
// RealnameAction |
|
|
const ( |
|
|
RealnameActionPass realnameAction = "pass" |
|
|
RealnameActionReject realnameAction = "reject" |
|
|
) |
|
|
|
|
|
// RealnameCardType is. |
|
|
type RealnameCardType string |
|
|
|
|
|
const ( |
|
|
cardTypeIdentityCard RealnameCardType = "identity_card" |
|
|
cardTypeForeignPassport RealnameCardType = "foreign_passport" |
|
|
//Mainland Travel Permit for Hong Kong and Macao Residents |
|
|
cardTypeHongkongMacaoPermit RealnameCardType = "hongkong_macao_travel_permit" |
|
|
//Mainland travel permit for Taiwan residents |
|
|
cardTypeTaiwanPermit RealnameCardType = "taiwan_travel_permit" |
|
|
cardTypeChinaPassport RealnameCardType = "china_passport" |
|
|
//Foreigner's Permanent Residence Card |
|
|
cardTypeForeignerPermanentResidenceCard RealnameCardType = "foreigner_permanent_residence_card" |
|
|
cardTypeForeignIdentityCard RealnameCardType = "foreign_identity_card" |
|
|
) |
|
|
|
|
|
// RealnameApplyStatus is. |
|
|
type RealnameApplyStatus string |
|
|
|
|
|
// RealnameApplyStatus |
|
|
const ( |
|
|
RealnameApplyStateAll RealnameApplyStatus = "all" |
|
|
RealnameApplyStatePending RealnameApplyStatus = "pending" |
|
|
RealnameApplyStatePassed RealnameApplyStatus = "passed" |
|
|
RealnameApplyStateRejective RealnameApplyStatus = "rejective" |
|
|
RealnameApplyStateNone RealnameApplyStatus = "none" |
|
|
) |
|
|
|
|
|
// DBStatus is. |
|
|
func (r RealnameApplyStatus) DBStatus() int { |
|
|
switch r { |
|
|
case RealnameApplyStatePending: |
|
|
return 0 |
|
|
case RealnameApplyStatePassed: |
|
|
return 1 |
|
|
case RealnameApplyStateRejective: |
|
|
return 2 |
|
|
default: |
|
|
return -1 |
|
|
} |
|
|
} |
|
|
|
|
|
// ArgRealnameList is. |
|
|
type ArgRealnameList struct { |
|
|
Channel realnameChannel `form:"channel" validate:"required"` |
|
|
MID int64 `form:"mid"` |
|
|
Card string `form:"card"` |
|
|
CardType RealnameCardType `form:"card_type"` |
|
|
Country int `form:"country"` |
|
|
OPName string `form:"op_name"` |
|
|
TSFrom int64 `form:"ts_from"` |
|
|
TSTo int64 `form:"ts_to"` |
|
|
State RealnameApplyStatus `form:"state"` |
|
|
PS int `form:"ps"` |
|
|
PN int `form:"pn"` |
|
|
IsDesc bool `form:"is_desc"` |
|
|
} |
|
|
|
|
|
// DBCardType return card_type store in db |
|
|
func (a *ArgRealnameList) DBCardType() int { |
|
|
switch a.CardType { |
|
|
case cardTypeIdentityCard: |
|
|
return 0 |
|
|
case cardTypeForeignPassport: |
|
|
return 1 |
|
|
case cardTypeHongkongMacaoPermit: |
|
|
return 2 |
|
|
case cardTypeTaiwanPermit: |
|
|
return 3 |
|
|
case cardTypeChinaPassport: |
|
|
return 4 |
|
|
case cardTypeForeignerPermanentResidenceCard: |
|
|
return 5 |
|
|
case cardTypeForeignIdentityCard: |
|
|
return 6 |
|
|
default: |
|
|
log.Warn("ArgRealnameList : %+v , unknown CardType", a) |
|
|
return -1 |
|
|
} |
|
|
} |
|
|
|
|
|
// DBCountry return country store in db |
|
|
func (a *ArgRealnameList) DBCountry() int { |
|
|
if a.CardType == "" { |
|
|
return -1 |
|
|
} |
|
|
return a.Country |
|
|
} |
|
|
|
|
|
// DBState return state store in db |
|
|
func (a *ArgRealnameList) DBState() int { |
|
|
switch a.State { |
|
|
case RealnameApplyStateAll: |
|
|
return -1 |
|
|
case RealnameApplyStatePending: |
|
|
return 0 |
|
|
case RealnameApplyStatePassed: |
|
|
return 1 |
|
|
case RealnameApplyStateRejective: |
|
|
return 2 |
|
|
case RealnameApplyStateNone: |
|
|
return 3 |
|
|
default: |
|
|
log.Warn("ArgRealnameList : %+v , unknown State", a) |
|
|
return 0 |
|
|
} |
|
|
} |
|
|
|
|
|
// ArgRealnamePendingList is. |
|
|
type ArgRealnamePendingList struct { |
|
|
Channel realnameChannel `form:"channel" validate:"required"` |
|
|
PS int `form:"ps"` |
|
|
PN int `form:"pn"` |
|
|
} |
|
|
|
|
|
// ArgRealnameAuditApply is. |
|
|
type ArgRealnameAuditApply struct { |
|
|
ID int64 `form:"id" validate:"required"` |
|
|
Channel realnameChannel `form:"channel" validate:"required"` |
|
|
Action realnameAction `form:"action" validate:"required"` |
|
|
Reason string `form:"reason"` |
|
|
} |
|
|
|
|
|
// DBChannel return channel store in db |
|
|
func (a *ArgRealnameAuditApply) DBChannel() int { |
|
|
switch a.Channel { |
|
|
case ChannelMain: |
|
|
return 0 |
|
|
case ChannelAlipay: |
|
|
return 1 |
|
|
default: |
|
|
log.Warn("ArgRealnameAuditApply : %+v , unknown Channel", a) |
|
|
return 0 |
|
|
} |
|
|
} |
|
|
|
|
|
// ArgRealnameReasonList is. |
|
|
type ArgRealnameReasonList struct { |
|
|
PS int `form:"ps"` |
|
|
PN int `form:"pn"` |
|
|
} |
|
|
|
|
|
// ArgRealnameSetReason is. |
|
|
type ArgRealnameSetReason struct { |
|
|
Reasons []string `form:"reasons,split"` |
|
|
} |
|
|
|
|
|
// ArgRealnameImage is. |
|
|
type ArgRealnameImage struct { |
|
|
Token string `form:"token" validate:"required"` |
|
|
} |
|
|
|
|
|
// ArgRealnameImagePreview is. |
|
|
type ArgRealnameImagePreview struct { |
|
|
ArgRealnameImage |
|
|
BorderSize uint `form:"border_size"` // 图片最大边长度(缩放后) |
|
|
} |
|
|
|
|
|
// ArgRealnameSearchCard is. |
|
|
type ArgRealnameSearchCard struct { |
|
|
Cards []string `form:"cards,split" validate:"required"` |
|
|
CardType int `form:"card_type"` |
|
|
Country int `form:"card_type"` |
|
|
} |
|
|
|
|
|
// RespRealnameApply is. |
|
|
type RespRealnameApply struct { |
|
|
ID int64 `json:"id"` |
|
|
Channel realnameChannel `json:"channel"` |
|
|
MID int64 `json:"mid"` |
|
|
Nickname string `json:"nickname"` |
|
|
Times int `json:"times"` |
|
|
CardType RealnameCardType `json:"card_type"` |
|
|
Country int16 `json:"country"` |
|
|
Card string `json:"card"` |
|
|
Realname string `json:"realname"` |
|
|
Level int32 `json:"level"` |
|
|
IMGIDs []int64 `json:"-"` |
|
|
IMGs []string `json:"imgs"` |
|
|
State RealnameApplyStatus `json:"state"` |
|
|
OPName string `json:"op_name"` |
|
|
OPTS int64 `json:"op_ts"` |
|
|
OPReason string `json:"op_reason"` |
|
|
CreateTS int64 `json:"create_ts"` |
|
|
} |
|
|
|
|
|
// ParseDBMainApply parse realname_apply from db |
|
|
func (r *RespRealnameApply) ParseDBMainApply(db *DBRealnameApply) { |
|
|
var err error |
|
|
r.ID = db.ID |
|
|
r.Channel = ChannelMain |
|
|
r.MID = db.MID |
|
|
r.CardType = r.convertCardType(db.CardType) |
|
|
r.Country = db.Country |
|
|
if db.CardNum != "" { |
|
|
if r.Card, err = CardDecrypt(db.CardNum); err != nil { |
|
|
log.Error("%+v", err) |
|
|
} |
|
|
} |
|
|
r.IMGIDs = append(r.IMGIDs, db.HandIMG, db.FrontIMG, db.BackIMG) |
|
|
r.Realname = db.Realname |
|
|
r.State = r.ParseStatus(db.Status) |
|
|
r.OPName = db.Operator |
|
|
r.OPTS = db.OperatorTime.Unix() |
|
|
r.OPReason = db.Remark |
|
|
r.CreateTS = db.CTime.Unix() |
|
|
} |
|
|
|
|
|
// ParseDBAlipayApply parse realname_alipay_apply from db |
|
|
func (r *RespRealnameApply) ParseDBAlipayApply(db *DBRealnameAlipayApply) { |
|
|
var err error |
|
|
r.ID = db.ID |
|
|
r.Channel = ChannelAlipay |
|
|
r.MID = db.MID |
|
|
r.CardType = cardTypeIdentityCard // identity_card |
|
|
r.Country = 0 // china |
|
|
if db.Card != "" { |
|
|
if r.Card, err = CardDecrypt(db.Card); err != nil { |
|
|
log.Error("%+v", err) |
|
|
} |
|
|
} |
|
|
r.ParseDBApplyIMG(db.IMG) |
|
|
r.Realname = db.Realname |
|
|
r.State = r.ParseStatus(db.Status) |
|
|
r.OPName = "alipay" |
|
|
if db.Operator != "" { |
|
|
r.OPName = db.Operator |
|
|
} |
|
|
r.OPTS = db.OperatorTime.Unix() |
|
|
r.OPReason = db.Reason |
|
|
r.CreateTS = db.CTime.Unix() |
|
|
} |
|
|
|
|
|
// ParseDBApplyIMG parse apply_img from db |
|
|
func (r *RespRealnameApply) ParseDBApplyIMG(token string) { |
|
|
r.IMGs = append(r.IMGs, imgURL(token)) |
|
|
} |
|
|
|
|
|
// ParseMember parse member info from rpc call |
|
|
func (r *RespRealnameApply) ParseMember(mem *memmdl.Member) { |
|
|
r.Nickname = mem.Name |
|
|
r.Level = mem.LevelInfo.Cur |
|
|
} |
|
|
|
|
|
func imgURL(token string) string { |
|
|
token = strings.TrimPrefix(token, "/idenfiles/") |
|
|
token = strings.TrimSuffix(token, ".txt") |
|
|
return fmt.Sprintf(conf.Conf.Realname.ImageURLTemplate, token) |
|
|
} |
|
|
|
|
|
// ParseStatus parse status stored in db |
|
|
func (r *RespRealnameApply) ParseStatus(status int) (s RealnameApplyStatus) { |
|
|
switch status { |
|
|
case 0: |
|
|
return RealnameApplyStatePending |
|
|
case 1: |
|
|
return RealnameApplyStatePassed |
|
|
case 2: |
|
|
return RealnameApplyStateRejective |
|
|
default: |
|
|
log.Warn("RespRealnameApply parse status err , unknown apply status :%d", status) |
|
|
return RealnameApplyStateNone |
|
|
} |
|
|
} |
|
|
|
|
|
// ConvertCardType convert card_type from db to api |
|
|
func (r *RespRealnameApply) convertCardType(cardType int8) (t RealnameCardType) { |
|
|
switch cardType { |
|
|
case 0: |
|
|
return cardTypeIdentityCard |
|
|
case 1: |
|
|
return cardTypeForeignPassport |
|
|
case 2: |
|
|
return cardTypeHongkongMacaoPermit |
|
|
case 3: |
|
|
return cardTypeTaiwanPermit |
|
|
case 4: |
|
|
return cardTypeChinaPassport |
|
|
case 5: |
|
|
return cardTypeForeignerPermanentResidenceCard |
|
|
case 6: |
|
|
return cardTypeForeignIdentityCard |
|
|
default: |
|
|
log.Warn("RespRealnameApply parse card type err , unknown card type :%d", cardType) |
|
|
return cardTypeIdentityCard |
|
|
} |
|
|
} |
|
|
|
|
|
// DBRealnameInfo is. |
|
|
type DBRealnameInfo struct { |
|
|
ID int64 `gorm:"column:id"` |
|
|
MID int64 `gorm:"column:mid"` |
|
|
Channel uint8 `gorm:"column:channel"` |
|
|
Realname string `gorm:"column:realname"` |
|
|
Country int16 `gorm:"column:country"` |
|
|
CardType int8 `gorm:"column:card_type"` |
|
|
Card string `gorm:"column:card"` |
|
|
CardMD5 string `gorm:"column:card_md5"` |
|
|
Status int `gorm:"column:status"` |
|
|
Reason string `gorm:"column:reason"` |
|
|
CTime time.Time `gorm:"column:ctime"` |
|
|
MTime time.Time `gorm:"column:mtime"` |
|
|
} |
|
|
|
|
|
// TableName is... |
|
|
func (d *DBRealnameInfo) TableName() string { |
|
|
return "realname_info" |
|
|
} |
|
|
|
|
|
// DBRealnameApply is. |
|
|
type DBRealnameApply struct { |
|
|
ID int64 `gorm:"column:id"` |
|
|
MID int64 `gorm:"column:mid"` |
|
|
Realname string `gorm:"column:realname"` |
|
|
Country int16 `gorm:"column:country"` |
|
|
CardType int8 `gorm:"column:card_type"` |
|
|
CardNum string `gorm:"column:card_num"` |
|
|
CardMD5 string `gorm:"column:card_md5"` |
|
|
HandIMG int64 `gorm:"column:hand_img"` |
|
|
FrontIMG int64 `gorm:"column:front_img"` |
|
|
BackIMG int64 `gorm:"column:back_img"` |
|
|
Status int `gorm:"column:status"` |
|
|
Operator string `gorm:"column:operator"` |
|
|
OperatorID int64 `gorm:"column:operator_id"` |
|
|
OperatorTime time.Time `gorm:"column:operator_time"` |
|
|
Remark string `gorm:"column:remark"` |
|
|
RemarkStatus int8 `gorm:"column:remark_status"` |
|
|
CTime time.Time `gorm:"column:ctime"` |
|
|
MTime time.Time `gorm:"column:mtime"` |
|
|
} |
|
|
|
|
|
// TableName is... |
|
|
func (d *DBRealnameApply) TableName() string { |
|
|
return "realname_apply" |
|
|
} |
|
|
|
|
|
// DBRealnameAlipayApply is. |
|
|
type DBRealnameAlipayApply struct { |
|
|
ID int64 `gorm:"column:id"` |
|
|
MID int64 `gorm:"column:mid"` |
|
|
Realname string `gorm:"column:realname"` |
|
|
Card string `gorm:"column:card"` |
|
|
IMG string `gorm:"column:img"` |
|
|
Status int `gorm:"column:status"` |
|
|
Reason string `gorm:"column:reason"` |
|
|
Bizno string `gorm:"column:bizno"` |
|
|
Operator string `gorm:"column:operator"` |
|
|
OperatorID int64 `gorm:"column:operator_id"` |
|
|
OperatorTime time.Time `gorm:"column:operator_time"` |
|
|
CTime time.Time `gorm:"column:ctime"` |
|
|
MTime time.Time `gorm:"column:mtime"` |
|
|
} |
|
|
|
|
|
// TableName is... |
|
|
func (d *DBRealnameAlipayApply) TableName() string { |
|
|
return "realname_alipay_apply" |
|
|
} |
|
|
|
|
|
// IsPassed is... |
|
|
func (d *DBRealnameApply) IsPassed() bool { |
|
|
return d.Status == 1 |
|
|
} |
|
|
|
|
|
// DBRealnameApplyIMG is. |
|
|
type DBRealnameApplyIMG struct { |
|
|
ID int64 `gorm:"column:id"` |
|
|
IMGData string `gorm:"column:img_data"` |
|
|
CTime time.Time `gorm:"column:ctime"` |
|
|
MTime time.Time `gorm:"column:mtime"` |
|
|
} |
|
|
|
|
|
// TableName ... |
|
|
func (d *DBRealnameApplyIMG) TableName() string { |
|
|
return "realname_apply_img" |
|
|
} |
|
|
|
|
|
// DBRealnameConfig ... |
|
|
type DBRealnameConfig struct { |
|
|
ID int64 `gorm:"column:id"` |
|
|
Key string `gorm:"column:key"` |
|
|
Data string `gorm:"column:data"` |
|
|
CTime time.Time `gorm:"column:ctime"` |
|
|
MTime time.Time `gorm:"column:mtime"` |
|
|
} |
|
|
|
|
|
// TableName ... |
|
|
func (d *DBRealnameConfig) TableName() string { |
|
|
return "realname_config" |
|
|
} |
|
|
|
|
|
// CardDecrypt is |
|
|
func CardDecrypt(data string) (text string, err error) { |
|
|
var ( |
|
|
dataBytes = []byte(data) |
|
|
decryptedData []byte |
|
|
textBytes []byte |
|
|
size int |
|
|
) |
|
|
decryptedData = make([]byte, base64.StdEncoding.DecodedLen(len(dataBytes))) |
|
|
if size, err = base64.StdEncoding.Decode(decryptedData, dataBytes); err != nil { |
|
|
err = errors.Wrapf(err, "base decode %s", data) |
|
|
return |
|
|
} |
|
|
if textBytes, err = rsaDecrypt(decryptedData[:size]); err != nil { |
|
|
err = errors.Wrapf(err, "rsa decrypt %s , data : %s", decryptedData, data) |
|
|
return |
|
|
} |
|
|
text = string(textBytes) |
|
|
return |
|
|
} |
|
|
|
|
|
func rsaDecrypt(text []byte) (content []byte, err error) { |
|
|
block, _ := pem.Decode(conf.Conf.Realname.RsaPriv) |
|
|
if block == nil { |
|
|
err = errors.New("private key error") |
|
|
return |
|
|
} |
|
|
var ( |
|
|
privateKey *rsa.PrivateKey |
|
|
) |
|
|
if privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil { |
|
|
err = errors.WithStack(err) |
|
|
return |
|
|
} |
|
|
if content, err = rsa.DecryptPKCS1v15(rand.Reader, privateKey, text); err != nil { |
|
|
err = errors.WithStack(err) |
|
|
return |
|
|
} |
|
|
return |
|
|
} |
|
|
|
|
|
// DBRealnameAuditLog is. |
|
|
type DBRealnameAuditLog struct { |
|
|
ID int64 `gorm:"column:id"` |
|
|
MID int64 `gorm:"column:mid"` |
|
|
AdminID int64 `gorm:"column:admin_id"` |
|
|
AdminName string `gorm:"column:admin_name"` |
|
|
Channel uint8 `gorm:"column:channel"` |
|
|
FromState int `gorm:"column:from_state"` |
|
|
ToState int `gorm:"column:to_state"` |
|
|
CTime time.Time `gorm:"column:ctime"` |
|
|
MTime time.Time `gorm:"column:mtime"` |
|
|
} |
|
|
|
|
|
// Tablename is. |
|
|
func (d *DBRealnameAuditLog) Tablename() string { |
|
|
return "realname_audit_log" |
|
|
} |
|
|
|
|
|
// Realname is. |
|
|
type Realname struct { |
|
|
State RealnameApplyStatus `json:"state"` |
|
|
Channel realnameChannel `json:"moral"` |
|
|
Card string `json:"card"` |
|
|
CardType int8 `json:"card_type"` |
|
|
Country int16 `json:"country"` |
|
|
Realname string `json:"realname"` |
|
|
Images []string `json:"images"` |
|
|
} |
|
|
|
|
|
// ParseDBApplyIMG parse apply_img from db |
|
|
func (r *Realname) ParseDBApplyIMG(token string) { |
|
|
r.Images = append(r.Images, imgURL(token)) |
|
|
} |
|
|
|
|
|
// ParseInfo . |
|
|
func (r *Realname) ParseInfo(info *DBRealnameInfo) { |
|
|
switch info.Status { |
|
|
case 0: |
|
|
r.State = RealnameApplyStatePending |
|
|
case 1: |
|
|
r.State = RealnameApplyStatePassed |
|
|
case 2: |
|
|
r.State = RealnameApplyStateRejective |
|
|
default: |
|
|
log.Warn("Realname status err , unknown info status :%d", info.Status) |
|
|
r.State = RealnameApplyStateNone |
|
|
} |
|
|
switch info.Channel { |
|
|
case 0: |
|
|
r.Channel = ChannelMain |
|
|
case 1: |
|
|
r.Channel = ChannelAlipay |
|
|
default: |
|
|
log.Warn("Realname channel err , unknown info channel :%d", info.Channel) |
|
|
r.Channel = ChannelMain |
|
|
} |
|
|
r.Realname = info.Realname |
|
|
r.CardType = info.CardType |
|
|
r.Country = info.Country |
|
|
var err error |
|
|
var maskedCard string |
|
|
if info.Card != "" && r.State == RealnameApplyStatePassed { |
|
|
if r.Card, err = CardDecrypt(info.Card); err != nil { |
|
|
log.Error("%+v", err) |
|
|
} |
|
|
var ( |
|
|
cStrs = strings.Split(r.Card, "") |
|
|
) |
|
|
if len(cStrs) > 0 { |
|
|
if len(cStrs) == 1 { |
|
|
maskedCard = "*" |
|
|
} else if len(cStrs) > 5 { |
|
|
|
|
|
maskedCard = cStrs[0] + strings.Repeat("*", len(cStrs)-3) + strings.Join(cStrs[len(cStrs)-2:], "") |
|
|
} else { |
|
|
maskedCard = cStrs[0] + strings.Repeat("*", len(cStrs)-1) |
|
|
} |
|
|
} |
|
|
r.Card = maskedCard |
|
|
} |
|
|
} |
|
|
|
|
|
// RealnameExport is. |
|
|
type RealnameExport struct { |
|
|
Mid int64 `json:"mid" gorm:"column:mid"` |
|
|
UserID string `json:"userid" gorm:"column:userid"` |
|
|
Uname string `json:"uname" gorm:"column:uname"` |
|
|
Realname string `json:"realname" gorm:"column:realname"` |
|
|
Tel string `json:"tel" gorm:"column:tel"` |
|
|
CardType int8 `json:"card_type" gorm:"column:card_type"` |
|
|
CardNum string `json:"card_num" gorm:"column:card_num"` |
|
|
} |
|
|
|
|
|
// PassportQueryByMidResult is. |
|
|
type PassportQueryByMidResult struct { |
|
|
Mid int64 `json:"mid"` |
|
|
Name string `json:"name"` |
|
|
Userid string `json:"userid"` |
|
|
Email string `json:"email"` |
|
|
Tel string `json:"tel"` |
|
|
Jointime xtime.Time `json:"jointime"` |
|
|
} |
|
|
|
|
|
var _cardTypeToString = map[int8]string{ |
|
|
0: "身份证", |
|
|
1: "护照(境外签发)", |
|
|
2: "港澳居民来往内地通行证", |
|
|
3: "台湾居民来往大陆通行证", |
|
|
4: "护照(中国签发)", |
|
|
5: "外国人永久居留证", |
|
|
6: "其他国家或地区身份证", |
|
|
} |
|
|
|
|
|
// CardTypeString is |
|
|
func CardTypeString(cardType int8) string { |
|
|
typeString, ok := _cardTypeToString[cardType] |
|
|
if !ok { |
|
|
return strconv.FormatInt(int64(cardType), 10) |
|
|
} |
|
|
return typeString |
|
|
}
|
|
|
|