123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772 |
- package service
- import (
- "bufio"
- "bytes"
- "context"
- "crypto/md5"
- "encoding/hex"
- "fmt"
- "image"
- "image/jpeg"
- "image/png"
- "io/ioutil"
- mrand "math/rand"
- "os"
- "strconv"
- "strings"
- "syscall"
- "time"
- "go-common/app/admin/main/member/conf"
- "go-common/app/admin/main/member/model"
- memmdl "go-common/app/service/main/member/model"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/net/metadata"
- "go-common/library/queue/databus/report"
- "github.com/nfnt/resize"
- "github.com/pkg/errors"
- )
- // consts
- const (
- _512KiloBytes = 512 * 1024
- )
- // RealnameList .
- func (s *Service) RealnameList(ctx context.Context, arg *model.ArgRealnameList) (list []*model.RespRealnameApply, total int, err error) {
- list = make([]*model.RespRealnameApply, 0)
- switch arg.Channel {
- case model.ChannelMain:
- return s.realnameMainList(ctx, arg)
- case model.ChannelAlipay:
- return s.realnameAlipayList(ctx, arg)
- }
- return
- }
- func (s *Service) realnameMainList(ctx context.Context, arg *model.ArgRealnameList) (list []*model.RespRealnameApply, total int, err error) {
- var (
- dl []*model.DBRealnameApply
- )
- if arg.Card != "" {
- // 如果查询证件号, 则通过证件号MD5 realname_info 查询到 对应的 mids
- var (
- infos []*model.DBRealnameInfo
- mids []int64
- md5 = cardMD5(arg.Card, arg.DBCardType(), arg.Country)
- )
- log.Info("realnameMainList card: %s, md5: %s", arg.Card, md5)
- if infos, err = s.dao.RealnameInfoByCardMD5(ctx, md5, arg.State.DBStatus(), model.ChannelMain.DBChannel()); err != nil {
- return
- }
- log.Info("realnameMainList infos : %+v", infos)
- if len(infos) <= 0 {
- return
- }
- for _, i := range infos {
- log.Info("realnameMainList info: %+v", i)
- mids = append(mids, i.MID)
- }
- log.Info("realnameMainList mids: %+v", mids)
- if dl, total, err = s.dao.RealnameMainList(ctx, mids, arg.DBCardType(), arg.DBCountry(), arg.OPName, arg.TSFrom, arg.TSTo, arg.DBState(), arg.PN, arg.PS, arg.IsDesc); err != nil {
- return
- }
- } else {
- var (
- mids []int64
- )
- if arg.MID > 0 {
- mids = append(mids, arg.MID)
- }
- if dl, total, err = s.dao.RealnameMainList(ctx, mids, arg.DBCardType(), arg.DBCountry(), arg.OPName, arg.TSFrom, arg.TSTo, arg.DBState(), arg.PN, arg.PS, arg.IsDesc); err != nil {
- return
- }
- }
- var (
- midMap = make(map[int64]int) // map[mid]count
- mids []int64
- imgIDs []int64
- )
- // 审核 db 数据解析进 list
- for _, d := range dl {
- midMap[d.MID] = 0
- var (
- r = &model.RespRealnameApply{}
- )
- r.ParseDBMainApply(d)
- imgIDs = append(imgIDs, d.HandIMG, d.FrontIMG, d.BackIMG)
- list = append(list, r)
- }
- // 没有数据则返回
- if len(midMap) <= 0 {
- return
- }
- // 获取实名申请次数
- for mid := range midMap {
- if midMap[mid], err = s.dao.RealnameApplyCount(ctx, mid); err != nil {
- return
- }
- mids = append(mids, mid)
- }
- // 获取mid的昵称 & 等级信息
- var (
- memsArg = &memmdl.ArgMemberMids{
- Mids: mids,
- }
- memMap map[int64]*memmdl.Member
- imgMap map[int64]*model.DBRealnameApplyIMG
- )
- if memMap, err = s.memberRPC.Members(ctx, memsArg); err != nil {
- err = errors.WithStack(err)
- return
- }
- // 获取证件照信息
- if imgMap, err = s.dao.RealnameApplyIMG(ctx, imgIDs); err != nil {
- return
- }
- for _, ra := range list {
- if mem, ok := memMap[ra.MID]; ok {
- ra.ParseMember(mem)
- }
- for _, id := range ra.IMGIDs {
- if img, ok := imgMap[id]; ok {
- ra.ParseDBApplyIMG(img.IMGData)
- }
- }
- ra.Times = midMap[ra.MID]
- }
- return
- }
- func (s *Service) realnameAlipayList(ctx context.Context, arg *model.ArgRealnameList) (list []*model.RespRealnameApply, total int, err error) {
- var (
- dl []*model.DBRealnameAlipayApply
- )
- if arg.Card != "" {
- // 如果查询证件号, 则通过证件号MD5 realname_info 查询到 对应的 mids
- var (
- infos []*model.DBRealnameInfo
- mids []int64
- md5 = cardMD5(arg.Card, arg.DBCardType(), arg.Country)
- )
- log.Info("realnameAlipayList card: %s, md5: %s", arg.Card, md5)
- if infos, err = s.dao.RealnameInfoByCardMD5(ctx, md5, arg.State.DBStatus(), model.ChannelAlipay.DBChannel()); err != nil {
- return
- }
- log.Info("realnameAlipayList infos : %+v", infos)
- if len(infos) <= 0 {
- return
- }
- for _, i := range infos {
- log.Info("realnameAlipayList info: %+v", i)
- mids = append(mids, i.MID)
- }
- log.Info("realnameAlipayList mids: %+v", mids)
- if dl, total, err = s.dao.RealnameAlipayList(ctx, mids, 0, 0, arg.State.DBStatus(), arg.PN, arg.PS, arg.IsDesc); err != nil {
- return
- }
- } else {
- var (
- mids []int64
- )
- if arg.MID > 0 {
- mids = append(mids, arg.MID)
- }
- if dl, total, err = s.dao.RealnameAlipayList(ctx, mids, arg.TSFrom, arg.TSTo, arg.State.DBStatus(), arg.PN, arg.PS, arg.IsDesc); err != nil {
- return
- }
- }
- log.Info("realnameAlipayList dl: %+v, total: %d", dl, total)
- var (
- midMap = make(map[int64]int)
- )
- // append to list
- for _, d := range dl {
- midMap[d.MID] = 0
- var (
- r = &model.RespRealnameApply{}
- )
- r.ParseDBAlipayApply(d)
- list = append(list, r)
- }
- if len(midMap) <= 0 {
- return
- }
- var mids []int64
- for mid := range midMap {
- if midMap[mid], err = s.dao.RealnameApplyCount(ctx, mid); err != nil {
- return
- }
- mids = append(mids, mid)
- }
- var (
- memsArg = &memmdl.ArgMemberMids{
- Mids: mids,
- }
- memMap map[int64]*memmdl.Member
- )
- if memMap, err = s.memberRPC.Members(ctx, memsArg); err != nil {
- err = errors.WithStack(err)
- return
- }
- for _, ra := range list {
- if mem, ok := memMap[ra.MID]; ok {
- ra.ParseMember(mem)
- }
- ra.Times = midMap[ra.MID]
- }
- return
- }
- func cardMD5(card string, cardType int, country int) (res string) {
- if card == "" || cardType < 0 || country < 0 {
- return
- }
- var (
- lowerCode = strings.ToLower(card)
- key = fmt.Sprintf("%s_%s_%d_%d", model.RealnameSalt, lowerCode, cardType, country)
- )
- return fmt.Sprintf("%x", md5.Sum([]byte(key)))
- }
- // RealnamePendingList .
- func (s *Service) RealnamePendingList(ctx context.Context, arg *model.ArgRealnamePendingList) (list []*model.RespRealnameApply, total int, err error) {
- var (
- larg = &model.ArgRealnameList{
- Channel: arg.Channel,
- State: model.RealnameApplyStatePending,
- TSFrom: time.Now().Add(-time.Hour * 24 * 7).Unix(),
- PS: arg.PS,
- PN: arg.PN,
- }
- )
- return s.RealnameList(ctx, larg)
- }
- // RealnameAuditApply .
- func (s *Service) RealnameAuditApply(ctx context.Context, arg *model.ArgRealnameAuditApply, adminName string, adminID int64) (err error) {
- var (
- mid int64
- )
- // 1. check the apply state
- switch arg.Channel {
- case model.ChannelMain:
- var apply *model.DBRealnameApply
- if apply, err = s.dao.RealnameMainApply(ctx, arg.ID); err != nil {
- return
- }
- if apply.IsPassed() {
- return
- }
- mid = apply.MID
- case model.ChannelAlipay:
- var apply *model.DBRealnameAlipayApply
- if apply, err = s.dao.RealnameAlipayApply(ctx, arg.ID); err != nil {
- return
- }
- if apply.Status == model.RealnameApplyStateNone.DBStatus() || apply.Status == model.RealnameApplyStateRejective.DBStatus() {
- return
- }
- mid = apply.MID
- }
- var (
- state = 0
- msgTitle = ""
- msgContent = ""
- mc = "2_2_1"
- expNotify = false
- )
- switch arg.Action {
- case model.RealnameActionPass:
- state = model.RealnameApplyStatePassed.DBStatus()
- msgTitle = "您提交的实名认证已审核通过"
- msgContent = "恭喜,您提交的实名认证已通过审核"
- expNotify = true
- case model.RealnameActionReject:
- state = model.RealnameApplyStateRejective.DBStatus()
- msgTitle = "您提交的实名认证未通过审核"
- msgContent = fmt.Sprintf(`抱歉,您提交的实名认证未通过审核,驳回原因:%s。请修改后重新提交实名认证。`, arg.Reason)
- default:
- err = ecode.RequestErr
- return
- }
- // 2. do something
- switch arg.Channel {
- case model.ChannelMain:
- if err = s.dao.UpdateOldRealnameApply(ctx, arg.ID, state, adminName, adminID, time.Now(), arg.Reason); err != nil {
- return
- }
- case model.ChannelAlipay:
- if err = s.dao.UpdateRealnameAlipayApply(ctx, arg.ID, adminID, adminName, state, arg.Reason); err != nil {
- return
- }
- if err = s.dao.UpdateRealnameInfo(ctx, mid, state, arg.Reason); err != nil {
- return
- }
- }
- go func() {
- if err := s.dao.RawMessage(context.Background(), mc, msgTitle, msgContent, []int64{mid}); err != nil {
- log.Error("%+v", err)
- }
- if expNotify {
- expMsg := &model.AddExpMsg{
- Event: "identify",
- Mid: mid,
- IP: metadata.String(ctx, metadata.RemoteIP),
- Ts: time.Now().Unix(),
- }
- if err := s.dao.PubExpMsg(ctx, expMsg); err != nil {
- log.Error("%+v", err)
- }
- }
- }()
- return
- }
- // RealnameReasonList .
- func (s *Service) RealnameReasonList(ctx context.Context, arg *model.ArgRealnameReasonList) (list []string, total int, err error) {
- return s.dao.RealnameReasonList(ctx)
- }
- // RealnameSetReason .
- func (s *Service) RealnameSetReason(ctx context.Context, arg *model.ArgRealnameSetReason) (err error) {
- return s.dao.UpdateRealnameReason(ctx, arg.Reasons)
- }
- // RealnameSearchCard .
- func (s *Service) RealnameSearchCard(ctx context.Context, cards []string, cardType int, country int) (data map[string]int64, err error) {
- var (
- hashmap = make(map[string]string) //map[hash]card
- hashes = make([]string, 0)
- list []*model.DBRealnameInfo
- )
- for _, card := range cards {
- hash := cardMD5(card, cardType, country)
- hashmap[hash] = card
- hashes = append(hashes, hash)
- }
- if list, err = s.dao.RealnameSearchCards(ctx, hashes); err != nil {
- return
- }
- data = make(map[string]int64)
- for _, l := range list {
- if rawCode, ok := hashmap[l.CardMD5]; ok {
- data[rawCode] = l.MID
- }
- }
- return
- }
- // RealnameUnbind is.
- func (s *Service) RealnameUnbind(ctx context.Context, mid int64, adminName string, adminID int64) (err error) {
- var (
- info *model.DBRealnameInfo
- )
- if info, err = s.dao.RealnameInfo(ctx, mid); err != nil {
- return
- }
- if info == nil {
- err = ecode.RealnameAlipayApplyInvalid
- return
- }
- if info.Status != model.RealnameApplyStatePassed.DBStatus() {
- return
- }
- if err = s.dao.UpdateRealnameInfo(ctx, mid, model.RealnameApplyStateRejective.DBStatus(), "管理后台解绑"); err != nil {
- return
- }
- switch info.Channel {
- case model.ChannelMain.DBChannel():
- if err = s.dao.RejectRealnameMainApply(ctx, mid, adminName, adminID, "管理后台解绑"); err != nil {
- return
- }
- case model.ChannelAlipay.DBChannel():
- if err = s.dao.RejectRealnameAlipayApply(ctx, mid, adminName, adminID, "管理后台解绑"); err != nil {
- return
- }
- default:
- log.Warn("Failed to reject realname apply: unrecognized channel: %+v", info)
- }
- go func() {
- r := &report.ManagerInfo{
- Uname: adminName,
- UID: adminID,
- Business: model.RealnameManagerLogID,
- Type: 0,
- Oid: mid,
- Action: model.LogActionRealnameUnbind,
- Ctime: time.Now(),
- }
- if err = report.Manager(r); err != nil {
- log.Error("Send manager log failed : %+v , report : %+v", err, r)
- err = nil
- return
- }
- log.Info("Send manager log success report : %+v", r)
- }()
- return
- }
- // RealnameImage return img
- func (s *Service) RealnameImage(ctx context.Context, token string) ([]byte, error) {
- filePath := fmt.Sprintf("%s/%s.txt", conf.Conf.Realname.DataDir, token)
- _, err := os.Stat(filePath)
- if os.IsNotExist(err) {
- log.Info("file : %s , not found", filePath)
- return nil, ecode.RequestErr
- }
- file, err := os.Open(filePath)
- if err != nil {
- return nil, errors.WithStack(err)
- }
- defer file.Close()
- img, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, errors.WithStack(err)
- }
- return s.mainCryptor.IMGDecrypt(img)
- }
- // FetchRealnameImage is
- func (s *Service) FetchRealnameImage(ctx context.Context, token string) ([]byte, error) {
- img, err := s.dao.GetRealnameImageCache(ctx, asIMGData(token))
- if err == nil && len(img) > 0 {
- return img, nil
- }
- if err != nil {
- log.Warn("Failed to get realname image from cache: %s: %+v", token, err)
- }
- img, err = s.RealnameImage(ctx, token)
- if err != nil {
- return nil, err
- }
- if len(img) <= _512KiloBytes {
- return img, nil
- }
- striped, err := StripImage(img)
- if err != nil {
- log.Warn("Failed to strip image: %+v", err)
- return img, nil
- }
- return striped, nil
- }
- // RealnameImagePreview return preview img
- func (s *Service) RealnameImagePreview(ctx context.Context, token string, borderSize uint) (data []byte, err error) {
- var (
- src []byte
- )
- if src, err = s.RealnameImage(ctx, token); err != nil {
- return
- }
- if len(src) == 0 {
- return
- }
- var (
- img image.Image
- imgWidth, imgHeight int
- imgFormat string
- sr = bytes.NewReader(src)
- )
- if img, imgFormat, err = image.Decode(sr); err != nil {
- log.Warn("Failed to decode image: %+v, return origin image data directly", err)
- return src, nil
- }
- imgWidth, imgHeight = img.Bounds().Dx(), img.Bounds().Dy()
- log.Info("Decode img : %s , format : %s , width : %d , height : %d ", token, imgFormat, imgWidth, imgHeight)
- if imgFormat != "png" && imgFormat != "jpg" && imgFormat != "jpeg" {
- return
- }
- if imgWidth > imgHeight {
- img = resize.Resize(borderSize, 0, img, resize.Lanczos3)
- } else {
- img = resize.Resize(0, borderSize, img, resize.Lanczos3)
- }
- var (
- bb bytes.Buffer
- bw = bufio.NewWriter(&bb)
- )
- switch imgFormat {
- case "jpg", "jpeg":
- if err = jpeg.Encode(bw, img, nil); err != nil {
- err = errors.WithStack(err)
- return
- }
- case "png":
- if err = png.Encode(bw, img); err != nil {
- err = errors.WithStack(err)
- return
- }
- }
- data = bb.Bytes()
- return
- }
- // RealnameExcel export user realname info
- func (s *Service) RealnameExcel(ctx context.Context, mids []int64) ([]*model.RealnameExport, error) {
- infos, err := s.dao.BatchRealnameInfo(ctx, mids)
- if err != nil {
- log.Warn("Failed to get realname info with mids: %+v: %+v", mids, err)
- // keep an empty infos
- infos = make(map[int64]*model.DBRealnameInfo)
- }
- pinfos, err := s.dao.PassportQueryByMidsChunked(ctx, mids, 100)
- if err != nil {
- log.Warn("Failed to get passport query by mids: %+v: %+v", mids, err)
- // keep an empty infos
- pinfos = make(map[int64]*model.PassportQueryByMidResult)
- }
- res := make([]*model.RealnameExport, 0, len(mids))
- for _, mid := range mids {
- export := &model.RealnameExport{
- Mid: mid,
- }
- // passport
- func() {
- p, ok := pinfos[mid]
- if !ok {
- log.Warn("Failed to get passport info with mid: %d", mid)
- return
- }
- export.UserID = p.Userid
- export.Uname = p.Name
- export.Tel = p.Tel
- }()
- // realname
- func() {
- info, ok := infos[mid]
- if !ok {
- log.Warn("Failed to get realname info with mid: %d", mid)
- return
- }
- export.Realname = info.Realname
- export.CardType = info.CardType
- cardDecode, err := model.CardDecrypt(info.Card)
- if err != nil {
- log.Error("Failed to decrypt card: %s: %+v", info.Card, err)
- return
- }
- export.CardNum = cardDecode
- }()
- res = append(res, export)
- }
- return res, nil
- }
- // RealnameSubmit is
- func (s *Service) RealnameSubmit(ctx context.Context, arg *model.ArgRealnameSubmit) error {
- encryptedCardNum, err := s.realnameCrypto.CardEncrypt([]byte(arg.CardNum))
- if err != nil {
- return err
- }
- _ = func() error {
- front := &model.DBRealnameApplyIMG{IMGData: asIMGData(arg.FrontImageToken)}
- if err := s.dao.AddRealnameIMG(ctx, front); err != nil {
- return err
- }
- back := &model.DBRealnameApplyIMG{IMGData: asIMGData(arg.BackImageToken)}
- if err := s.dao.AddRealnameIMG(ctx, back); err != nil {
- return err
- }
- apply := &model.DBRealnameApply{
- MID: arg.Mid,
- Realname: arg.Realname,
- Country: arg.Country,
- CardType: arg.CardType,
- CardNum: string(encryptedCardNum),
- CardMD5: cardMD5(arg.CardNum, int(arg.CardType), int(arg.Country)),
- FrontIMG: front.ID,
- BackIMG: back.ID,
- Status: model.RealnameApplyStatePassed.DBStatus(),
- Operator: arg.Operator,
- OperatorID: arg.OperatorID,
- OperatorTime: time.Now(),
- }
- if arg.HandImageToken != "" {
- hand := &model.DBRealnameApplyIMG{IMGData: asIMGData(arg.HandImageToken)}
- if err := s.dao.AddRealnameIMG(ctx, hand); err != nil {
- return err
- }
- apply.HandIMG = hand.ID
- }
- if err := s.dao.AddRealnameApply(ctx, apply); err != nil {
- return err
- }
- info := &model.DBRealnameInfo{
- MID: apply.MID,
- Channel: model.ChannelMain.DBChannel(),
- Realname: apply.Realname,
- Country: apply.Country,
- CardType: apply.CardType,
- Card: apply.CardNum,
- CardMD5: apply.CardMD5,
- Status: model.RealnameApplyStatePassed.DBStatus(),
- Reason: fmt.Sprintf("管理后台提交:%s", arg.Remark),
- }
- return s.dao.SubmitRealnameInfo(ctx, info)
- }
- toOld := func() error {
- front := &model.DeDeIdentificationCardApplyImg{IMGData: asIMGData(arg.FrontImageToken)}
- if err := s.dao.AddOldRealnameIMG(ctx, front); err != nil {
- return err
- }
- back := &model.DeDeIdentificationCardApplyImg{IMGData: asIMGData(arg.BackImageToken)}
- if err := s.dao.AddOldRealnameIMG(ctx, back); err != nil {
- return err
- }
- apply := &model.DeDeIdentificationCardApply{
- MID: arg.Mid,
- Realname: arg.Realname,
- Type: arg.CardType,
- CardData: string(encryptedCardNum),
- CardForSearch: cardMD5(arg.CardNum, int(arg.CardType), int(arg.Country)),
- FrontImg: front.ID,
- BackImg: back.ID,
- ApplyTime: int32(time.Now().Unix()),
- Operator: arg.Operator,
- OperatorTime: int32(time.Now().Unix()),
- Status: int8(model.RealnameApplyStatePassed.DBStatus()),
- Remark: fmt.Sprintf("管理后台提交:%s", arg.Remark),
- }
- if arg.HandImageToken != "" {
- hand := &model.DeDeIdentificationCardApplyImg{IMGData: asIMGData(arg.HandImageToken)}
- if err := s.dao.AddOldRealnameIMG(ctx, hand); err != nil {
- return err
- }
- apply.FrontImg2 = hand.ID
- }
- if err := s.dao.AddOldRealnameApply(ctx, apply); err != nil {
- return err
- }
- info := &model.DBRealnameInfo{
- MID: apply.MID,
- Channel: model.ChannelMain.DBChannel(),
- Realname: apply.Realname,
- Country: arg.Country,
- CardType: arg.CardType,
- Card: apply.CardData,
- CardMD5: apply.CardForSearch,
- Status: model.RealnameApplyStatePassed.DBStatus(),
- Reason: fmt.Sprintf("管理后台提交:%s", arg.Remark),
- }
- return s.dao.SubmitRealnameInfo(ctx, info)
- }
- if err := toOld(); err != nil {
- return err
- }
- report.Manager(&report.ManagerInfo{
- Uname: arg.Operator,
- UID: arg.OperatorID,
- Business: model.RealnameManagerLogID,
- Type: 0,
- Oid: arg.Mid,
- Action: model.LogActionRealnameSubmit,
- Ctime: time.Now(),
- })
- return nil
- }
- // RealnameFileUpload is
- func (s *Service) RealnameFileUpload(ctx context.Context, mid int64, data []byte) (src string, err error) {
- var (
- md5Engine = md5.New()
- hashMID string
- hashRand string
- fileName string
- dirPath string
- dateStr string
- )
- md5Engine.Write([]byte(strconv.FormatInt(mid, 10)))
- hashMID = hex.EncodeToString(md5Engine.Sum(nil))
- md5Engine.Reset()
- md5Engine.Write([]byte(strconv.FormatInt(time.Now().Unix(), 10)))
- md5Engine.Write([]byte(strconv.FormatInt(mrand.Int63n(1000000), 10)))
- hashRand = hex.EncodeToString(md5Engine.Sum(nil))
- fileName = fmt.Sprintf("%s_%s.txt", hashMID[:6], hashRand)
- dateStr = time.Now().Format("20060102")
- dirPath = fmt.Sprintf("%s/%s/", s.c.Realname.DataDir, dateStr)
- var (
- dataFile *os.File
- writeFileSize int
- encrptedData []byte
- )
- _, err = os.Stat(dirPath)
- if os.IsNotExist(err) {
- mask := syscall.Umask(0)
- defer syscall.Umask(mask)
- if err = os.MkdirAll(dirPath, 0777); err != nil {
- err = errors.WithStack(err)
- return
- }
- }
- if encrptedData, err = s.mainCryptor.IMGEncrypt(data); err != nil {
- err = errors.WithStack(err)
- return
- }
- if dataFile, err = os.Create(dirPath + fileName); err != nil {
- err = errors.Wrapf(err, "create file %s failed", dirPath+fileName)
- return
- }
- defer dataFile.Close()
- if writeFileSize, err = dataFile.Write(encrptedData); err != nil {
- err = errors.Wrapf(err, "write file %s size %d failed", dirPath+fileName, len(encrptedData))
- return
- }
- if writeFileSize != len(encrptedData) {
- err = errors.Errorf("Write file data to %s , expected %d actual %d", dirPath+fileName, len(encrptedData), writeFileSize)
- return
- }
- src = fmt.Sprintf("%s/%s", dateStr, strings.TrimSuffix(fileName, ".txt"))
- return
- }
- func asIMGData(imgToken string) string {
- return model.RealnameImgPrefix + imgToken + model.RealnameImgSuffix
- }
- func asIMGToken(IMGData string) string {
- token := strings.TrimPrefix(IMGData, "/idenfiles/")
- token = strings.TrimSuffix(token, ".txt")
- return token
- }
- // StripImage is
- func StripImage(raw []byte) ([]byte, error) {
- i, format, err := image.Decode(bytes.NewReader(raw))
- if err != nil {
- return nil, errors.WithStack(err)
- }
- out := &bytes.Buffer{}
- switch format {
- case "jpg", "jpeg":
- if err := jpeg.Encode(out, i, &jpeg.Options{Quality: jpeg.DefaultQuality}); err != nil {
- return nil, errors.WithStack(err)
- }
- default:
- return nil, errors.Errorf("Unsupported type: %s", format)
- }
- return out.Bytes(), nil
- }
|