user_merchant_base_api_quota.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. package user_merchant
  2. import (
  3. "context"
  4. "gd_management/apis"
  5. "gd_management/errors"
  6. "gd_management/impl/order"
  7. "gd_management/impl/pubsub"
  8. "encoding/json"
  9. "fmt"
  10. "time"
  11. "gd_management/common.in/id"
  12. "gd_management/common.in/jsonrpc2"
  13. "gd_management/common.in/storage"
  14. "gd_management/common.in/utils"
  15. "github.com/astaxie/beego/orm"
  16. "go.uber.org/zap"
  17. )
  18. func ManagementSetMerchantDataApiQuota(ctx context.Context, req *apis.ManagementSetMerchantDataApiQuotaReq, reply *apis.ManagementSetMerchantDataApiQuotaReply) (err error) {
  19. task := func(o orm.Ormer) error {
  20. now := time.Now()
  21. nowString := now.Format("2006-01-02 15:04:05")
  22. nowSecond := now.Unix()
  23. mdaTab := apis.TGdMerchantDataApi{}
  24. if err := pubsub.PublishMerchantApiNotify(req.MerchantDataApiId, 0, 0, 0); err != nil {
  25. return err
  26. }
  27. err := o.QueryTable("t_gd_merchant_data_api").Filter("id", req.MerchantDataApiId).One(&mdaTab)
  28. if err != nil {
  29. if err == orm.ErrNoRows {
  30. return errors.DataBaseNoRecord
  31. }
  32. return errors.DataBaseError
  33. }
  34. //按次数
  35. state := 0
  36. if mdaTab.ComboType == 0 {
  37. if mdaTab.EndTime == 0 {
  38. mdaTab.ComboType = 1
  39. } else {
  40. mdaTab.ComboType = 2
  41. }
  42. }
  43. if mdaTab.ComboType == 1 {
  44. if req.Count < 0 {
  45. return errors.ArgsError
  46. }
  47. if req.Count == 0 {
  48. state = 1
  49. }
  50. sql := "update t_gd_merchant_data_api set count=?, state=?, update_time=? where id=?"
  51. _, err := o.Raw(sql, req.Count, state, nowString, req.MerchantDataApiId).Exec()
  52. if err != nil {
  53. l.Error("mysql",
  54. zap.String("sql", sql),
  55. zap.String("fields", fmt.Sprintf("id:%d", req.MerchantDataApiId)),
  56. zap.String("error", err.Error()))
  57. return errors.DataBaseError
  58. }
  59. return nil
  60. }
  61. if mdaTab.ComboType == 2 {
  62. if req.DayNumber < 0 || req.DayCount < 0 {
  63. return errors.ArgsError
  64. }
  65. if req.DayNumber == 0 {
  66. state = 1
  67. }
  68. var start_time int64
  69. var end_time int64
  70. err = o.Raw("select start_time,end_time from t_gd_merchant_data_api where id = ?", req.MerchantDataApiId).QueryRow(&start_time, &end_time)
  71. if err != nil {
  72. l.Error("mysql",
  73. zap.String("sql", "select start_time from t_gd_merchant_data_api where id = ?"),
  74. zap.String("fields", fmt.Sprintf("id:%d", req.MerchantDataApiId)),
  75. zap.String("error", err.Error()))
  76. return errors.DataBaseError
  77. }
  78. if end_time < nowSecond {
  79. start_time = nowSecond
  80. end_time = start_time + int64(req.DayNumber*24*3600)
  81. } else {
  82. end_time = nowSecond + int64(req.DayNumber*24*3600) - (nowSecond-start_time)%(3600*24)
  83. }
  84. sql := "update t_gd_merchant_data_api set count_per_day=?, state=?, start_time=?, end_time=?, update_time=? where id=?"
  85. _, err = o.Raw(sql, req.DayCount, state, start_time, end_time, nowString, req.MerchantDataApiId).Exec()
  86. if err != nil {
  87. l.Error("mysql",
  88. zap.String("sql", sql),
  89. zap.String("fields", fmt.Sprintf("id:%d", req.MerchantDataApiId)),
  90. zap.String("error", err.Error()))
  91. return errors.DataBaseError
  92. }
  93. }
  94. return nil
  95. }
  96. tasks := []storage.DbaTasker{}
  97. tasks = append(tasks, storage.GenerateDbaTask(task))
  98. storage.ExecTrans(tasks...)
  99. l.Debug(utils.MarshalJsonString(req, reply))
  100. return nil
  101. }
  102. func GetMerchantDataApiQuota(ctx context.Context, req *apis.GetMerchantDataApiQuotaReq, reply *apis.GetMerchantDataApiQuotaReply) error {
  103. if req.Id <= 0 {
  104. return errors.ArgsError
  105. }
  106. p := apis.TGdMerchantDataApi{}
  107. sql := "SELECT * FROM t_gd_merchant_data_api WHERE id = ?"
  108. err := orm.NewOrm().Raw(sql, req.Id).QueryRow(&p)
  109. if err != nil {
  110. l.Error("mysql",
  111. zap.String("sql", sql),
  112. zap.String("fields", fmt.Sprintf("id:%d", req.Id)),
  113. zap.String("error", err.Error()))
  114. return errors.DataBaseError
  115. }
  116. reply.MerchantId = p.MerchantId
  117. reply.QueryTypeId = p.QueryTypeId
  118. reply.Count = p.Count
  119. reply.CountPerDay = p.CountPerDay
  120. reply.StartTime = p.StartTime
  121. reply.EndTime = p.EndTime
  122. reply.ComboType = p.ComboType
  123. reply.State = p.State
  124. return nil
  125. }
  126. const (
  127. H5Order = "10"
  128. DataApiOrder = "20"
  129. )
  130. func generateDataApiOrderID(o orm.Ormer) (string, error) {
  131. count := 0
  132. for {
  133. count++
  134. dsId, err := id.GetDistributedUniqueID()
  135. if count > 5 {
  136. return "", errors.ApiOrderGenrateFail
  137. }
  138. if err != nil {
  139. continue
  140. }
  141. orderId := fmt.Sprintf("%s%d", DataApiOrder, dsId)
  142. exist := o.QueryTable("t_gd_data_api_order").Filter("order_no", orderId).Exist()
  143. if exist {
  144. continue
  145. } else {
  146. return orderId, nil
  147. }
  148. }
  149. }
  150. func getUsedCount(o orm.Ormer, merchantDataApiId int64) (int, error) {
  151. ret := 0
  152. sql := fmt.Sprintf("select count from t_gd_api_access_count where merchant_data_api_id=%d and create_time='0000-00-00'", merchantDataApiId)
  153. err := o.Raw(sql).QueryRow(&ret)
  154. if err != nil && err != orm.ErrNoRows {
  155. return 0, errors.DataBaseError
  156. }
  157. return ret, nil
  158. }
  159. func updateThreshold(req *apis.UpdateMerchantDataApiReq, p apis.TGdMerchantDataApi, o orm.Ormer) error {
  160. _, err := o.Raw("update t_gd_merchant_data_api set count_per_day=?, count_thresholds=?, day_thresholds=?, day_total_count=?, ip_whitelist=?, ip_whitelist_enable=?, count_thresholds_enable=?, update_time=? where id=?",
  161. req.TotalComboDayCount, req.CountThresholds, req.DayThresholds, req.DayTotalCount, req.IpWhitelist, req.IpWhitelistEnable, req.CountThresholdsEnable, time.Now().Format("2006-01-02 15:04:05"), req.MerchantDataApiId).Exec()
  162. if err != nil {
  163. return errors.DataBaseError
  164. }
  165. return nil
  166. }
  167. func getTargetComb(o orm.Ormer, comboId int64) (*apis.TGdDataApiCombo, error) {
  168. ret := apis.TGdDataApiCombo{}
  169. err := o.Raw("select * from t_gd_data_api_combo where id=?", comboId).QueryRow(&ret)
  170. if err != nil {
  171. if err != orm.ErrNoRows {
  172. return nil, errors.DataBaseError
  173. }
  174. return nil, errors.DataBaseNoRecord
  175. }
  176. return &ret, nil
  177. }
  178. func changeCombo(o orm.Ormer, req *apis.UpdateMerchantDataApiReq, target *apis.TGdDataApiCombo, p *apis.TGdMerchantDataApi) error {
  179. newOrderId, err := generateDataApiOrderID(o)
  180. if err != nil {
  181. return err
  182. }
  183. newOrder := apis.TGdDataApiOrder{}
  184. newOrder.Status = order.OrderComplete
  185. newOrder.OrderNo = newOrderId
  186. newOrder.ComboId = target.Id
  187. newOrder.BuyAccount = "GD后台管理员"
  188. newOrder.PayType = 1
  189. newOrder.Count = 1
  190. newOrder.MerchantId = p.MerchantId
  191. newOrder.QueryTypeId = p.QueryTypeId
  192. newOrder.GoodsPrice = target.Price
  193. newOrder.CreateTime = time.Now().Format("2006-01-02 15:04:05")
  194. if target.Type == 1 {
  195. if target.Count+req.Count < 0 {
  196. return errors.ArgsError
  197. }
  198. sql := fmt.Sprintf("update t_gd_merchant_data_api set combo_type=1, state=0, count_after_increase=0, used_before_increase=0, count_per_day=0, start_time=0, end_time=0, count=%d where id=%d", target.Count+req.Count, req.MerchantDataApiId)
  199. _, err := o.Raw(sql).Exec()
  200. if err != nil {
  201. return errors.DataBaseError
  202. }
  203. days := int((p.EndTime - p.StartTime) / (24 * 3600))
  204. newOrder.ComboDesc = fmt.Sprintf("%d次每天/%d天-%d次", p.CountPerDay, days, target.Count+req.Count)
  205. } else if target.Type == 2 {
  206. now := time.Now()
  207. if target.Count+req.DayCount < 0 ||
  208. target.TotalDay+req.DayNumber < 0 {
  209. return errors.ArgsError
  210. }
  211. start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix()
  212. end := start + int64((target.TotalDay+req.DayNumber)*24*3600)
  213. sql := fmt.Sprintf("update t_gd_merchant_data_api set combo_type=2, state = 0, count_after_increase=0, used_before_increase=0, count_per_day=%d, start_time=%d, end_time=%d, count=0 where id=%d", target.Count+req.DayCount, start, end, req.MerchantDataApiId)
  214. _, err := o.Raw(sql).Exec()
  215. if err != nil {
  216. return errors.DataBaseError
  217. }
  218. newOrder.ComboDesc = fmt.Sprintf("%d次-%d次每天/%d天", p.Count, target.Count+req.DayCount, target.TotalDay+req.DayNumber)
  219. } else {
  220. return errors.FreeQueryTypeCanNotSetQuota
  221. }
  222. _, err = o.Raw("delete from t_gd_api_access_count where merchant_data_api_id=?", req.MerchantDataApiId).Exec()
  223. if err != nil {
  224. return errors.DataBaseError
  225. }
  226. _, err = o.Insert(&newOrder)
  227. if err != nil {
  228. return errors.DataBaseError
  229. }
  230. return nil
  231. }
  232. // Update 修改商户数据API
  233. func Update(ctx context.Context, req *apis.UpdateMerchantDataApiReq, reply *apis.UpdateMerchantDataApiReply) (err error) {
  234. // 捕获各个task中的异常并返回给调用者
  235. defer func() {
  236. if r := recover(); r != nil {
  237. err = fmt.Errorf("%+v", r)
  238. e := &jsonrpc2.Error{}
  239. if er := json.Unmarshal([]byte(err.Error()), e); er != nil {
  240. l.Error("err",
  241. zap.String("system_err", err.Error()),
  242. zap.Stack("stacktrace"))
  243. }
  244. }
  245. }()
  246. // 参数检查
  247. if req.MerchantDataApiId <= 0 {
  248. l.Error("argument",
  249. zap.String("call", "check"),
  250. zap.String("fields", utils.MarshalJsonString(req)))
  251. return errors.ArgsError
  252. }
  253. var (
  254. p = apis.TGdMerchantDataApi{}
  255. )
  256. // 发布redis订阅
  257. redisPublishTask := func(db orm.Ormer) error {
  258. if err := pubsub.PublishMerchantApiNotify(req.MerchantDataApiId, 0, 0, 0); err != nil {
  259. return err
  260. }
  261. if err := pubsub.PublishApiExportInfoNotify(); err != nil {
  262. return err
  263. }
  264. return nil
  265. }
  266. // 查询数据api类型
  267. getDataApiInfoTask := func(db orm.Ormer) error {
  268. err := db.Raw("SELECT * FROM t_gd_merchant_data_api where id = ?", req.MerchantDataApiId).QueryRow(&p)
  269. if err != nil {
  270. l.Error("mysql",
  271. zap.String("sql", "SELECT * FROM t_gd_merchant_data_api where id = ?"),
  272. zap.String("fields", utils.MarshalJsonString(req.MerchantDataApiId)),
  273. zap.String("error", err.Error()))
  274. if err == orm.ErrNoRows {
  275. return errors.DataBaseNoRecord
  276. }
  277. return errors.DataBaseError
  278. }
  279. var is_free int
  280. db.Raw("select is_free from t_gd_data_api_query_type where id = ?", p.QueryTypeId).QueryRow(&is_free)
  281. if is_free == 1 {
  282. return errors.FreeQueryTypeCanNotSetQuota
  283. }
  284. return nil
  285. }
  286. // 更新数据api配额
  287. updateDataApiTask := func(db orm.Ormer) error {
  288. if err := updateThreshold(req, p, db); err != nil {
  289. return err
  290. }
  291. if p.ComboType == 0 {
  292. if p.EndTime == 0 {
  293. p.ComboType = 1
  294. } else {
  295. p.ComboType = 2
  296. }
  297. }
  298. targetCombo, err := getTargetComb(db, req.ComboId)
  299. if err != nil {
  300. return err
  301. }
  302. if targetCombo.Type != p.ComboType {
  303. return changeCombo(db, req, targetCombo, &p)
  304. }
  305. used, err := getUsedCount(db, req.MerchantDataApiId)
  306. if err != nil {
  307. return err
  308. }
  309. if p.ComboType == 1 {
  310. // 按次数
  311. if req.Count == 0 {
  312. return nil
  313. }
  314. if p.Count+req.Count < 0 {
  315. return errors.ArgsError
  316. }
  317. state := 0
  318. if p.Count+req.Count == 0 {
  319. state = 1
  320. }
  321. dataOrder := apis.TGdDataApiOrder{}
  322. dataOrder.Status = order.OrderComplete
  323. dataOrder.BuyAccount = "GD后台管理员"
  324. dataOrder.PayType = 1
  325. dataOrder.Count = 1
  326. dataOrder.MerchantId = p.MerchantId
  327. dataOrder.QueryTypeId = p.QueryTypeId
  328. dataOrder.CreateTime = time.Now().Format("2006-01-02 15:04:05")
  329. orderId, err := generateDataApiOrderID(db)
  330. if err != nil {
  331. return errors.ApiOrderGenrateFail
  332. }
  333. dataOrder.OrderNo = orderId
  334. if err != nil {
  335. return errors.DataBaseError
  336. }
  337. countAfterIncrease := 0
  338. usedBeforeIncrease := 0
  339. countAfterIncrease = req.Count + p.Count - used
  340. usedBeforeIncrease = used
  341. if countAfterIncrease < 0 {
  342. countAfterIncrease = 0
  343. usedBeforeIncrease = 0
  344. }
  345. if req.Count > 0 {
  346. dataOrder.ComboDesc = fmt.Sprintf("+%d次", req.Count)
  347. } else {
  348. dataOrder.ComboDesc = fmt.Sprintf("%d次", req.Count)
  349. }
  350. _, err = db.Insert(&dataOrder)
  351. sql := fmt.Sprintf("UPDATE t_gd_merchant_data_api SET count = %d, update_time = '%s', state = %d WHERE id = %d",
  352. p.Count+req.Count, time.Now().Format("2006-01-02 15:04:05"), state, req.MerchantDataApiId)
  353. if countAfterIncrease > 0 {
  354. sql = fmt.Sprintf("UPDATE t_gd_merchant_data_api SET count = %d, update_time = '%s', state = %d, count_after_increase=%d, used_before_increase=%d WHERE id = %d",
  355. p.Count+req.Count, time.Now().Format("2006-01-02 15:04:05"), state, countAfterIncrease, usedBeforeIncrease, req.MerchantDataApiId)
  356. }
  357. if _, err = db.Raw(sql).Exec(); err != nil {
  358. l.Error("mysql",
  359. zap.String("sql", sql),
  360. zap.String("error", err.Error()))
  361. return errors.DataBaseError
  362. }
  363. } else if p.ComboType == 2 {
  364. // 按时间
  365. if p.CountPerDay+req.DayCount < 0 {
  366. return errors.ArgsError
  367. }
  368. state := 0
  369. if p.CountPerDay+req.DayCount == 0 {
  370. state = 1
  371. }
  372. dataOrder := apis.TGdDataApiOrder{}
  373. dataOrder.Status = order.OrderComplete
  374. dataOrder.BuyAccount = "GD后台管理员"
  375. dataOrder.PayType = 1
  376. dataOrder.Count = 1
  377. dataOrder.MerchantId = p.MerchantId
  378. dataOrder.QueryTypeId = p.QueryTypeId
  379. dataOrder.CreateTime = time.Now().Format("2006-01-02 15:04:05")
  380. orderId, err := generateDataApiOrderID(db)
  381. if err != nil {
  382. return errors.ApiOrderGenrateFail
  383. }
  384. dataOrder.OrderNo = orderId
  385. if req.DayCount != 0 {
  386. if req.DayCount > 0 {
  387. dataOrder.ComboDesc = fmt.Sprintf("+%d次/天", req.DayCount)
  388. } else {
  389. dataOrder.ComboDesc = fmt.Sprintf("%d次/天", req.DayCount)
  390. }
  391. }
  392. if req.DayNumber != 0 {
  393. if dataOrder.ComboDesc != "" {
  394. dataOrder.ComboDesc = dataOrder.ComboDesc + ","
  395. }
  396. if req.DayNumber > 0 {
  397. dataOrder.ComboDesc = fmt.Sprintf(dataOrder.ComboDesc+"+%d天", req.DayNumber)
  398. } else {
  399. dataOrder.ComboDesc = fmt.Sprintf(dataOrder.ComboDesc+"%d天", req.DayNumber)
  400. }
  401. }
  402. _, err = db.Insert(&dataOrder)
  403. if err != nil {
  404. return errors.DataBaseError
  405. }
  406. // values
  407. var start, end int64
  408. if req.DayNumber == 0 {
  409. start = p.StartTime
  410. end = p.EndTime
  411. } else {
  412. now := time.Now()
  413. ts := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).Unix()
  414. if p.EndTime < ts {
  415. start = ts
  416. end = start + int64(req.DayNumber*24*3600)
  417. } else {
  418. start = p.StartTime
  419. end = p.EndTime + int64(req.DayNumber*24*3600)
  420. //end = ts + int64(req.DayNumber*24*3600) - (ts-p.StartTime)%(3600*24)
  421. }
  422. if end <= start {
  423. state = 1
  424. }
  425. }
  426. if _, err := db.Raw("UPDATE t_gd_merchant_data_api SET count_per_day=?, state=?, start_time=?, end_time=?, update_time=? WHERE id = ?",
  427. p.CountPerDay+req.DayCount, state, start, end, time.Now().Format("2006-01-02 15:04:05"), req.MerchantDataApiId).Exec(); err != nil {
  428. l.Error("mysql",
  429. zap.String("sql", "UPDATE t_gd_merchant_data_api SET count_per_day=?, state=?, start_time=?, end_time=?, update_time=? WHERE id = ?"),
  430. zap.String("fields", utils.MarshalJsonString(p.CountPerDay+req.DayCount, state, start, end, time.Now().Format("2006-01-02 15:04:05"), req.MerchantDataApiId)),
  431. zap.String("error", err.Error()))
  432. return errors.DataBaseError
  433. }
  434. }
  435. return nil
  436. }
  437. tasks := []storage.DbaTasker{}
  438. tasks = append(tasks, storage.GenerateDbaTask(getDataApiInfoTask))
  439. tasks = append(tasks, storage.GenerateDbaTask(updateDataApiTask))
  440. tasks = append(tasks, storage.GenerateDbaTask(redisPublishTask))
  441. storage.ExecTrans(tasks...)
  442. return nil
  443. }