123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 |
- package telecom
- import (
- "bytes"
- "context"
- "crypto/des"
- "errors"
- "fmt"
- "math/rand"
- "strconv"
- "time"
- "go-common/app/interface/main/app-wall/model/telecom"
- "go-common/library/ecode"
- "go-common/library/log"
- "go-common/library/sync/errgroup"
- )
- const (
- _sendSMSCaptcha = `{"captcha":"%v"}`
- _sendSMSFlow = `{"flow":"%v"}`
- _flowPackageID = 279
- )
- // InOrdersSync insert OrdersSync
- func (s *Service) InOrdersSync(c context.Context, ip string, u *telecom.TelecomOrderJson) (err error) {
- if !s.iplimit(_telecomKey, ip) {
- err = ecode.AccessDenied
- return
- }
- if u == nil || u.Detail == nil {
- err = ecode.NothingFound
- return
- }
- var (
- result int64
- requestNo int
- phoneStr string
- detail = u.Detail
- )
- detail.TelecomJSONChange()
- requestNo, _ = strconv.Atoi(u.RequestNo)
- if detail.PhoneID == "" {
- if phoneStr, err = s.dao.PayPhone(c, int64(requestNo)); err != nil {
- log.Error("telecom_s.dao.PayPhone error(%v)", err)
- return
- }
- } else {
- phoneStr = detail.PhoneID
- }
- if result, err = s.dao.InOrderSync(c, requestNo, u.ResultType, phoneStr, detail); err != nil || result == 0 {
- log.Error("telecom_s.dao.OrdersSync (%v) error(%v) or result==0", u, err)
- return
- }
- if detail.OrderStatus == 3 {
- phoneInt, _ := strconv.Atoi(phoneStr)
- if err = s.dao.SendTelecomSMS(c, phoneInt, s.smsOrderTemplateOK); err != nil {
- log.Error("telecom_s.dao.SendTelecomSMS error(%v)", err)
- return
- }
- }
- return
- }
- // InRechargeSync insert RechargeSync
- func (s *Service) InRechargeSync(c context.Context, ip string, u *telecom.RechargeJSON) (err error) {
- if !s.iplimit(_telecomKey, ip) {
- err = ecode.AccessDenied
- return
- }
- var result int64
- if result, err = s.dao.InRechargeSync(c, u); err != nil || result == 0 {
- log.Error("telecom_s.dao.InRechargeSync (%v) error(%v) or result==0", u, err)
- return
- }
- return
- }
- // telecomMessageOrder
- func (s *Service) TelecomMessageSync(c context.Context, ip string, u *telecom.TelecomMessageJSON) (err error) {
- if !s.iplimit(_telecomKey, ip) {
- err = ecode.AccessDenied
- return
- }
- if u == nil {
- err = ecode.ServerErr
- return
- }
- phoneInt, _ := strconv.Atoi(u.PhoneID)
- if err = s.dao.SendTelecomSMS(c, phoneInt, s.smsMsgTemplate); err != nil {
- log.Error("telecom_s.dao.SendTelecomSMS error(%v)", err)
- return
- }
- return
- }
- // telecomInfo
- func (s *Service) telecomInfo(c context.Context, phone int) (res map[int]*telecom.OrderInfo, err error) {
- var (
- row *telecom.OrderInfo
- )
- res = map[int]*telecom.OrderInfo{}
- if row, err = s.dao.TelecomCache(c, phone); err == nil && row != nil {
- res[phone] = row
- s.pHit.Incr("telecom_cache")
- return
- }
- if res, err = s.dao.OrdersUserFlow(c, phone); err != nil {
- log.Error("telecom_s.dao.OrdersUserFlow phone (%v) error(%v)", phone, err)
- return
- }
- s.pMiss.Incr("telecom_cache")
- if user, ok := res[phone]; ok {
- if err = s.dao.AddTelecomCache(c, phone, user); err != nil {
- log.Error("telecom_s.dao.AddTelecomCache error(%v)", err)
- return
- }
- }
- return
- }
- // telecomInfoByOrderID
- func (s *Service) telecomInfoByOrderID(c context.Context, orderID int64) (res map[int64]*telecom.OrderInfo, err error) {
- var (
- row *telecom.OrderInfo
- )
- res = map[int64]*telecom.OrderInfo{}
- if row, err = s.dao.TelecomOrderIDCache(c, orderID); err == nil && row != nil {
- res[orderID] = row
- s.pHit.Incr("telecom_orderid_cache")
- return
- }
- if res, err = s.dao.OrdersUserByOrderID(c, orderID); err != nil {
- log.Error("telecom_s.dao.OrdersUserByOrderID phone (%v) error(%v)", orderID, err)
- return
- }
- s.pMiss.Incr("telecom_orderid_cache")
- if user, ok := res[orderID]; ok {
- if err = s.dao.AddTelecomOrderIDCache(c, orderID, user); err != nil {
- log.Error("telecom_s.dao.AddTelecomOrderIDCache error(%v)", err)
- return
- }
- }
- return
- }
- // TelecomPay
- func (s *Service) TelecomPay(c context.Context, phone, isRepeatOrder, payChannel, payAction int, orderID int64, ipStr string) (res *telecom.Pay, msg string, err error) {
- var (
- requestNo int64
- t map[int]*telecom.OrderInfo
- rcode int
- beginTime time.Time
- firstOrderEndtime time.Time
- )
- if requestNo, err = s.seqdao.SeqID(c); err != nil {
- log.Error("telecom_s.seqdao.SeqID error (%v)", err)
- return
- }
- if t, err = s.telecomInfo(c, phone); err != nil {
- log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
- return
- }
- if user, ok := t[phone]; ok {
- beginTime = user.Begintime.Time()
- firstOrderEndtime = user.Endtime.Time()
- }
- if res, err, msg = s.dao.PayInfo(c, requestNo, phone, isRepeatOrder, payChannel, payAction, orderID, ipStr, beginTime, firstOrderEndtime); err != nil || res == nil {
- log.Error("telecom_s.dao.PayInfo requestNo (%v) phone (%v) isRepeatOrder (%v) payChannel (%v) payAction (%v) t.OrderID (%v) ipStr (%v) error (%v)",
- requestNo, phone, isRepeatOrder, payChannel, payAction, orderID, ipStr, err)
- return
- }
- phoneStr := strconv.Itoa(phone)
- if rcode, err = s.dao.AddPayPhone(c, requestNo, phoneStr); err != nil || rcode != 1 {
- log.Error("telecom_s.dao.AddPayPhone error (%v)", err)
- return
- }
- return
- }
- // CancelRepeatOrder
- func (s *Service) CancelRepeatOrder(c context.Context, phone int) (msg string, err error) {
- var (
- res map[int]*telecom.OrderInfo
- )
- res, err = s.telecomInfo(c, phone)
- if err != nil {
- log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
- return
- }
- user, ok := res[phone]
- if !ok {
- err = ecode.NothingFound
- msg = "订单不存在"
- return
- }
- if msg, err = s.dao.CancelRepeatOrder(c, phone, user.SignNo); err != nil {
- log.Error("telecom_s.dao.CancelRepeatOrder phone(%v) signNo(%v) error (%v)", phone, user.SignNo, err)
- return
- }
- return
- }
- // OrderList user order list
- func (s *Service) OrderList(c context.Context, orderID int64, phone int) (res *telecom.SucOrder, msg string, err error) {
- if res, err, msg = s.dao.SucOrderList(c, phone); err != nil || res == nil {
- log.Error("telecom_s.dao.SucOrderList orderID (%v) phone (%v) error (%v)", orderID, phone, err)
- return
- }
- return
- }
- // PhoneFlow user flow
- func (s *Service) PhoneFlow(c context.Context, orderID int64, phone int) (res *telecom.OrderFlow, msg string, err error) {
- var t *telecom.SucOrder
- if t, err, msg = s.dao.SucOrderList(c, phone); err != nil || t == nil {
- log.Error("telecom_s.dao.SucOrderList orderID (%v) phone (%v) error (%v)", orderID, phone, err)
- return
- }
- res = &telecom.OrderFlow{
- FlowBalance: t.FlowBalance,
- }
- if (t.FlowBalance/t.FlowPackageSize)*100 < s.flowPercentage {
- flow := strconv.Itoa(t.FlowBalance)
- dataJSON := fmt.Sprintf(_sendSMSFlow, flow)
- if err = s.dao.SendSMS(c, phone, s.smsFlowTemplate, dataJSON); err != nil {
- log.Error("telecom_s.dao.SendSMS phone(%v) error (%v)", phone, err)
- return
- }
- msg = "免流量量剩余不不⾜足10%,超出部分会按正常流量量资费计费"
- return
- }
- return
- }
- // OrderConsent user orderConsent
- func (s *Service) OrderConsent(c context.Context, phone int, orderID int64, captcha string) (res *telecom.PhoneConsent, msg string, err error) {
- var (
- area string
- t *telecom.SucOrder
- captchaStr string
- order *telecom.OrderPhoneState
- )
- captchaStr, err = s.dao.PhoneCode(c, phone)
- if err != nil {
- log.Error("telecom_s.dao.PhoneCode error (%v)", err)
- msg = "验证码已过期"
- return
- }
- if captchaStr == "" || captchaStr != captcha {
- err = ecode.NotModified
- msg = "验证码错误"
- return
- }
- res = &telecom.PhoneConsent{
- Consent: 0,
- }
- g, ctx := errgroup.WithContext(c)
- g.Go(func() error {
- if area, err, msg = s.dao.PhoneArea(ctx, phone); err != nil {
- log.Error("telecom_s.dao.PhoneArea phone(%v) error (%v)", phone, err)
- return err
- }
- return nil
- })
- g.Go(func() error {
- if t, err, _ = s.dao.SucOrderList(ctx, phone); err != nil {
- if err == ecode.NothingFound {
- err = nil
- } else {
- log.Error("telecom_s.dao.SucOrderList sphone (%v) error (%v)", phone, err)
- }
- return err
- }
- return nil
- })
- if orderID > 0 {
- g.Go(func() error {
- if order, err = s.dao.OrderState(ctx, orderID); err != nil {
- log.Error("telecom_s.dao.OrderState phone(%v) orderID(%v) error(%v)", phone, orderID, err)
- return err
- }
- return nil
- })
- }
- if err = g.Wait(); err != nil {
- log.Error("telecom_errgroup.WithContext error(%v)", err)
- return
- }
- if len(area) >= 4 {
- a := area[:4]
- if _, ok := s.telecomArea[a]; !ok {
- return
- }
- }
- if order != nil && order.OrderState == 2 && order.FlowPackageID == _flowPackageID {
- res.Consent = 3
- return
- }
- if t != nil && t.OrderID > 0 {
- res.Consent = 2
- return
- }
- res.Consent = 1
- return
- }
- // PhoneCode
- func (s *Service) PhoneCode(c context.Context, phone int, captcha string, now time.Time) (res *telecom.Pay, err error, msg string) {
- var (
- captchaStr string
- order map[int]*telecom.OrderInfo
- )
- captchaStr, err = s.dao.PhoneCode(c, phone)
- if err != nil {
- log.Error("telecom_s.dao.PhoneCode error (%v)", err)
- msg = "验证码已过期"
- return
- }
- if captchaStr == "" || captchaStr != captcha {
- err = ecode.NotModified
- msg = "验证码错误"
- return
- }
- if order, err = s.telecomInfo(c, phone); err != nil {
- log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
- return
- }
- user, ok := order[phone]
- if !ok {
- err = ecode.NothingFound
- msg = "订单不存在"
- return
- }
- switch user.OrderState {
- case 2:
- err = ecode.NotModified
- msg = "订购中"
- case 3:
- if now.Unix() > int64(user.Endtime) {
- err = ecode.NotModified
- msg = "订单已过期"
- } else {
- res = &telecom.Pay{
- OrderID: user.OrderID,
- }
- msg = "激活成功,麻麻再也不不⽤用担⼼心我的流量量了了(/≧▽≦)/"
- }
- case 4:
- err = ecode.NotModified
- msg = "订单失败"
- case 5:
- err = ecode.NotModified
- msg = "订单已过期"
- }
- return
- }
- // PhoneSendSMS
- func (s *Service) PhoneSendSMS(c context.Context, phone int) (err error) {
- var (
- captcha string
- rcode int
- )
- r := rand.New(rand.NewSource(time.Now().UnixNano()))
- for i := 0; i < 6; i++ {
- captcha = captcha + strconv.Itoa(r.Intn(10))
- }
- dataJSON := fmt.Sprintf(_sendSMSCaptcha, captcha)
- if err = s.dao.SendSMS(c, phone, s.smsTemplate, dataJSON); err != nil {
- log.Error("telecom_s.dao.SendSMS error (%v)", err)
- return
- }
- if rcode, err = s.dao.AddPhoneCode(c, phone, captcha); err != nil || rcode != 1 {
- log.Error("telecom_s.dao.AddPhoneCode error (%v)", err)
- return
- }
- return
- }
- // OrderState
- func (s *Service) OrderState(c context.Context, orderid int64) (t *telecom.OrderState, msg string, err error) {
- var (
- orderState *telecom.OrderPhoneState
- torder map[int64]*telecom.OrderInfo
- userOrder *telecom.OrderInfo
- tSucOrder *telecom.SucOrder
- ok bool
- )
- g, ctx := errgroup.WithContext(c)
- log.Error("userOrder.PhoneID_test")
- g.Go(func() error {
- if orderState, err = s.dao.OrderState(ctx, orderid); err != nil {
- log.Error("telecom_s.dao.OrderState orderID error(%v)", orderid, err)
- return err
- }
- return nil
- })
- g.Go(func() error {
- if torder, err = s.telecomInfoByOrderID(c, orderid); err != nil {
- log.Error("telecom_s.telecomInfoByOrderID error(%v)", orderid, err)
- return err
- }
- if userOrder, ok = torder[orderid]; ok {
- if tSucOrder, err, _ = s.dao.SucOrderList(ctx, userOrder.PhoneID); err != nil {
- if err == ecode.NothingFound {
- err = nil
- } else {
- log.Error("telecom_s.dao.SucOrderList sphone (%v) error (%v)", userOrder.PhoneID, err)
- }
- return err
- }
- }
- return nil
- })
- if err = g.Wait(); err != nil {
- log.Error("telecom_errgroup.WithContext error(%v)", err)
- return
- }
- if orderState == nil {
- t = &telecom.OrderState{
- OrderState: 1,
- }
- return
- }
- t = &telecom.OrderState{
- OrderState: orderState.OrderState,
- FlowSize: orderState.FlowSize,
- }
- if tSucOrder != nil && tSucOrder.OrderID > 0 {
- t.FlowBalance = tSucOrder.FlowBalance
- t.FlowSize = tSucOrder.FlowPackageSize
- }
- if ok {
- t.IsRepeatorder = userOrder.IsRepeatorder
- if userOrder.IsRepeatorder == 0 {
- t.Endtime = userOrder.Endtime
- }
- }
- switch t.OrderState {
- case 6:
- if !ok {
- err = ecode.NothingFound
- msg = "订单不存在"
- return
- }
- t.Endtime = userOrder.Endtime
- }
- return
- }
- // telecomIp ip limit
- func (s *Service) iplimit(k, ip string) bool {
- key := fmt.Sprintf(_initIPlimitKey, k, ip)
- if _, ok := s.operationIPlimit[key]; ok {
- return true
- }
- return false
- }
- // DesDecrypt
- func (s *Service) DesDecrypt(src, key []byte) ([]byte, error) {
- block, err := des.NewCipher(key)
- if err != nil {
- return nil, err
- }
- out := make([]byte, len(src))
- dst := out
- bs := block.BlockSize()
- if len(src)%bs != 0 {
- return nil, errors.New("crypto/cipher: input not full blocks")
- }
- for len(src) > 0 {
- block.Decrypt(dst, src[:bs])
- src = src[bs:]
- dst = dst[bs:]
- }
- out = s.zeroUnPadding(out)
- return out, nil
- }
- // zeroUnPadding
- func (s *Service) zeroUnPadding(origData []byte) []byte {
- return bytes.TrimFunc(origData,
- func(r rune) bool {
- return r == rune(0)
- })
- }
|