realname.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. package model
  2. import (
  3. "crypto/rand"
  4. "crypto/rsa"
  5. "crypto/x509"
  6. "encoding/base64"
  7. "encoding/pem"
  8. "fmt"
  9. "strconv"
  10. "strings"
  11. "time"
  12. "go-common/app/admin/main/member/conf"
  13. memmdl "go-common/app/service/main/member/model"
  14. "go-common/library/log"
  15. xtime "go-common/library/time"
  16. "github.com/pkg/errors"
  17. )
  18. // realname conf var
  19. var (
  20. RealnameSalt = "biliidentification@#$%^&*()(*&^%$#"
  21. RealnameImgPrefix = "/idenfiles/"
  22. RealnameImgSuffix = ".txt"
  23. LogActionRealnameUnbind = "realname_unbind"
  24. LogActionRealnameBack = "realname_back"
  25. LogActionRealnameSubmit = "realname_submit"
  26. RealnameManagerLogID = 251
  27. )
  28. type realnameChannel string
  29. // RealnameChannle
  30. const (
  31. ChannelMain realnameChannel = "main"
  32. ChannelAlipay realnameChannel = "alipay"
  33. )
  34. func (ch realnameChannel) DBChannel() uint8 {
  35. switch ch {
  36. case ChannelMain:
  37. return 0
  38. case ChannelAlipay:
  39. return 1
  40. }
  41. return 0
  42. }
  43. type realnameAction string
  44. // RealnameAction
  45. const (
  46. RealnameActionPass realnameAction = "pass"
  47. RealnameActionReject realnameAction = "reject"
  48. )
  49. // RealnameCardType is.
  50. type RealnameCardType string
  51. const (
  52. cardTypeIdentityCard RealnameCardType = "identity_card"
  53. cardTypeForeignPassport RealnameCardType = "foreign_passport"
  54. //Mainland Travel Permit for Hong Kong and Macao Residents
  55. cardTypeHongkongMacaoPermit RealnameCardType = "hongkong_macao_travel_permit"
  56. //Mainland travel permit for Taiwan residents
  57. cardTypeTaiwanPermit RealnameCardType = "taiwan_travel_permit"
  58. cardTypeChinaPassport RealnameCardType = "china_passport"
  59. //Foreigner's Permanent Residence Card
  60. cardTypeForeignerPermanentResidenceCard RealnameCardType = "foreigner_permanent_residence_card"
  61. cardTypeForeignIdentityCard RealnameCardType = "foreign_identity_card"
  62. )
  63. // RealnameApplyStatus is.
  64. type RealnameApplyStatus string
  65. // RealnameApplyStatus
  66. const (
  67. RealnameApplyStateAll RealnameApplyStatus = "all"
  68. RealnameApplyStatePending RealnameApplyStatus = "pending"
  69. RealnameApplyStatePassed RealnameApplyStatus = "passed"
  70. RealnameApplyStateRejective RealnameApplyStatus = "rejective"
  71. RealnameApplyStateNone RealnameApplyStatus = "none"
  72. )
  73. // DBStatus is.
  74. func (r RealnameApplyStatus) DBStatus() int {
  75. switch r {
  76. case RealnameApplyStatePending:
  77. return 0
  78. case RealnameApplyStatePassed:
  79. return 1
  80. case RealnameApplyStateRejective:
  81. return 2
  82. default:
  83. return -1
  84. }
  85. }
  86. // ArgRealnameList is.
  87. type ArgRealnameList struct {
  88. Channel realnameChannel `form:"channel" validate:"required"`
  89. MID int64 `form:"mid"`
  90. Card string `form:"card"`
  91. CardType RealnameCardType `form:"card_type"`
  92. Country int `form:"country"`
  93. OPName string `form:"op_name"`
  94. TSFrom int64 `form:"ts_from"`
  95. TSTo int64 `form:"ts_to"`
  96. State RealnameApplyStatus `form:"state"`
  97. PS int `form:"ps"`
  98. PN int `form:"pn"`
  99. IsDesc bool `form:"is_desc"`
  100. }
  101. // DBCardType return card_type store in db
  102. func (a *ArgRealnameList) DBCardType() int {
  103. switch a.CardType {
  104. case cardTypeIdentityCard:
  105. return 0
  106. case cardTypeForeignPassport:
  107. return 1
  108. case cardTypeHongkongMacaoPermit:
  109. return 2
  110. case cardTypeTaiwanPermit:
  111. return 3
  112. case cardTypeChinaPassport:
  113. return 4
  114. case cardTypeForeignerPermanentResidenceCard:
  115. return 5
  116. case cardTypeForeignIdentityCard:
  117. return 6
  118. default:
  119. log.Warn("ArgRealnameList : %+v , unknown CardType", a)
  120. return -1
  121. }
  122. }
  123. // DBCountry return country store in db
  124. func (a *ArgRealnameList) DBCountry() int {
  125. if a.CardType == "" {
  126. return -1
  127. }
  128. return a.Country
  129. }
  130. // DBState return state store in db
  131. func (a *ArgRealnameList) DBState() int {
  132. switch a.State {
  133. case RealnameApplyStateAll:
  134. return -1
  135. case RealnameApplyStatePending:
  136. return 0
  137. case RealnameApplyStatePassed:
  138. return 1
  139. case RealnameApplyStateRejective:
  140. return 2
  141. case RealnameApplyStateNone:
  142. return 3
  143. default:
  144. log.Warn("ArgRealnameList : %+v , unknown State", a)
  145. return 0
  146. }
  147. }
  148. // ArgRealnamePendingList is.
  149. type ArgRealnamePendingList struct {
  150. Channel realnameChannel `form:"channel" validate:"required"`
  151. PS int `form:"ps"`
  152. PN int `form:"pn"`
  153. }
  154. // ArgRealnameAuditApply is.
  155. type ArgRealnameAuditApply struct {
  156. ID int64 `form:"id" validate:"required"`
  157. Channel realnameChannel `form:"channel" validate:"required"`
  158. Action realnameAction `form:"action" validate:"required"`
  159. Reason string `form:"reason"`
  160. }
  161. // DBChannel return channel store in db
  162. func (a *ArgRealnameAuditApply) DBChannel() int {
  163. switch a.Channel {
  164. case ChannelMain:
  165. return 0
  166. case ChannelAlipay:
  167. return 1
  168. default:
  169. log.Warn("ArgRealnameAuditApply : %+v , unknown Channel", a)
  170. return 0
  171. }
  172. }
  173. // ArgRealnameReasonList is.
  174. type ArgRealnameReasonList struct {
  175. PS int `form:"ps"`
  176. PN int `form:"pn"`
  177. }
  178. // ArgRealnameSetReason is.
  179. type ArgRealnameSetReason struct {
  180. Reasons []string `form:"reasons,split"`
  181. }
  182. // ArgRealnameImage is.
  183. type ArgRealnameImage struct {
  184. Token string `form:"token" validate:"required"`
  185. }
  186. // ArgRealnameImagePreview is.
  187. type ArgRealnameImagePreview struct {
  188. ArgRealnameImage
  189. BorderSize uint `form:"border_size"` // 图片最大边长度(缩放后)
  190. }
  191. // ArgRealnameSearchCard is.
  192. type ArgRealnameSearchCard struct {
  193. Cards []string `form:"cards,split" validate:"required"`
  194. CardType int `form:"card_type"`
  195. Country int `form:"card_type"`
  196. }
  197. // RespRealnameApply is.
  198. type RespRealnameApply struct {
  199. ID int64 `json:"id"`
  200. Channel realnameChannel `json:"channel"`
  201. MID int64 `json:"mid"`
  202. Nickname string `json:"nickname"`
  203. Times int `json:"times"`
  204. CardType RealnameCardType `json:"card_type"`
  205. Country int16 `json:"country"`
  206. Card string `json:"card"`
  207. Realname string `json:"realname"`
  208. Level int32 `json:"level"`
  209. IMGIDs []int64 `json:"-"`
  210. IMGs []string `json:"imgs"`
  211. State RealnameApplyStatus `json:"state"`
  212. OPName string `json:"op_name"`
  213. OPTS int64 `json:"op_ts"`
  214. OPReason string `json:"op_reason"`
  215. CreateTS int64 `json:"create_ts"`
  216. }
  217. // ParseDBMainApply parse realname_apply from db
  218. func (r *RespRealnameApply) ParseDBMainApply(db *DBRealnameApply) {
  219. var err error
  220. r.ID = db.ID
  221. r.Channel = ChannelMain
  222. r.MID = db.MID
  223. r.CardType = r.convertCardType(db.CardType)
  224. r.Country = db.Country
  225. if db.CardNum != "" {
  226. if r.Card, err = CardDecrypt(db.CardNum); err != nil {
  227. log.Error("%+v", err)
  228. }
  229. }
  230. r.IMGIDs = append(r.IMGIDs, db.HandIMG, db.FrontIMG, db.BackIMG)
  231. r.Realname = db.Realname
  232. r.State = r.ParseStatus(db.Status)
  233. r.OPName = db.Operator
  234. r.OPTS = db.OperatorTime.Unix()
  235. r.OPReason = db.Remark
  236. r.CreateTS = db.CTime.Unix()
  237. }
  238. // ParseDBAlipayApply parse realname_alipay_apply from db
  239. func (r *RespRealnameApply) ParseDBAlipayApply(db *DBRealnameAlipayApply) {
  240. var err error
  241. r.ID = db.ID
  242. r.Channel = ChannelAlipay
  243. r.MID = db.MID
  244. r.CardType = cardTypeIdentityCard // identity_card
  245. r.Country = 0 // china
  246. if db.Card != "" {
  247. if r.Card, err = CardDecrypt(db.Card); err != nil {
  248. log.Error("%+v", err)
  249. }
  250. }
  251. r.ParseDBApplyIMG(db.IMG)
  252. r.Realname = db.Realname
  253. r.State = r.ParseStatus(db.Status)
  254. r.OPName = "alipay"
  255. if db.Operator != "" {
  256. r.OPName = db.Operator
  257. }
  258. r.OPTS = db.OperatorTime.Unix()
  259. r.OPReason = db.Reason
  260. r.CreateTS = db.CTime.Unix()
  261. }
  262. // ParseDBApplyIMG parse apply_img from db
  263. func (r *RespRealnameApply) ParseDBApplyIMG(token string) {
  264. r.IMGs = append(r.IMGs, imgURL(token))
  265. }
  266. // ParseMember parse member info from rpc call
  267. func (r *RespRealnameApply) ParseMember(mem *memmdl.Member) {
  268. r.Nickname = mem.Name
  269. r.Level = mem.LevelInfo.Cur
  270. }
  271. func imgURL(token string) string {
  272. token = strings.TrimPrefix(token, "/idenfiles/")
  273. token = strings.TrimSuffix(token, ".txt")
  274. return fmt.Sprintf(conf.Conf.Realname.ImageURLTemplate, token)
  275. }
  276. // ParseStatus parse status stored in db
  277. func (r *RespRealnameApply) ParseStatus(status int) (s RealnameApplyStatus) {
  278. switch status {
  279. case 0:
  280. return RealnameApplyStatePending
  281. case 1:
  282. return RealnameApplyStatePassed
  283. case 2:
  284. return RealnameApplyStateRejective
  285. default:
  286. log.Warn("RespRealnameApply parse status err , unknown apply status :%d", status)
  287. return RealnameApplyStateNone
  288. }
  289. }
  290. // ConvertCardType convert card_type from db to api
  291. func (r *RespRealnameApply) convertCardType(cardType int8) (t RealnameCardType) {
  292. switch cardType {
  293. case 0:
  294. return cardTypeIdentityCard
  295. case 1:
  296. return cardTypeForeignPassport
  297. case 2:
  298. return cardTypeHongkongMacaoPermit
  299. case 3:
  300. return cardTypeTaiwanPermit
  301. case 4:
  302. return cardTypeChinaPassport
  303. case 5:
  304. return cardTypeForeignerPermanentResidenceCard
  305. case 6:
  306. return cardTypeForeignIdentityCard
  307. default:
  308. log.Warn("RespRealnameApply parse card type err , unknown card type :%d", cardType)
  309. return cardTypeIdentityCard
  310. }
  311. }
  312. // DBRealnameInfo is.
  313. type DBRealnameInfo struct {
  314. ID int64 `gorm:"column:id"`
  315. MID int64 `gorm:"column:mid"`
  316. Channel uint8 `gorm:"column:channel"`
  317. Realname string `gorm:"column:realname"`
  318. Country int16 `gorm:"column:country"`
  319. CardType int8 `gorm:"column:card_type"`
  320. Card string `gorm:"column:card"`
  321. CardMD5 string `gorm:"column:card_md5"`
  322. Status int `gorm:"column:status"`
  323. Reason string `gorm:"column:reason"`
  324. CTime time.Time `gorm:"column:ctime"`
  325. MTime time.Time `gorm:"column:mtime"`
  326. }
  327. // TableName is...
  328. func (d *DBRealnameInfo) TableName() string {
  329. return "realname_info"
  330. }
  331. // DBRealnameApply is.
  332. type DBRealnameApply struct {
  333. ID int64 `gorm:"column:id"`
  334. MID int64 `gorm:"column:mid"`
  335. Realname string `gorm:"column:realname"`
  336. Country int16 `gorm:"column:country"`
  337. CardType int8 `gorm:"column:card_type"`
  338. CardNum string `gorm:"column:card_num"`
  339. CardMD5 string `gorm:"column:card_md5"`
  340. HandIMG int64 `gorm:"column:hand_img"`
  341. FrontIMG int64 `gorm:"column:front_img"`
  342. BackIMG int64 `gorm:"column:back_img"`
  343. Status int `gorm:"column:status"`
  344. Operator string `gorm:"column:operator"`
  345. OperatorID int64 `gorm:"column:operator_id"`
  346. OperatorTime time.Time `gorm:"column:operator_time"`
  347. Remark string `gorm:"column:remark"`
  348. RemarkStatus int8 `gorm:"column:remark_status"`
  349. CTime time.Time `gorm:"column:ctime"`
  350. MTime time.Time `gorm:"column:mtime"`
  351. }
  352. // TableName is...
  353. func (d *DBRealnameApply) TableName() string {
  354. return "realname_apply"
  355. }
  356. // DBRealnameAlipayApply is.
  357. type DBRealnameAlipayApply struct {
  358. ID int64 `gorm:"column:id"`
  359. MID int64 `gorm:"column:mid"`
  360. Realname string `gorm:"column:realname"`
  361. Card string `gorm:"column:card"`
  362. IMG string `gorm:"column:img"`
  363. Status int `gorm:"column:status"`
  364. Reason string `gorm:"column:reason"`
  365. Bizno string `gorm:"column:bizno"`
  366. Operator string `gorm:"column:operator"`
  367. OperatorID int64 `gorm:"column:operator_id"`
  368. OperatorTime time.Time `gorm:"column:operator_time"`
  369. CTime time.Time `gorm:"column:ctime"`
  370. MTime time.Time `gorm:"column:mtime"`
  371. }
  372. // TableName is...
  373. func (d *DBRealnameAlipayApply) TableName() string {
  374. return "realname_alipay_apply"
  375. }
  376. // IsPassed is...
  377. func (d *DBRealnameApply) IsPassed() bool {
  378. return d.Status == 1
  379. }
  380. // DBRealnameApplyIMG is.
  381. type DBRealnameApplyIMG struct {
  382. ID int64 `gorm:"column:id"`
  383. IMGData string `gorm:"column:img_data"`
  384. CTime time.Time `gorm:"column:ctime"`
  385. MTime time.Time `gorm:"column:mtime"`
  386. }
  387. // TableName ...
  388. func (d *DBRealnameApplyIMG) TableName() string {
  389. return "realname_apply_img"
  390. }
  391. // DBRealnameConfig ...
  392. type DBRealnameConfig struct {
  393. ID int64 `gorm:"column:id"`
  394. Key string `gorm:"column:key"`
  395. Data string `gorm:"column:data"`
  396. CTime time.Time `gorm:"column:ctime"`
  397. MTime time.Time `gorm:"column:mtime"`
  398. }
  399. // TableName ...
  400. func (d *DBRealnameConfig) TableName() string {
  401. return "realname_config"
  402. }
  403. // CardDecrypt is
  404. func CardDecrypt(data string) (text string, err error) {
  405. var (
  406. dataBytes = []byte(data)
  407. decryptedData []byte
  408. textBytes []byte
  409. size int
  410. )
  411. decryptedData = make([]byte, base64.StdEncoding.DecodedLen(len(dataBytes)))
  412. if size, err = base64.StdEncoding.Decode(decryptedData, dataBytes); err != nil {
  413. err = errors.Wrapf(err, "base decode %s", data)
  414. return
  415. }
  416. if textBytes, err = rsaDecrypt(decryptedData[:size]); err != nil {
  417. err = errors.Wrapf(err, "rsa decrypt %s , data : %s", decryptedData, data)
  418. return
  419. }
  420. text = string(textBytes)
  421. return
  422. }
  423. func rsaDecrypt(text []byte) (content []byte, err error) {
  424. block, _ := pem.Decode(conf.Conf.Realname.RsaPriv)
  425. if block == nil {
  426. err = errors.New("private key error")
  427. return
  428. }
  429. var (
  430. privateKey *rsa.PrivateKey
  431. )
  432. if privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes); err != nil {
  433. err = errors.WithStack(err)
  434. return
  435. }
  436. if content, err = rsa.DecryptPKCS1v15(rand.Reader, privateKey, text); err != nil {
  437. err = errors.WithStack(err)
  438. return
  439. }
  440. return
  441. }
  442. // DBRealnameAuditLog is.
  443. type DBRealnameAuditLog struct {
  444. ID int64 `gorm:"column:id"`
  445. MID int64 `gorm:"column:mid"`
  446. AdminID int64 `gorm:"column:admin_id"`
  447. AdminName string `gorm:"column:admin_name"`
  448. Channel uint8 `gorm:"column:channel"`
  449. FromState int `gorm:"column:from_state"`
  450. ToState int `gorm:"column:to_state"`
  451. CTime time.Time `gorm:"column:ctime"`
  452. MTime time.Time `gorm:"column:mtime"`
  453. }
  454. // Tablename is.
  455. func (d *DBRealnameAuditLog) Tablename() string {
  456. return "realname_audit_log"
  457. }
  458. // Realname is.
  459. type Realname struct {
  460. State RealnameApplyStatus `json:"state"`
  461. Channel realnameChannel `json:"moral"`
  462. Card string `json:"card"`
  463. CardType int8 `json:"card_type"`
  464. Country int16 `json:"country"`
  465. Realname string `json:"realname"`
  466. Images []string `json:"images"`
  467. }
  468. // ParseDBApplyIMG parse apply_img from db
  469. func (r *Realname) ParseDBApplyIMG(token string) {
  470. r.Images = append(r.Images, imgURL(token))
  471. }
  472. // ParseInfo .
  473. func (r *Realname) ParseInfo(info *DBRealnameInfo) {
  474. switch info.Status {
  475. case 0:
  476. r.State = RealnameApplyStatePending
  477. case 1:
  478. r.State = RealnameApplyStatePassed
  479. case 2:
  480. r.State = RealnameApplyStateRejective
  481. default:
  482. log.Warn("Realname status err , unknown info status :%d", info.Status)
  483. r.State = RealnameApplyStateNone
  484. }
  485. switch info.Channel {
  486. case 0:
  487. r.Channel = ChannelMain
  488. case 1:
  489. r.Channel = ChannelAlipay
  490. default:
  491. log.Warn("Realname channel err , unknown info channel :%d", info.Channel)
  492. r.Channel = ChannelMain
  493. }
  494. r.Realname = info.Realname
  495. r.CardType = info.CardType
  496. r.Country = info.Country
  497. var err error
  498. var maskedCard string
  499. if info.Card != "" && r.State == RealnameApplyStatePassed {
  500. if r.Card, err = CardDecrypt(info.Card); err != nil {
  501. log.Error("%+v", err)
  502. }
  503. var (
  504. cStrs = strings.Split(r.Card, "")
  505. )
  506. if len(cStrs) > 0 {
  507. if len(cStrs) == 1 {
  508. maskedCard = "*"
  509. } else if len(cStrs) > 5 {
  510. maskedCard = cStrs[0] + strings.Repeat("*", len(cStrs)-3) + strings.Join(cStrs[len(cStrs)-2:], "")
  511. } else {
  512. maskedCard = cStrs[0] + strings.Repeat("*", len(cStrs)-1)
  513. }
  514. }
  515. r.Card = maskedCard
  516. }
  517. }
  518. // RealnameExport is.
  519. type RealnameExport struct {
  520. Mid int64 `json:"mid" gorm:"column:mid"`
  521. UserID string `json:"userid" gorm:"column:userid"`
  522. Uname string `json:"uname" gorm:"column:uname"`
  523. Realname string `json:"realname" gorm:"column:realname"`
  524. Tel string `json:"tel" gorm:"column:tel"`
  525. CardType int8 `json:"card_type" gorm:"column:card_type"`
  526. CardNum string `json:"card_num" gorm:"column:card_num"`
  527. }
  528. // PassportQueryByMidResult is.
  529. type PassportQueryByMidResult struct {
  530. Mid int64 `json:"mid"`
  531. Name string `json:"name"`
  532. Userid string `json:"userid"`
  533. Email string `json:"email"`
  534. Tel string `json:"tel"`
  535. Jointime xtime.Time `json:"jointime"`
  536. }
  537. var _cardTypeToString = map[int8]string{
  538. 0: "身份证",
  539. 1: "护照(境外签发)",
  540. 2: "港澳居民来往内地通行证",
  541. 3: "台湾居民来往大陆通行证",
  542. 4: "护照(中国签发)",
  543. 5: "外国人永久居留证",
  544. 6: "其他国家或地区身份证",
  545. }
  546. // CardTypeString is
  547. func CardTypeString(cardType int8) string {
  548. typeString, ok := _cardTypeToString[cardType]
  549. if !ok {
  550. return strconv.FormatInt(int64(cardType), 10)
  551. }
  552. return typeString
  553. }