telecom.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. package telecom
  2. import (
  3. "bytes"
  4. "context"
  5. "crypto/des"
  6. "errors"
  7. "fmt"
  8. "math/rand"
  9. "strconv"
  10. "time"
  11. "go-common/app/interface/main/app-wall/model/telecom"
  12. "go-common/library/ecode"
  13. "go-common/library/log"
  14. "go-common/library/sync/errgroup"
  15. )
  16. const (
  17. _sendSMSCaptcha = `{"captcha":"%v"}`
  18. _sendSMSFlow = `{"flow":"%v"}`
  19. _flowPackageID = 279
  20. )
  21. // InOrdersSync insert OrdersSync
  22. func (s *Service) InOrdersSync(c context.Context, ip string, u *telecom.TelecomOrderJson) (err error) {
  23. if !s.iplimit(_telecomKey, ip) {
  24. err = ecode.AccessDenied
  25. return
  26. }
  27. if u == nil || u.Detail == nil {
  28. err = ecode.NothingFound
  29. return
  30. }
  31. var (
  32. result int64
  33. requestNo int
  34. phoneStr string
  35. detail = u.Detail
  36. )
  37. detail.TelecomJSONChange()
  38. requestNo, _ = strconv.Atoi(u.RequestNo)
  39. if detail.PhoneID == "" {
  40. if phoneStr, err = s.dao.PayPhone(c, int64(requestNo)); err != nil {
  41. log.Error("telecom_s.dao.PayPhone error(%v)", err)
  42. return
  43. }
  44. } else {
  45. phoneStr = detail.PhoneID
  46. }
  47. if result, err = s.dao.InOrderSync(c, requestNo, u.ResultType, phoneStr, detail); err != nil || result == 0 {
  48. log.Error("telecom_s.dao.OrdersSync (%v) error(%v) or result==0", u, err)
  49. return
  50. }
  51. if detail.OrderStatus == 3 {
  52. phoneInt, _ := strconv.Atoi(phoneStr)
  53. if err = s.dao.SendTelecomSMS(c, phoneInt, s.smsOrderTemplateOK); err != nil {
  54. log.Error("telecom_s.dao.SendTelecomSMS error(%v)", err)
  55. return
  56. }
  57. }
  58. return
  59. }
  60. // InRechargeSync insert RechargeSync
  61. func (s *Service) InRechargeSync(c context.Context, ip string, u *telecom.RechargeJSON) (err error) {
  62. if !s.iplimit(_telecomKey, ip) {
  63. err = ecode.AccessDenied
  64. return
  65. }
  66. var result int64
  67. if result, err = s.dao.InRechargeSync(c, u); err != nil || result == 0 {
  68. log.Error("telecom_s.dao.InRechargeSync (%v) error(%v) or result==0", u, err)
  69. return
  70. }
  71. return
  72. }
  73. // telecomMessageOrder
  74. func (s *Service) TelecomMessageSync(c context.Context, ip string, u *telecom.TelecomMessageJSON) (err error) {
  75. if !s.iplimit(_telecomKey, ip) {
  76. err = ecode.AccessDenied
  77. return
  78. }
  79. if u == nil {
  80. err = ecode.ServerErr
  81. return
  82. }
  83. phoneInt, _ := strconv.Atoi(u.PhoneID)
  84. if err = s.dao.SendTelecomSMS(c, phoneInt, s.smsMsgTemplate); err != nil {
  85. log.Error("telecom_s.dao.SendTelecomSMS error(%v)", err)
  86. return
  87. }
  88. return
  89. }
  90. // telecomInfo
  91. func (s *Service) telecomInfo(c context.Context, phone int) (res map[int]*telecom.OrderInfo, err error) {
  92. var (
  93. row *telecom.OrderInfo
  94. )
  95. res = map[int]*telecom.OrderInfo{}
  96. if row, err = s.dao.TelecomCache(c, phone); err == nil && row != nil {
  97. res[phone] = row
  98. s.pHit.Incr("telecom_cache")
  99. return
  100. }
  101. if res, err = s.dao.OrdersUserFlow(c, phone); err != nil {
  102. log.Error("telecom_s.dao.OrdersUserFlow phone (%v) error(%v)", phone, err)
  103. return
  104. }
  105. s.pMiss.Incr("telecom_cache")
  106. if user, ok := res[phone]; ok {
  107. if err = s.dao.AddTelecomCache(c, phone, user); err != nil {
  108. log.Error("telecom_s.dao.AddTelecomCache error(%v)", err)
  109. return
  110. }
  111. }
  112. return
  113. }
  114. // telecomInfoByOrderID
  115. func (s *Service) telecomInfoByOrderID(c context.Context, orderID int64) (res map[int64]*telecom.OrderInfo, err error) {
  116. var (
  117. row *telecom.OrderInfo
  118. )
  119. res = map[int64]*telecom.OrderInfo{}
  120. if row, err = s.dao.TelecomOrderIDCache(c, orderID); err == nil && row != nil {
  121. res[orderID] = row
  122. s.pHit.Incr("telecom_orderid_cache")
  123. return
  124. }
  125. if res, err = s.dao.OrdersUserByOrderID(c, orderID); err != nil {
  126. log.Error("telecom_s.dao.OrdersUserByOrderID phone (%v) error(%v)", orderID, err)
  127. return
  128. }
  129. s.pMiss.Incr("telecom_orderid_cache")
  130. if user, ok := res[orderID]; ok {
  131. if err = s.dao.AddTelecomOrderIDCache(c, orderID, user); err != nil {
  132. log.Error("telecom_s.dao.AddTelecomOrderIDCache error(%v)", err)
  133. return
  134. }
  135. }
  136. return
  137. }
  138. // TelecomPay
  139. func (s *Service) TelecomPay(c context.Context, phone, isRepeatOrder, payChannel, payAction int, orderID int64, ipStr string) (res *telecom.Pay, msg string, err error) {
  140. var (
  141. requestNo int64
  142. t map[int]*telecom.OrderInfo
  143. rcode int
  144. beginTime time.Time
  145. firstOrderEndtime time.Time
  146. )
  147. if requestNo, err = s.seqdao.SeqID(c); err != nil {
  148. log.Error("telecom_s.seqdao.SeqID error (%v)", err)
  149. return
  150. }
  151. if t, err = s.telecomInfo(c, phone); err != nil {
  152. log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
  153. return
  154. }
  155. if user, ok := t[phone]; ok {
  156. beginTime = user.Begintime.Time()
  157. firstOrderEndtime = user.Endtime.Time()
  158. }
  159. if res, err, msg = s.dao.PayInfo(c, requestNo, phone, isRepeatOrder, payChannel, payAction, orderID, ipStr, beginTime, firstOrderEndtime); err != nil || res == nil {
  160. log.Error("telecom_s.dao.PayInfo requestNo (%v) phone (%v) isRepeatOrder (%v) payChannel (%v) payAction (%v) t.OrderID (%v) ipStr (%v) error (%v)",
  161. requestNo, phone, isRepeatOrder, payChannel, payAction, orderID, ipStr, err)
  162. return
  163. }
  164. phoneStr := strconv.Itoa(phone)
  165. if rcode, err = s.dao.AddPayPhone(c, requestNo, phoneStr); err != nil || rcode != 1 {
  166. log.Error("telecom_s.dao.AddPayPhone error (%v)", err)
  167. return
  168. }
  169. return
  170. }
  171. // CancelRepeatOrder
  172. func (s *Service) CancelRepeatOrder(c context.Context, phone int) (msg string, err error) {
  173. var (
  174. res map[int]*telecom.OrderInfo
  175. )
  176. res, err = s.telecomInfo(c, phone)
  177. if err != nil {
  178. log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
  179. return
  180. }
  181. user, ok := res[phone]
  182. if !ok {
  183. err = ecode.NothingFound
  184. msg = "订单不存在"
  185. return
  186. }
  187. if msg, err = s.dao.CancelRepeatOrder(c, phone, user.SignNo); err != nil {
  188. log.Error("telecom_s.dao.CancelRepeatOrder phone(%v) signNo(%v) error (%v)", phone, user.SignNo, err)
  189. return
  190. }
  191. return
  192. }
  193. // OrderList user order list
  194. func (s *Service) OrderList(c context.Context, orderID int64, phone int) (res *telecom.SucOrder, msg string, err error) {
  195. if res, err, msg = s.dao.SucOrderList(c, phone); err != nil || res == nil {
  196. log.Error("telecom_s.dao.SucOrderList orderID (%v) phone (%v) error (%v)", orderID, phone, err)
  197. return
  198. }
  199. return
  200. }
  201. // PhoneFlow user flow
  202. func (s *Service) PhoneFlow(c context.Context, orderID int64, phone int) (res *telecom.OrderFlow, msg string, err error) {
  203. var t *telecom.SucOrder
  204. if t, err, msg = s.dao.SucOrderList(c, phone); err != nil || t == nil {
  205. log.Error("telecom_s.dao.SucOrderList orderID (%v) phone (%v) error (%v)", orderID, phone, err)
  206. return
  207. }
  208. res = &telecom.OrderFlow{
  209. FlowBalance: t.FlowBalance,
  210. }
  211. if (t.FlowBalance/t.FlowPackageSize)*100 < s.flowPercentage {
  212. flow := strconv.Itoa(t.FlowBalance)
  213. dataJSON := fmt.Sprintf(_sendSMSFlow, flow)
  214. if err = s.dao.SendSMS(c, phone, s.smsFlowTemplate, dataJSON); err != nil {
  215. log.Error("telecom_s.dao.SendSMS phone(%v) error (%v)", phone, err)
  216. return
  217. }
  218. msg = "免流量量剩余不不⾜足10%,超出部分会按正常流量量资费计费"
  219. return
  220. }
  221. return
  222. }
  223. // OrderConsent user orderConsent
  224. func (s *Service) OrderConsent(c context.Context, phone int, orderID int64, captcha string) (res *telecom.PhoneConsent, msg string, err error) {
  225. var (
  226. area string
  227. t *telecom.SucOrder
  228. captchaStr string
  229. order *telecom.OrderPhoneState
  230. )
  231. captchaStr, err = s.dao.PhoneCode(c, phone)
  232. if err != nil {
  233. log.Error("telecom_s.dao.PhoneCode error (%v)", err)
  234. msg = "验证码已过期"
  235. return
  236. }
  237. if captchaStr == "" || captchaStr != captcha {
  238. err = ecode.NotModified
  239. msg = "验证码错误"
  240. return
  241. }
  242. res = &telecom.PhoneConsent{
  243. Consent: 0,
  244. }
  245. g, ctx := errgroup.WithContext(c)
  246. g.Go(func() error {
  247. if area, err, msg = s.dao.PhoneArea(ctx, phone); err != nil {
  248. log.Error("telecom_s.dao.PhoneArea phone(%v) error (%v)", phone, err)
  249. return err
  250. }
  251. return nil
  252. })
  253. g.Go(func() error {
  254. if t, err, _ = s.dao.SucOrderList(ctx, phone); err != nil {
  255. if err == ecode.NothingFound {
  256. err = nil
  257. } else {
  258. log.Error("telecom_s.dao.SucOrderList sphone (%v) error (%v)", phone, err)
  259. }
  260. return err
  261. }
  262. return nil
  263. })
  264. if orderID > 0 {
  265. g.Go(func() error {
  266. if order, err = s.dao.OrderState(ctx, orderID); err != nil {
  267. log.Error("telecom_s.dao.OrderState phone(%v) orderID(%v) error(%v)", phone, orderID, err)
  268. return err
  269. }
  270. return nil
  271. })
  272. }
  273. if err = g.Wait(); err != nil {
  274. log.Error("telecom_errgroup.WithContext error(%v)", err)
  275. return
  276. }
  277. if len(area) >= 4 {
  278. a := area[:4]
  279. if _, ok := s.telecomArea[a]; !ok {
  280. return
  281. }
  282. }
  283. if order != nil && order.OrderState == 2 && order.FlowPackageID == _flowPackageID {
  284. res.Consent = 3
  285. return
  286. }
  287. if t != nil && t.OrderID > 0 {
  288. res.Consent = 2
  289. return
  290. }
  291. res.Consent = 1
  292. return
  293. }
  294. // PhoneCode
  295. func (s *Service) PhoneCode(c context.Context, phone int, captcha string, now time.Time) (res *telecom.Pay, err error, msg string) {
  296. var (
  297. captchaStr string
  298. order map[int]*telecom.OrderInfo
  299. )
  300. captchaStr, err = s.dao.PhoneCode(c, phone)
  301. if err != nil {
  302. log.Error("telecom_s.dao.PhoneCode error (%v)", err)
  303. msg = "验证码已过期"
  304. return
  305. }
  306. if captchaStr == "" || captchaStr != captcha {
  307. err = ecode.NotModified
  308. msg = "验证码错误"
  309. return
  310. }
  311. if order, err = s.telecomInfo(c, phone); err != nil {
  312. log.Error("telecom_s.telecomInfo phone(%v) error (%v)", phone, err)
  313. return
  314. }
  315. user, ok := order[phone]
  316. if !ok {
  317. err = ecode.NothingFound
  318. msg = "订单不存在"
  319. return
  320. }
  321. switch user.OrderState {
  322. case 2:
  323. err = ecode.NotModified
  324. msg = "订购中"
  325. case 3:
  326. if now.Unix() > int64(user.Endtime) {
  327. err = ecode.NotModified
  328. msg = "订单已过期"
  329. } else {
  330. res = &telecom.Pay{
  331. OrderID: user.OrderID,
  332. }
  333. msg = "激活成功,麻麻再也不不⽤用担⼼心我的流量量了了(/≧▽≦)/"
  334. }
  335. case 4:
  336. err = ecode.NotModified
  337. msg = "订单失败"
  338. case 5:
  339. err = ecode.NotModified
  340. msg = "订单已过期"
  341. }
  342. return
  343. }
  344. // PhoneSendSMS
  345. func (s *Service) PhoneSendSMS(c context.Context, phone int) (err error) {
  346. var (
  347. captcha string
  348. rcode int
  349. )
  350. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  351. for i := 0; i < 6; i++ {
  352. captcha = captcha + strconv.Itoa(r.Intn(10))
  353. }
  354. dataJSON := fmt.Sprintf(_sendSMSCaptcha, captcha)
  355. if err = s.dao.SendSMS(c, phone, s.smsTemplate, dataJSON); err != nil {
  356. log.Error("telecom_s.dao.SendSMS error (%v)", err)
  357. return
  358. }
  359. if rcode, err = s.dao.AddPhoneCode(c, phone, captcha); err != nil || rcode != 1 {
  360. log.Error("telecom_s.dao.AddPhoneCode error (%v)", err)
  361. return
  362. }
  363. return
  364. }
  365. // OrderState
  366. func (s *Service) OrderState(c context.Context, orderid int64) (t *telecom.OrderState, msg string, err error) {
  367. var (
  368. orderState *telecom.OrderPhoneState
  369. torder map[int64]*telecom.OrderInfo
  370. userOrder *telecom.OrderInfo
  371. tSucOrder *telecom.SucOrder
  372. ok bool
  373. )
  374. g, ctx := errgroup.WithContext(c)
  375. log.Error("userOrder.PhoneID_test")
  376. g.Go(func() error {
  377. if orderState, err = s.dao.OrderState(ctx, orderid); err != nil {
  378. log.Error("telecom_s.dao.OrderState orderID error(%v)", orderid, err)
  379. return err
  380. }
  381. return nil
  382. })
  383. g.Go(func() error {
  384. if torder, err = s.telecomInfoByOrderID(c, orderid); err != nil {
  385. log.Error("telecom_s.telecomInfoByOrderID error(%v)", orderid, err)
  386. return err
  387. }
  388. if userOrder, ok = torder[orderid]; ok {
  389. if tSucOrder, err, _ = s.dao.SucOrderList(ctx, userOrder.PhoneID); err != nil {
  390. if err == ecode.NothingFound {
  391. err = nil
  392. } else {
  393. log.Error("telecom_s.dao.SucOrderList sphone (%v) error (%v)", userOrder.PhoneID, err)
  394. }
  395. return err
  396. }
  397. }
  398. return nil
  399. })
  400. if err = g.Wait(); err != nil {
  401. log.Error("telecom_errgroup.WithContext error(%v)", err)
  402. return
  403. }
  404. if orderState == nil {
  405. t = &telecom.OrderState{
  406. OrderState: 1,
  407. }
  408. return
  409. }
  410. t = &telecom.OrderState{
  411. OrderState: orderState.OrderState,
  412. FlowSize: orderState.FlowSize,
  413. }
  414. if tSucOrder != nil && tSucOrder.OrderID > 0 {
  415. t.FlowBalance = tSucOrder.FlowBalance
  416. t.FlowSize = tSucOrder.FlowPackageSize
  417. }
  418. if ok {
  419. t.IsRepeatorder = userOrder.IsRepeatorder
  420. if userOrder.IsRepeatorder == 0 {
  421. t.Endtime = userOrder.Endtime
  422. }
  423. }
  424. switch t.OrderState {
  425. case 6:
  426. if !ok {
  427. err = ecode.NothingFound
  428. msg = "订单不存在"
  429. return
  430. }
  431. t.Endtime = userOrder.Endtime
  432. }
  433. return
  434. }
  435. // telecomIp ip limit
  436. func (s *Service) iplimit(k, ip string) bool {
  437. key := fmt.Sprintf(_initIPlimitKey, k, ip)
  438. if _, ok := s.operationIPlimit[key]; ok {
  439. return true
  440. }
  441. return false
  442. }
  443. // DesDecrypt
  444. func (s *Service) DesDecrypt(src, key []byte) ([]byte, error) {
  445. block, err := des.NewCipher(key)
  446. if err != nil {
  447. return nil, err
  448. }
  449. out := make([]byte, len(src))
  450. dst := out
  451. bs := block.BlockSize()
  452. if len(src)%bs != 0 {
  453. return nil, errors.New("crypto/cipher: input not full blocks")
  454. }
  455. for len(src) > 0 {
  456. block.Decrypt(dst, src[:bs])
  457. src = src[bs:]
  458. dst = dst[bs:]
  459. }
  460. out = s.zeroUnPadding(out)
  461. return out, nil
  462. }
  463. // zeroUnPadding
  464. func (s *Service) zeroUnPadding(origData []byte) []byte {
  465. return bytes.TrimFunc(origData,
  466. func(r rune) bool {
  467. return r == rune(0)
  468. })
  469. }